6 Advanced Tasks
You can use REST API to perform advanced operations such as obtaining a count of resource items in a resource collection, executing custom actions, and executing batch requests.
Returning the Estimated Count of Business Object Items
REST APIs support retrieving the estimated item count in the resource collection.
The following sample estimates the total records and queries the first two items in the Employee
collection. The query parameter totalResults
ensures the response payload contains the totalResults
attribute.
Request
-
URL
<base_url>/Employee?totalResults=true&limit=2
-
HTTP Method
GET
-
Query Parameter
totalResults
This parameter when set to
true
will include the estimated item count in the response for the resource collection. Otherwise the count is not included. The default value isfalse
. -
Content-Type
none
-
Payload
none
Response
-
HTTP Code
200
-
Content-Type
application/vnd.oracle.adf.resourceitem+json
-
Payload
{ "items" : [ { "EmployeeId" : 101, "FirstName" : "Neena", "LastName" : "Smith", "Email" : "NSMITH", "JobId" : "AD_VP", "DepartmentId" : 90, "Salary" : 2000, "links" : [ { "rel" : "self", "href" : "<base_url>/Employee/NSMITH", "name" : "Employee", "kind" : "item" } ] }, { "EmployeeId" : 102, "FirstName" : "Lex", "LastName" : "De Haan", "Email" : "LDEHAAN", "JobId" : "AD_VP", "DepartmentId" : 90, "Salary" : 3000, "links" : [ { "rel" : "self", "href" : "<base_url>/Employee/LDEHAAN", "name" : "Employee", "kind" : "item" } ] } ], "totalResults" : 5, "count" : 2, "hasMore" : true, "limit" : 2, "offset" : 0, "links" : [ { "rel" : "self", "href" : "<base_url>/Employee", "name" : "Employee", "kind" : "collection" } ] }
Making Batch Requests
REST APIs support executing multiple operations in a single roundtrip using a batch request. The data is committed at the end of the request. However, if one request part in a batch request fails, then all changes are rolled back and an error response is returned.
A batch request can consist of a combination of create, update, delete, upsert, and get requests. The path parameter and the payload needs to be the same as what you use to invoke the request directly. The get method supports the same URL parameters in the batch request as a separate HTTP request.
The request URL path must not use encoding of the URI parts, for example, to identify a multi-part key. Using an encoded path in the request will result in an exception error.
The following sample illustrates a successful batch operation that executes operations in four parts: 1) update employee 101, 2) update employee 102, 3) update employee 103, 4) query employee 104.
Request
-
URL
<base_url>
-
HTTP Method
POST
-
Content-Type
application/vnd.oracle.adf.batch+json
-
Payload
{ "parts": [{ "id": "part1", "path": "/Employee/101", "operation": "update", "payload": { "Salary": 10000 } }, { "id": "part2", "path": "/Employee/102", "operation": "update", "payload": { "Salary": 10000 } }, { "id": "part3", "path": "/Employee/103", "operation": "update", "payload": { "Salary": 10000 } }, { "id": "part4", "path": "/Employee?q=EmployeeId%3D101", "operation": "get" }] }
Response
-
HTTP Code
200
-
Content-Type
application/vnd.oracle.adf.batch+json
-
Payload
{ "parts": [{ "id": "part1", "path": "<base_url>/Employee/101", "operation": "update", "payload": { "EmployeeId": 101, "FirstName": "Neena", "LastName": "Smith", "Email": "NSMITH", "JobId": "AD_VP", "DepartmentId": 90, "Salary": 10000, "links": [{ "rel": "self", "href": "<base_url>/Employee/101", "name": "Employee", "kind": "item" } ] } }, { "id": "part2", "path": "<base_url>/Employee/102", "operation": "update", "payload": { "EmployeeId": 102, "FirstName": "Lex", "LastName": "De Haan", "Email": "LDEHAAN", "JobId": "AD_VP", "DepartmentId": 90, "Salary": 10000, "links": [{ "rel": "self", "href": "<base_url>/Employee/102", "name": "Employee", "kind": "item" } ] } }, { "id": "part3", "path": "<base_url>/Employee/103", "operation": "update", "payload": { "EmployeeId": 103, "FirstName": "Alexander", "LastName": "Hunold", "Email": "AHUNOLD", "JobId": "IT_PROG", "DepartmentId": 60, "Salary": 10000, "links": [{ "rel": "self", "href": "<base_url>/Employee/103", "name": "Employee", "kind": "item" } ] } }, { "id": "part4", "path": "<base_url>/Employee", "operation": "get", "payload": { "EmployeeId": 101, "FirstName": "Neena", "LastName": "Smith", "Email": "NSMITH", "JobId": "AD_VP", "DepartmentId": 90, "Salary": 10000, "links": [{ "rel": "self", "href": "<base_url>/Employee/101", "name": "Employee", "kind": "item" } ] } }] }
Working with Error Responses
Error responses can be obtained in the form of a JSON payload in the form of HTTP status codes and error messages.
In addition to HTTP status codes and error messages, it is possible to obtain exception details in the response when your request is enabled to use REST API framework version 4 and the request is made for either application/vnd.oracle.adf.error+json
or application/json
media types. With framework version 4, the response will be in the form an exception detail payload which provides the following benefits to the web application:
-
If multiple errors occur in a single request, the details of each error are presented in a hierarchical structure.
-
An application-specific error code may be present that identifies the exception corresponding to each error.
-
An error path may be present that identifies the location of each error in the request payload structure.
Note:
The exception detail may or may not present certain details, such as the application-specific error code and the request payload’s error path.
For example, compare the error response for a POST submitted with a payload that contains the following incorrectly formatted date field when framework version 3 (or earlier) is enable and when framework version 4 (or later) is enabled.
{ "EmpNum" : 5027,
"EmpName" : "John",
"EmpHireDate" : "not a date"
}
Standard Error Response, Version 3 and earlier
Without framework version 4, no response payload is generated and instead only a single error message that does not reference the request payload will be returned in the response.
"An instance of type oracle.jbo.domain.Date cannot be created from string not a date. The string value must be in format YYYY-MM-DDTHH:MI:SS.sss+hh:mm."
Exception Payload Error Response, Version 4 and later
With framework version 4 enabled, the following exception detail payload is generated for the response. The payload includes the usual HTTP status code and formats the details of one or more exceptions in an array structure.
{ "title" : "Bad Request",
"status" : "400",
"o:errorDetails" : [ {
"detail" : "An instance of type oracle.jbo.domain.Date cannot be created from string not a date.
The string value must be in format YYYY-MM-DDTHH:MI:SS.sss+hh:mm.",
"o:errorCode" : "26099",
"o:errorPath" : "/EmpHireDate"
} ]
}
Understanding the Exception Payload Error Response
-
REST API framework version is version 4.
-
Either
application/vnd.oracle.adf.error+json
orapplication/json
is the media type for the response.
The exception detail payload is a JSON object with the following structure:
{ "title" : "Message as per HTTP status code",
"status" : "HTTP error code",
"o:errorDetails" : [
...
{
"detail" : "Message of detail error",
"o:errorCode" : "error code"
"o:errorPath" : "JSON pointer to the location of the error in the request payload"
},
...
]
}
You opt into the exception payload as the error responses by using framework version 4 and making a request for either the application/vnd.oracle.adf.error+json
media type or application/json
media type.
Note that within the exception payload o:errorDetails
can vary as per the number and the types of errors encountered. Additionally, the error code and error path are not guaranteed to be present in the response payload and should not be relied upon by web applications.
Obtaining an Exception Payload Error Response
REST APIs support obtaining exception details in the response when the request is made with an appropriate media type.
Starting with version 4 of the REST API framework, web applications may obtain an error response with a detailed exception payload.
The following sample attempts to create the department object with a new department item. However, for this example the request fails because the item for the department already exists.
Notice in the exception payload the o:errorDetails
array provides the error path for where the error occurred in the request object; however, these particular details may not always be available to web applications.
Request Example 1
-
URL
<base_url>/Department
-
HTTP Method
POST
-
Accept Header
application/vnd.oracle.adf.resourceitem+json,application/json
-
Payload
{ "DeptNum" : 50, "DeptName" : "SALES", }
Response Example 1
-
HTTP Code
400
-
Content-Type
application/json
-
Payload
{ "title" : "Bad Request", "status" : "400", "o:errorDetails" : [ { "detail" : "A department with the same name already exists. Please provide a different name.", "o:errorCode" : "Dept_Rule_0" } ] }
The following sample attempts to create the department object with a new department item. However, for this example the request fails because the employee names entered exceed the number of characters allowed by the validation rule defined for the EmpName
field.
Request Example 2
-
URL
<base_url>/Department
-
HTTP Method
POST
-
Accept Header
application/vnd.oracle.adf.resourceitem+json,application/vnd.oracle.adf.error+json
-
Payload
{ "DeptNum" : 52, "DeptName" : "newDept522", "Employee" : [ { "EmpNum" : 501, "EmpName" : "MILLERSxxxxxxxxxxxxxxxxx" }, { "EmpNum" : 502, "EmpName" : "JONESPxxxxxxxxxxxxxxxxx" } ] }
Response Example 2
-
HTTP Code
400
-
Content-Type
application/vnd.oracle.adf.error+json
-
Payload
{ "title" : "Bad Request", "status" : "400", "o:errorDetails" : [ { "detail" : "Value MILLERSxxxxxxxxxxxxxxxxx for field EmpName exceeds the maximum length allowed.", "o:errorCode" : "27040", "o:errorPath" : "/Employee/0/EmpName" }, { "detail" : "Value JONESPxxxxxxxxxxxxxxxxx for field EmpName exceeds the maximum length allowed.", "o:errorCode" : "27040", "o:errorPath" : "/Employee/1/EmpName" } ] }
The following sample attempts to perform a batch operation. However, for this example the batch operation fails for the reasons shown in the exception detail payload of the error response.
Request Example 3
-
URL
<base_url>
-
HTTP Method
POST
-
Content-Type Header
application/vnd.oracle.adf.batch+json
-
Payload
{ "parts": [ { "id": "part1", "path": "/Employee", "operation": "create", "payload" : { "EmpNum" : 1299, "EmpJob" : "CLERK", "EmpMgr" : 7566, "EmpHireDate" : null, "EmpSal" : 245, "EmpComm" : 0, "EmpDeptNum" : 30 } }, { "id": "part2", "path": "/Employee", "operation": "create", "payload": { "EmpNum" : 7589, "EmpName" : "SampleEmpxxxxxxxxxxxxxxxxxx", "EmpJob" : "CLERK", "EmpMgr" : 7566, "EmpHireDate" : null, "EmpSal" : 245, "EmpComm" : 0, "EmpDeptNum" : 30 } }, { "id": "part3", "path": "/Department", "operation": "create", "payload": { "DeptNum" : 52, "DeptName" : "newDept522", "Employee" : [ { "EmpNum" : 7588, "EmpName" : "SampleEmpxxxxxxxxxxxxxxxxxx", "EmpJob" : "CLERK", "EmpMgr" : 7566, "EmpHireDate" : null, "EmpSal" : 245, "EmpComm" : 0, "EmpDeptNum" : 30 } ] } }, { "id": "part4", "path": "/Department/10/child/Loc", "operation": "get" }, { "id": "part5", "path": "/Department?invQP=invVal", "operation": "get" }, { "id": "part6", "path": "/Department/54", "operation": "delete" }, { "id": "part7", "path": "/Department/54", "operation": "get" } ] }
Response Example 3
-
HTTP Code
400
-
Content-Type
application/vnd.oracle.adf.error+json
-
Payload
{ "title" : "Bad Request", "status" : "400", "o:errorDetails" : [ { "detail" : "URL request parameter invQP cannot be used in this context.", "o:errorCode" : "27520" }, { "detail" : "Attribute EmpName in Emp is required.", "o:errorCode" : "27014", "o:errorPath" : "/parts/0" }, { "detail" : "Value SampleEmpxxxxxxxxxxxxxxxxxx for field EmpName exceeds the maximum length allowed.", "o:errorCode" : "27040", "o:errorPath" : "/parts/1/payload/EmpName" }, { "detail" : "Attribute EmpName in Emp is required.", "o:errorCode" : "27014", "o:errorPath" : "/parts/1" }, { "detail" : "Value SampleEmpxxxxxxxxxxxxxxxxxx for field EmpName exceeds the maximum length allowed.", "o:errorCode" : "27040", "o:errorPath" : "/parts/2/payload/Employee/0/EmpName" }, { "detail" : "Attribute EmpName in AM.Dept_empWorksIn_deptToEmpQA_EmpViewDef is required.", "o:errorCode" : "27014", "o:errorPath" : "/parts/2" }, { "detail" : "Not Found", "o:errorCode" : "11404", "o:errorPath" : "/parts/3" } ] }
Obtaining the Standard Error Message Response
REST APIs support generating an error message that describes the validation or system error when the request is made with REST API framework versions 1 through 3 enabled.
Before version 4 of the REST API framework, the error response returns a single error message and HTTP status code. Version 4 and later allows web applications to obtain an error response with a detailed exception payload.
The following sample attempts to update the Departments
resource with a new department resource item. However, for this example the update fails because the item for the department already exists. The response is an error message because REST API framework version 4 (or later) is not enabled.
Request Example Made With Framework Version 3
-
URL
http://server/demo/rest/11.2/Departments
-
HTTP Method
POST
-
Content-Type
application/vnd.oracle.adf.resourceitem+json
-
Accept Header
application/vnd.oracle.adf.resourceitem+json,application/json
-
Payload
{ "DeptNum" : 50, "DeptName" : "SALES", }
Response Example From Framework Version 3
-
HTTP Code
400
-
Error Response
A department with the same name already exists. Please provide a different name.
Enable Polling for Endpoint Requests
If you run into timeout issues when working with business objects, you might want to enable polling for long-running endpoint requests.
Polling is useful in many contexts involving long-running processes, where you run the risk of breaking the client/server connection because of gateway or browser timeouts. A process can be long running, say, when your application integrates with external services, perhaps through a trigger that makes API calls to an external service. It can also involve endpoint requests that import a large volume of data from a file or from one database (development, staging, or live) to another during your application's lifecycle. Most data-related endpoint requests, including those to create, query, update, and delete business object data, are long-running processes that can benefit from polling.
You can enable polling by adding the vb-poll=true
query parameter to an endpoint request URL. Now when the client makes an endpoint request, the server—instead of waiting for the request to complete and then return an HTTP response (status 200 or otherwise)—returns an HTTP response (status 202) with details of a new URL for the client to poll. This allows the server to continue processing the request in the background and the client to poll the new URL as and when it wants to find out if the request is complete and get the response (or error).
To enable polling for long-running endpoint requests: