Has anyone had any success batching REST calls together with the batch service methods?
We are currently on V11 in a RAMP environment and I'm having some issues with this. I am get the error "Object reference not set to an instance of an object." for any service URI I enter (local, relative, or even web.
I'm really stuck on this right now and I'm not sure if this is a V11, RAMP, or coding or other random issue.
Here is my current POST body to https://fairlb/testapi/constituentservice/constituents/batch from within my RAMP terminal (local to the gateway):
<BatchRequest>
<Requests>
<Request>
<Id>1</Id>
<Uri>https://fairlb/testapi/constituentservice/constituents/5</Uri>
<HttpMethod>GET</HttpMethod>
</Request>
</Requests>
</BatchRequest>
Has anyone had similar issues in a non-RAMP environment?
-Chris
Hi Chris,
It's a little tricky with the dataservice because it does not know about the objects you are trying to batch, so you have to use the content type of a:XElement like below:
<BatchRequest xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Content i:type="a:XElement" xmlns:a="http://schemas.datacontract.org/2004/07/System.Xml.Linq">
<CustomThing>
<CustomColumn>1</CustomColumn>
</CustomThing>
</Content>
<HttpMethod>POST</HttpMethod>
<Uri>https://website.com/testapi/tessituraservice/custom/customthings/</Uri>
<Id>2</Id>
<Uri>https://website.com/testapi/tessituraservice/custom/customthings/1</Uri>
Thanks Paul-- That will probably save me some extra headaches in the future. Seems my GET call is matching yours, though, so I'm still unsure of what might be wrong with my base calls.
Do you know if the API loops back through the network to make the batch calls? I'm still not entirely sure of the stack behavior when it comes to these Batch methods
Hi
I'm trying to do a similar thing with a json payload to batch insert into a custom table
In XML it works but in JSON I get an xml (!) response saying
<ErrorMessages xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><ErrorMessage><Code i:nil="true"/><Description>Value cannot be null.
Parameter name: source</Description><ErrorPath i:nil="true"/></ErrorMessage></ErrorMessages>
The respective payloads are as follows
(And I'm using headers for the JSON request that work with a non-Batch POST)
JSON:
{
"BatchRequest": {
"Requests": [
"Request": {
"Content": {
"perfinfo": {
"inv_no": "666",
"artifax_event": "666"
}
},
"HttpMethod": "POST",
"Id": 1,
"Uri": "https://ti3svcs.inhouse.rfh.org.uk/TessituraService/Custom/perfinfos/"
"inv_no": "999",
"artifax_event": "999"
"Id": 2,
]
XML:
<perfinfo>
<inv_no>92463</inv_no>
<artifax_event>666</artifax_event>
</perfinfo>
<Uri>https://ti3svcs.inhouse.rfh.org.uk/TessituraService/Custom/perfinfos/</Uri>
<artifax_event>999</artifax_event>
Just replied to the thread on the developer forum as well...I'm trying to do a JSON batch as well, and not able to figure it out.
I've been trying to work with the example and the basic diagnostics api call:
{ "Requests": [ { "Request": { "HttpMethod":"GET", "Id":1, "Uri":"http://calplb/TestAPI/TessituraService/Diagnostics/Status", "Content":{} }}, { "Request": { "HttpMethod": "GET", "Id":2, "Uri":"http://calplb/TestAPI/TessituraService/Diagnostics/Status", "Content":{} }}, ] }
And I get this error:
"Code": "PARAMETER_SHOULD_BE_GREATER_THAN_ZERO", "Description": "The parameter must be greater than zero.", "Details": " at Tessitura.Services.Common.Util.Throw`1.If(Func`1 action)\r\n at Tessitura.Services.Common.Batch.BatchRequestValidator.Validate(BatchRequest batchRequest)\r\n at Tessitura.Service.Web.Controllers.Custom.BatchService.Validate(BatchRequest batchRequest)\r\n at Tessitura.Service.Web.Controllers.Custom.BatchService.ExecuteBatchRequest(BatchRequest batchRequest, ContentType contentType)\r\n at Tessitura.Service.Web.Controllers.Base.BatchBaseController.Process(BatchRequest batchRequest, ContentType contentType)\r\n at Tessitura.Service.Web.Controllers.BatchController.Post(HttpRequestMessage requestMessage)\r\n at lambda_method(Closure , Object , Object[] )\r\n at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass10.<GetExecutor>b__9(Object instance, Object[] methodParameters)\r\n at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken)\r\n--- End of stack trace from previous location where exception was thrown etc.
What parameter? It sounds like a complaint about "Id", but that seems correct.
Nevermind, I was jumping too quickly between other examples in this thread (presumably from v11) and the example in the rest service catalog. This works!
{ "Requests": [ { "HttpMethod":"GET", "Id":1, "Uri":"http://calplb/TestAPI/TessituraService/Diagnostics/Status", "Content":{} }, { "HttpMethod": "GET", "Id":2, "Uri":"http://calplb/TestAPI/TessituraService/Diagnostics/Status", "Content":{} }, ] }
Okay, now I have a genuine question.
If I call CRM/Addresses with this in the request:
{ "Constituent": { "Id": 20335666 }, "AddressType": { "Id": 14 }, "Street1": "111 Nob Hill Crescent", "City": "San Francisco", "State": { "Id": 11}, "PostalCode": "94109", "Country": { "Id": 1 }, "Label": "True", "PrimaryIndicator": "False", "Months": "YYYYNNNNYYYY" }
It works. But if I try to call it through a batch, thusly:
{ "Requests": [ { "HttpMethod":"POST", "Id":1, "Uri":"http://calplb/TestAPI/TessituraService/CRM/Addresses/", "Content":{ "Constituent": { "Id": 20335666 }, "AddressType": { "Id": 14 }, "Street1": "111 Nob Hill Crescent", "City": "San Francisco", "State": { "Id": 11}, "PostalCode": "94109", "Country": { "Id": 1 }, "Label": "True", "PrimaryIndicator": "False", "Months": "YYYYNNNNYYYY" } } ] }
I get this error:
{ "Responses": [ { "RequestId": 1, "ResponseObject": null, "StatusCode": 500, "ErrorMessages": [ { "Code": null, "Description": "Object of type 'Newtonsoft.Json.Linq.JObject' cannot be converted to type 'Tessitura.Service.Client.CRM.Address'.", "Details": null, "ErrorPath": null } ] } ], "BatchFailed": true }
What subtlety of formatting the contents am I missing? Alas the only examples in the documentation are XML.
I just tried your exact example, changing only address type, constituent ID, and Uri, and it worked for me. I'm on 12.5.1HF12.
12.5.1's REST Client does have a rudimentary JSON example, but the only other things it demonstrates are some properties on the request: a "ReturnTypeString" which doesn't appear to have any affect, "ContinueOnError": true (maybe something to try), and "DependsOnRequests", which it gives absolutely no explanation of.
I just tried your exact example, changing only address type, constituent ID, and Uri, and it work for me. I'm on 12.5.1HF12.
Thanks for the confirmation! I think I'll try bumping this to support if I have the outline of my syntax right.
"DependsOnRequests" is my next step!
Hi Nick,
Did you say you were able to get this Batch call to work? Tessitura has just told me that there is a defect with JSON and Batch calls that is currently under development, and have suggested I switch to XML (blech).
--Gawain
What version and hotfix are you on?
I can make this request as JSON just fine
Thanks Christopher...I'm not 100% sure, is that something I can easily look up? The version # is 12.5.1.216.
Ah, here we go, dbo.FS_CURRENT_VERSION():
12.5.1+HF44 216
So, Hotfix 44?
That is strange I don't think that you should have a problem then.
Have you tried XML with success? What are your headers set to?
I tried to break this earlier and I was getting fairly responsive errors, it seems that the conversion was happening fine with data structure you had provided.
Hi Christopher,
I've asked Tessitura Support if this was an issue introduced by a hotfix, in case having a higher HF is what is causing me to have the problem and not you guys.
I tried XML (Tessitura Support recommended it as a workaround), but I'm having no success there either.
Here's what I'm plugging in (now almost identical to the code snipped in the documentation):
<BatchRequest> <Requests> <Request> <HttpMethod>POST</HttpMethod> <Id>1</Id> <Uri>http://calplb/TestAPI/TessituraService/CRM/Addresses/</Uri> <Content i:type="address" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <Constituent><Id>20335666</Id></Constituent> <Addresstype><Id>14</Id></Addresstype> <Street1>111 Nob Hill Crescent</Street1> <City>San Francisco</City> <State><Id>11</Id></State> <PostalCode>94109</PostalCode> <Country><Id>1</Id></Country> <Label>True</Label> <PrimaryIndicator>False</PrimaryIndicator> <Months>YYYYNNNNYYYY</Months> </Content> </Request> </Requests> </BatchRequest>
And here's the error I'm getting back:
<BatchResponse xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <BatchFailed>true</BatchFailed> <Responses> <Response> <ErrorMessages> <ErrorMessage> <Code>FIELD_CANNOT_BE_NULL</Code> <Description>Field 'entity' cannot be null or empty.</Description> <Details i:nil="true" /> <ErrorPath>entity</ErrorPath> </ErrorMessage> </ErrorMessages> <RequestId>1</RequestId> <ResponseObject i:nil="true" /> <StatusCode>BadRequest</StatusCode> </Response> </Responses> </BatchResponse>
Interesting.
We are on HF48 right now and are getting scheduled for 49 this week, so if that's the case it must have gotten un-borked.
Maybe update and report back if you still have any issues?
Upgraded to HF48, but no change. Not surprised, frankly. Something else is clearly wrong.
In the meantime, trying to work around not being able try things out in Batch, I'm realizing that I might have a bigger problem. My assumption was that I was going to build some procedures to call through Custom/Execute, and I was going to used returned ids to fill in dependent procedures. However, Custom/Execute isn't going to return columns in a way that I think can be referenced by the DependsOnRequest...and if did, I wouldn't be able to apply it to the dependent call to Custom/Execute since the parameters are all bunged together in a single object ("Parameters").
I'm trying to figure out TR_DATASERVICE, but documentation is even more scanty for that, particularly for formatting POST and PUT commands.
Say Christopher/Nick,
When you were running this, were you doing it through the provided Rest Client (that's what I'm doing), or via cURL or the .Net libraries?
I was just using the REST client provided in the services web interface.