Important

You are browsing the documentation for version 4.1 of OroCommerce, OroCRM and OroPlatform, which is no longer maintained. Read version 5.1 (the latest LTS version) of the Oro documentation to get up-to-date information.

See our Release Process documentation for more information on the currently supported and upcoming releases.

Batch API

The Batch API provides a way to create or update a list of entities of the same type via one API request.

The request is processed asynchronously. The server may process records in any order regardless of the order in which they are specified in the request.

Input Data Format

The input data for each record are the same as for API resources to create or update a single account record:

{
   "data": [
      {
          "type":"entityType",
          "attributes": {...},
          "relationships": {...}
      },
      {
          "type":"entityType",
          "attributes": {...},
          "relationships": {...}
       }
   ]
}

To mark records that should be updated, use the update meta property:

{
   "data": [
      {
          "meta": {update: true},
          "type":"entityType",
          "id": 1,
          "attributes": {...},
          "relationships": {...}
      },
      {
          "meta": {update: true},
          "type":"entityType",
          "id": 2,
          "attributes": {...},
          "relationships": {...}
       }
   ]
}

See Creating and Updating Related Resources with Primary API Resource for more details about this meta property.

Included Items

Related entities can be created or updated when processing primary entities.

The list of related entities should be specified in the included section that must be placed at the root level, the same as the data section:

{
   "data": [
      {
          "type":"entityType",
          "attributes": {...},
          "relationships": {
              "relation": {
                  "data": {
                      "type":"entityType1",
                      "id": "included_entity_1"
                  }
              },
              ...
          }
      },
      ...
   ],
   "included": [
       {
          "type":"entityType1",
          "id": "included_entity_1",
          "attributes": {...},
          "relationships": {...}
      },
      ...
   ]
}

The included records can be updated when processing the request. To mark included records that should be updated, use the update meta property:

{
   "data": [
      {
          "type":"entityType",
          "attributes": {...},
          "relationships": {
              "relation": {
                  "data": {
                      "type":"entityType1",
                      "id": "12"
                  }
              },
              ...
          }
      },
      ...
   ],
   "included": [
       {
          "meta": {update: true},
          "type":"entityType1",
          "id": "12",
          "attributes": {...},
          "relationships": {...}
      },
      ...
   ]
}

Batch API Example

The next example shows how to insert a list of accounts.

Request

1PATCH /api/accounts HTTP/1.1
2Content-Type: application/vnd.api+json
3Accept: application/vnd.api+json

Request Body

 1{
 2   "data": [
 3      {
 4          "type":"accounts",
 5          "attributes":{
 6             "name":"Gartner management group"
 7          }
 8      },
 9      {
10          "type":"accounts",
11          "attributes":{
12             "name":"Cloth World"
13          }
14       }
15   ]
16}

Response

 1{
 2  "data": {
 3    "type": "asyncoperations",
 4    "id": "1",
 5    "links": {
 6      "self": "http://your_domain.com/admin/api/asyncoperations/1"
 7    },
 8    "attributes": {
 9      "status": "new",
10      "progress": null,
11      "createdAt": "2020-03-11T17:41:17Z",
12      "updatedAt": "2020-03-11T17:41:17Z",
13      "elapsedTime": 0,
14      "entityType": "accounts",
15      "summary": null
16    },
17    "relationships": {
18      "owner": {
19        "data": {
20          "type": "users",
21          "id": "1"
22        }
23      },
24      "organization": {
25        "data": {
26          "type": "organizations",
27          "id": "1"
28        }
29      }
30    }
31  }
32}

The response of request is the corresponding asynchronous operation created for the request.

The response object has the following data:

  • status - The status of the asynchronous operation. Possible values: new, running, failed, success, cancelled.

  • progress - The progress, in percentage, for the asynchronous operation.

  • elapsedTime - The number of seconds the asynchronous operation has been running for.

  • entityType - The type of an entity for which the asynchronous operation was created.

  • createdAt - The date and time when the asynchronous operation was created.

  • updatedAt - The date and time when the asynchronous operation was last updated.

  • owner - A user who created the asynchronous operation.

  • organization - An organization the asynchronous operation belongs to.

  • summary - The summary statistics of the asynchronous operation. This field will have data only when an asynchronous operation is finished successfully.

The summary can have the following properties:

  • aggregateTime - The accumulated time, in milliseconds, taken by the system to accomplish the asynchronous operation.

  • readCount - The number of items that have been successfully read.

  • writeCount - The number of items that have been successfully written.

  • errorCount - The number of errors occurred when processing the asynchronous operation.

  • createCount - The number of items that have been successfully created.

  • updateCount - The number of items that have been successfully updated.

To see updated status of job, use the following request:

Request

1GET /api/asyncoperations/1 HTTP/1.1
2Accept: application/vnd.api+json

Response

{
  "data": {
    "type": "asyncoperations",
    "id": "1",
    "attributes": {
      "status": "success",
      "progress": 1,
      "elapsedTime": 3,
      "entityType": "accounts",
      "summary": {
        "aggregateTime": 2737,
        "readCount": 2,
        "writeCount": 2,
        "errorCount": 0,
        "createCount": 2,
        "updateCount": 0,
      ...
      }
    },
    ...
  }
}

This example shows the status of the operation that was successfully completed. Here 2 entities were read and inserted.

If some entities were not processed, the summary’s errorCount field will contain the number of errors occurred when processing the asynchronous operation:

{
  "data": {
    "type": "asyncoperations",
    "id": "1",
    "attributes": {
      "status": "success",
      "progress": 1,
      "elapsedTime": 3,
      "entityType": "accounts",
      "summary": {
        "aggregateTime": 2218,
        "readCount": 2,
        "writeCount": 1,
        "errorCount": 1,
        "createCount": 1,
        "updateCount": 0
      ...
      }
    },
    ...
  }
}

To sse the list of errors, use the asyncoperations/{id}/errors subresource:

1GET /api/asyncoperations/1/errors HTTP/1.1
2Accept: application/vnd.api+json

Response

 1{
 2  "data": [
 3    {
 4      "type": "asyncoperationerrors",
 5      "id": "3-1-1",
 6      "attributes": {
 7        "status": 400,
 8        "title": "not blank constraint",
 9        "detail": "This value should not be blank.",
10        "source": {
11          "pointer": "/data/0/attributes/name"
12        }
13      }
14    }
15  ]
16}

The returned asynchronous operation errors have the following data:

  • status - The HTTP status code applicable to the problem.

  • title - A short, human-readable summary that describes the problem type.

  • detail - A human-readable explanation specific to this occurrence of the problem.

  • source - An object containing references to the source of the error.

The source object can have the following properties:

  • pointer - A JSON Pointer to the value in the request document that caused the error, e.g., “/data/0” for a primary data object, or “/data/0/attributes/title” for a specific attribute.

  • propertyPath - A path to the value in the request document that caused the error. This property is returned if the pointer property cannot be computed.