Batching


REST Service resources are fine-grained, requiring multiple independent calls to act on a group of related entities. For example, updating a constituent might consist of one call to update the name, another call to update an address and finally a third call to update an attribute. There is no problem with making these calls independently, but there are also times when it is beneficial to group operations together. Grouping the operations may allow you to develop classes that combine commonly used operations.

By using batching, a set of REST calls to a single service can be grouped into a single BatchRequest resource. Each call is processed individually at the server but travels across the network as a single request.

Request


To use batching build a request body which contains separate "request" node for each operation. Note that each "request" must have an "id" to determine the order in which the operations will take place. Methods and verbs can be mixed within a batch. If a specific Request is a PUT or POST, and therefore requires a request body to be sent, that body will be contained in a "content" node within the "request" node. The "content" node uses a type attribute to specify what type of entity the body represents. Important: XML nodes must be in alphabetical order to be deserialized correctly. For example, if you were sending a batch that contained an individual request to update (PUT) an Artist name, the opening tag of the Content node would look like this:

<Content i:type="Artist">
    <FirstName>John</FirstName>
    <Id>51</Id>
    <LastName>Doe</LastName>
    <MiddleName>Alex</MiddleName>
    <UpdatedDateTime>2017-08-02T09:55:48.1579517-05:00</UpdatedDateTime>
    <VoiceId>5</VoiceId>
</Content>

"Content" : 
{
    "$type": "Tessitura.Service.Client.TXN.Artist, Tessitura.Service.Client",
    "FirstName": "John",
    "Id": 51,
    "LastName": "Doe",
    "MiddleName": "Alex",
    "UpdatedDateTime": "2017-08-02T09:55:48.1579517-05:00",
    "VoiceId": 5
}

DependsOn Feature


The Batch Resource has a special feature that allows an operation in a batch to depend on a piece of data from a previous operation in the same batch. This is done by adding a "dependsonrequests" node to the the Request that uses the data.

Inside "dependsonrequests" there are one or more "dependsonrequest" nodes that specify each data dependency. A "dependsonrequest" has three required elements:

  • "id" is the Request Id that will contain the data.
  • "sourcepath" is the element that contains the data. This uses object dot notation, with "content" being the root.
  • "targetpath" is the element where the data will be used in the current Request. Again, this uses object dot notation with "content" being the root. The ability to replace data in on Request from data in a prior Request only applies to data coming from a "content" node and being placed into a "content" node. You cannot replace data in the URI itself.

The example below shows a Batch Request where the first step is to create a new web session. The second request logs in using the sessionKey from the first request. The third request gets the Constituent Detail for the constituent that was logged in.

 
{
    "Requests": 
    [
    {
        "Content": 
        {
            "$type": "Tessitura.Service.Client.Web.SessionRequest, Tessitura.Service.Client",
            "IpAddress": "1.2.3.4",
            "BusinessUnitId": 1
        },
        "HttpMethod": "POST",
        "Id": 1,
        "Uri": "{{url}}Web/Session",
        "ContinueOnError": false
    },
    {
        "Content": 
        {
            "$type": "Tessitura.Service.Client.Web.LoginRequest, Tessitura.Service.Client",
            "LoginTypeId": 1,
            "Password": "password",
            "PromotionCode": "50",
            "UserName": "johndoe"
        },
        "DependsOnRequests" : 
        [
            {
                "Id": 1,
                "IsUrlDependency": true,
                "SourcePath": "SessionKey",
                "TargetPath": "sessionKey"
            }
        ],
        "HttpMethod": "POST",
        "Id": 2,
        "Uri": "{{url}}Web/Session/{sessionKey}/Login",
        "ContinueOnError": false
    },
    {
        "DependsOnRequests" : 
        [
            {
                "Id": 2,
                "IsUrlDependency": true,
                "SourcePath": "LoginInfo.ConstituentId",
                "TargetPath": "constituentId"
            }
        ],
        "HttpMethod": "GET",
        "Id": 3,
        "Uri": "{{url}}CRM/Constituents/{constituentId}/Detail",
        "ContinueOnError": false
    }
    ]
}