Using API Gateway, I would like to intercept the Integration Request, change the model and then forward it through to the endpoint via a body mapping template.
For example, I would like to change the MatterGUID property to be MatterId + value.
If i include my entire model within the template, it works fine;
#set($inputRoot = $input.path('$'))
{
"Property1" : "$inputRoot.Property1",
"MatterId" : "$inputRoot.MatterGUID",
"Property2" : "$inputRoot.Property2",
"Property3" : "$inputRoot.Property3"
}
However, I would like to update my model by updating only the field needing to be changed. i.e. something like:
#set($inputRoot = $input.path('$'))
{
"MatterId" : "$inputRoot.MatterGUID"
}
However, doing that will pass only the MatterId through to the endpoint, not all the other properties - I can understand why that happens but would like to know what i'm missing in order to include the entire object but with the changed MatterGUID value.
Almost like if I could run a replaceAll on the model and for it to affect only the property I'd like:
$inputRoot.Replace("MatterGUID", "MatterId")
The model is not the source of truth on what the payload should contain, the mapping template is. It is currently not possible to include properties within the payload that are defined in the model and not present in the mapping template.
Related
I have tried to create a record of my customized object through REST service in IBM Maximo.
The problem is that I created the record but I can't assign values to the attributes.
Next I will show what I did and what happened:
I have an Object Structure called oxidato that represents my customized object.
I did a POST using POSTMAN to this URL:
http://hostname:port/maximo/oslc/os/oxidato?lean=1
In the body section this is the JSON I was trying to send:
{
"attribute1":"205",
"attribute2":"206"
}
The record was created but none of the attributes was filled.
In my opinion, the REST service received the POST but canĀ“t read the body.
What am I missing? I add an image of the POSTMAN as example:
EDIT1: I update the POST in order to use the newest API RES (Thanks Dex!)
EDIT2: I add an image of the header
I have found that Maximo will often ignore incoming attributes that aren't in the Maximo namespace (http://www.ibm.com/maximo). You could go through the trouble of setting up your VALOR1 and VALOR2 attributes to be in that namespace, but it's easier to just tell OSLC to ignore namespaces. You do that by setting the "lean" parameter to "1".
In your case, go to the "Params" tab and add an entry with a name of "lean". Give it a value of "1" and then send your POST again. You should see "?lean=1" appear at the end of the POST URL along the top there, but your body content should remain unchanged.
EDIT:
On the other hand, it looks like (based on your URL) that you aren't actually using the newer JSON/OSLC REST API; It looks like you are using the older REST services. This IBM page gives you a lot of information on the newer JSON REST API, including the correct URLs for it: https://developer.ibm.com/static/site-id/155/maximodev/restguide/Maximo_Nextgen_REST_API.html.
You should change your URL to /maximo/oslc/os/oxidato to use the newer API that naturally supports JSON and the lean parameter described above. This does required Maximo 7.6 to use though.
EDIT 2:
The attributes are often oddly case sensitive, requiring lowercase. Your example in your question of "attribute1" and "attribute2" are properly lowercase, but your screenshot shows uppercase attribute names. Try changing them to "valor1" and "valor2". Also, these are persistent attributes, right?
The response code received back (e.g. 200 - OK) and the response body will detail the record that was created.
I think you are correct in that the body of the post request is being ignored. Provided there are no required fields on the custom MBO your POST is probably creating an empty record with the next value in the sequence for the key field but you should see that in the response.
The following POST should create a record with values provided for attribute1 and attribute2 and provide a response with the record's identifier so that you can look it up in Maximo and show the values that were stored for attribute1 and attribute2:
http://hostname:port/maximo/rest/os/oxidato/?_format=json&_compact=1&attribute1=205&attribute2=206
Response: 200 OK
Reponse Body:
{ "CreateOXIDATOResponse": {
"rsStart": 0,
"rsCount": 1,
"rsTotal": 1,
"OXIDATOSet": {
"OXIDATO": {
"rowstamp": "[0 0 0 0 0 -43 127 13]",
"ATTRIBUTE1": "205",
"ATTRIBUTE2": "206",
"OXIDATOID": 13
}
} } }
You may also want to turn on debug logging for the REST interface in System Configuration -> Platform Configuration -> Logging for additional detail on what's happening in the log file.
I'm using SoapUI to call a web service.
I have two call, one returns an id to me, the second one use this id to make his request.
This is how the second call looks like:
https://example.com/something/{id}
With the property transfer, I have no problem retrieving the id from the first call. But when I try to add it to my endpoint (Property transfer -> Target: XXX, Property: Endpoint), the whole Endpoint is replaced by {id}.
I know I probably need to write something on the "box" belove the "Target" line, but I have no idea what.
I already tried to google it, but I seem to only found answers which are using a Groovy script and this sounds way too complicated for what I want to do. Surely, there is an easy way to do this?
Add a Properties teststep to your testcase.
Add a parameter to the Properties teststep named "id"
Change your property transfer teststep to target id inside Properties
Now open your second call, and change the value of the id parameter to ${Properties#id} and the id from your Properties teststep should be used as the value.
Your REST Request teststep should look something like this.
The "/value" at the top right, is there because I actually typed in "value" in the Properties teststep in the id parameter
If you are having problems getting your request to look something like that, try creating a new REST Request teststep, and then choose to create a new Rest request, and then type in something like
http://example.com/{id}
...when prompted for the endpoint.
I have an architecture issue concerning a RestAPI url with multiple identifiers.
In a simple relationship, I use to write something like this :
GET /users/2/tickets/46 to retrieve the ticket 46 of the user 2.
But I want to retrieve, for example, a list of operations which can be identified by two identifiers, a userId and a workstationId. Both of them are not related.
For a GET request, it's weird for me to write this :
GET /users/2/workstations/5/operations because there's no relation...
Is it a best practice to use url parameters as filter ? :
GET /operations?userId=2&workstationId=5
EDIT :
And for a PUT/PATCH request when editing a specific operation, should I keep the same pattern :
PATCH /operations/123?userId=2&workstationId=5
{
"data":"test"
}
Or should I put the identifiers in json payload :
PATCH /operations/123
{
"userId":"2",
"workstationId":"5",
"data":"test"
}
I'm looking for a method in the library to convert an OData response object into a normalized js object that can be sent into another ODataModel.create function. An OData "object" would be an OData REST response containing 'd', the '__meta', the 'results', etc.
I have a working solution with custom methods in a Utilities module but I'm not too sure about its resilience to all possible OData rules.
It isn't necessary to have the d, __meta and results section in a valid OData body:
The d potion is optional. You may also just form your body as a regular object such as:
{
Id: 12345,
Name: 'This is a valid OData body'
}
The __metadata section is optional as well and may be left out.
The results section is something you will receive when you query an Entity Set. If you query a single Entity (by providing its key), this section is left out as there will only be one result. You can't use the results section when you want to submit entities to the OData service, as every submission is supposed to happen in a separate operations.
With that, your normalisation/processing code could be very simple and look like:
jQuery.each(odata.results, function(idx, value) {
var body = value.d ? value.d : value;
delete body.__metadata;
// Do something with the body, e.g.:
ODataModel.create("/AwesomeEntity", body);
});
I hope this makes life easier? Full OData v2 JSON specs are available here:
http://www.odata.org/documentation/odata-version-2-0/json-format/
I have a property on my "Contact" entity:
public partial class Contact
{
public string FullName { get { return this.FirstName + this.LastName; } set { } }
}
I then use breeze get the Contact data from my Web API function that returns Contacts. My data returned from my Web API call has the "FullName" property and the correct value coming down to the client, but my "Metadata" does not have the "FullName" property anywhere in it. What do I need to do to get the Metadata?
I found no sensible solution to adding partial class items to the metatata from the server. My opinion is that this should be considered as a bug to the server Breeze metadata function.
However the extended items data do get served from the server.
So if you add the extended properties manually on the client metadata-store, everything should be fine.
Here is an example how you do it in the javascript client code:
var man = new breeze.EntityManager(myServiceName);
man.metadataStore.registerEntityTypeCtor('Contact', function () { this.FullName = ''; });
You don't really want that computed properties coming over the wire, do you? Why do you have a setter? This is a read-only property. And if this is an EF Code First class, how did you keep EF from believing that FullName is mapped to a "FullName" column in the "Contact" table?
I'm going to assume that you don't actually want the "FullName" to come over the wire. You want to extend the type with either a custom EntityType constructor or an initializer. I think you want an initializer in this case.
Take a look at "Extending Entities" which happens to illustrate the recommended technique with a fullName property.