REST Batching

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

Parents
  • 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">

    <Requests>

    <Request>

    <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>

    <Id>1</Id>

    <Uri>https://website.com/testapi/tessituraservice/custom/customthings/</Uri>

    </Request>

    <Request>

    <HttpMethod>GET</HttpMethod>

    <Id>2</Id>

    <Uri>https://website.com/testapi/tessituraservice/custom/customthings/1</Uri>

    </Request>

    </Requests>

    </BatchRequest>



    [edited by: Paul Kappel at 3:38 PM (GMT -6) on 28 Jul 2014]
  • 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

  • Are you specifying the content-type header on the call as text/xml?

  • Yes and it seems to be parsing it just fine. For instance if I change the Id of the batch call to 0 I get a parameter must be greater than zero error.

     

    The only thing that seems to be an issue is that the Batch call can't initialize the sub calls

  • It's random, but I just did some tests on v11- try ordering your request like this:

    <BatchRequest>

    <Requests>

    <Request>

    <HttpMethod>get</HttpMethod>

    <Id>1</Id>

    <Uri>https://fairlb/liveapi/constituentservice/constituents/5</Uri>

    </Request>

    </Requests>

    </BatchRequest>

  • That worked.... I guess the deserialization process in V11 is quite temperamental and I hadn't tried that order.

    Thanks Paul!

  • 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.&#xD;

    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/"

                    }

                },

                {

                    "Request": {

                        "Content": {

                            "perfinfo": {

                                "inv_no": "999",

                                "artifax_event": "999"

                            },

                            "HttpMethod": "POST",

                            "Id": 2,

                            "Uri": "https://ti3svcs.inhouse.rfh.org.uk/TessituraService/Custom/perfinfos/"

                        }

                    }

                }

            ]

        }

    }

     

    XML:

     

     

    <BatchRequest xmlns:i="http://www.w3.org/2001/XMLSchema-instance">

      <Requests>

        <Request>

          <Content  i:type="a:XElement" xmlns:a="http://schemas.datacontract.org/2004/07/System.Xml.Linq">

            <perfinfo>

              <inv_no>92463</inv_no>

              <artifax_event>666</artifax_event>

            </perfinfo>

          </Content>

          <HttpMethod>POST</HttpMethod>

          <Id>1</Id>

          <Uri>https://ti3svcs.inhouse.rfh.org.uk/TessituraService/Custom/perfinfos/</Uri>

        </Request>

        <Request>

          <Content  i:type="a:XElement" xmlns:a="http://schemas.datacontract.org/2004/07/System.Xml.Linq">

            <perfinfo>

              <inv_no>92463</inv_no>

              <artifax_event>999</artifax_event>

            </perfinfo>

          </Content>

          <HttpMethod>POST</HttpMethod>

          <Id>2</Id>

          <Uri>https://ti3svcs.inhouse.rfh.org.uk/TessituraService/Custom/perfinfos/</Uri>

        </Request>

      </Requests>

    </BatchRequest>

  • 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.



    [edited by: Nick Reilingh at 10:18 PM (GMT -6) on 13 Jul 2017]
  • 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.

    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.

    "DependsOnRequests" is my next step!

Reply
  • 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.

    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.

    "DependsOnRequests" is my next step!

Children
No Data