Sabre RPC Protocol 1.0 Specification
Table of contents
1 Overview 2 Application and transport separation 2.1 Application Layer 2.2 Transport Layer 3 Service versioning 4 Request and Response 4.1 Error handling 5 Transport 5.1 HTTP 5.2 JSON
1 Overview
RPC (Remote Procedure Call) is a request-response service communication protocol. RPC can take many forms, such as Java RMI (Remote Method Invocation), CORBA (Common Object Request Broker Architecture), SOAP (Simple Object Access Protocol), GraphQL, XML-RPC, gRPC, Apache Avro or JSON-RPC.
Some of these protocols utilize IDL (Interface Description Language), while others are based on data model schema. Some are transport agnostic, while others are tied to specific transport protocols, such as HTTP. There are solutions with single message data formats, such as XML, JSON or Protobuf (structured binary data), while others can adapt different formats and marshalling/unmarshalling methods.
However, all RPC protocols require a service operation name, as well as request and response objects for remote service invocation.
Most of all, the RPC protocol is designed with simplicity in mind.
Although XML-RPC and JSON-RPC provide very simple RPC protocols, they are not "friendly" for intermediate transport devices such as gateways, load balancers, or routers. This is due to a service operation (and sometimes a service version) being held in a request object, which requires parsing and interpretation, instead of just passing it through to a service endpoint.
Important! RPC protocol requirements specified in the following sections only apply to a specific subset of Sabre APIs. Refer to the API's documentation to determine whether the API utilizes Sabre RPC Protocol 1.0.
2 Application and transport separation
Remote service invocation is performed with separation of the Application Layer from the Transport Layer (separation of concerns).
Note: The current version of this specification assumes that HTTP is used as the transport protocol, with JSON format, for exchanging message payloads (request and response). Further revisions will cover other transports and message formats.
2.1 Application layer
The client and service represent the Application Layer and exchange request and response objects. There is one request object and one response object used for a single service invocation. Errors returned from the Application Layer part of the service are contained in the response object.
2.2 Transport layer
The Transport Layer is responsible for the delivery of request and response objects to/from the target service operation. This includes addressing the service endpoint by transport protocol as well as message marshalling/unmarshalling by the client stub and service skeleton.
A Gateway is part of the Transport Layer and is responsible for caller authentication and authorization for the endpoint of the target service.
The Transport Layer handles transport protocol-specific errors, such as connectivity errors.
3 Service versioning
Semantic Versioning 2.0.0 schema is used for service versioning. MAJOR version numbers for a service request are provided and handled by the Transport Layer. MINOR version numbers can also be handled by the Transport Layer to support many concurrent MAJOR service versions. It is recommended to only use MAJOR version numbers. MINOR version numbers should be handled only in special situations.
Services should provide the full version number through a dedicated service operation, such as getVersion
. If the chosen transport protocol allows, the service version can also be delivered together with a service response message.
API version is identified by MAJOR and MINOR numbers. An API implementation version has MAJOR and MINOR numbers, followed by the PATCH number, as well as the additional version components according to the Semantic Versioning 2.0.0 schema.
4 Request and response
Invocation of a service is performed by receiving a request object and responding with a response object. A single service operation accepts only one request object schema and always returns the same response object schema. Empty request objects are allowed when service invocation does not require an argument, such as the getVersion
operation (refer to the Service Versioning section). To return application-level error(s), this information is held in the response object.
Callers always send the same type of request object while invoking the service, and should always expect the same response object type.
4.1 Error handling
Application Layer errors, as well as some of the Transport Layer errors, are returned as part of the response object. The response object schema contains a dedicated optional element for error-related data, and should be provided only when errors occur.
4.1.1 Error format
The response object contains an optional list of error elements related to both Application and Transport Layers. Each error element contains an error type and error category with an additional description to indicate the cause of the error, and point at the particular field(s) or value(s) in question.
Error element format:
Field | Optional? | Description |
---|---|---|
category |
no | Indicates the general scenario of the error and suggests a general behavior for similar errors. See the following section for details. |
type |
no | The general type of the error within the category. See the following section for details. |
description |
yes | A human readable message describing what went wrong. |
fieldName |
yes | The name of the request, resource field, or property which is related to the returned error. |
fieldPath |
yes | The full path to a field or property specified by the fieldName field. |
fieldValue |
yes | The value of a field or resource (specified by the fieldName ) indicating the source of an error. |
The aforementioned format is the minimal structure of the error elements required by this specification. It can be extended for particular service implementation (if needed) by providing additional fields or elements (the above Error Format field specification must not be modified).
4.1.2 Error categories and types
There are predefined categories and types of errors that may appear in the Transport Layer. It is an extensible structure and can also be extended to define Application Layer errors; however, it is not restricted by this specification, as they are application-specific.
Transport Layer error categories:
Error Category | Description |
---|---|
BAD_REQUEST |
Indicates that the request is not syntactically correct (doesn't conform to the schema). It usually means that there is a bug on the client side that causes a bad request. The type of error should indicate the category the error falls under. |
RESOURCE_NOT_FOUND |
Indicates that the requested service or operation required to perform the operation does not exist. The type of error should indicate the type of resource that does not exist. |
INTERNAL_SERVER_ERROR |
Indicates that the request caused an unrecognized error on the server side. |
UNSUPPORTED_TRANSPORT |
Indicates that the request or expected response represents an unsupported message format or transport type. For HTTP protocol, this may be used to return an error for an incorrect Content-Type or for Content-Encoding of the request message, or that an HTTP method other than POST was used. |
The Transport Layer error types with mapping to error categories:
Error Category | Error Type | Description |
---|---|---|
BAD_REQUEST |
REQUIRED_FIELD_MISSING |
The request does not contain a required field, or null value of the field is provided. The field location or value may be identified by fieldName , fieldPath , and fieldValue . |
BAD_REQUEST |
INVALID_VALUE |
The value of a given field in the request is not valid. It can be caused by violating a pattern restriction, an invalid date format string, a number exceeding the required range, etc. The information about the incorrect field should be provided by fieldName , fieldPath , and fieldValue . |
BAD_REQUEST |
UNPARSEABLE_REQUEST |
The request format does not fulfill the message schema. |
UNSUPPORTED_TRANSPORT |
UNSUPPORTED_MEDIA_TYPE |
Indicates that the request represents an unsupported media type. For HTTP protocol, this may be used to return an error for an incorrect Content-Type or Content-Encoding of the request message. |
UNSUPPORTED_TRANSPORT |
METHOD_NOT_ALLOWED |
An incorrect transport method of the transport protocol was used to deliver the request. For HTTP protocol, this shows that a method other than HTTP POST was used. |
INTERNAL_SERVER_ERROR |
INTERNAL_SERVER_ERROR |
Indicates that the request caused an unrecognized error on the server side. If possible, more details might be provided using the description field. |
RESOURCE_NOT_FOUND |
RESOURCE_NOT_FOUND |
Indicates that the requested service or operation required to perform the operation does not exist. The description should indicate the type of resource that does not exist. You can define more types in this category for application-specific resources. |
5 Transport
There is no dedicated transport protocol required and many network protocols can be used. However, the Transport Layer must provide the following:
- Target service endpoint location and/or operation name
- Indication of message format
- MAJOR version number of the target service
- MINOR version number to support many MAJOR versions concurrently (this is optional)
- Service invocation context, such as transaction ID, correlation ID, authentication token, or other invocation metadata
- Application Layer data is not allowed, such as service arguments
5.1 HTTP
HTTP protocol is used with the following restrictions:
-
The service URL is formatted as:
http[s]://{host}[:{port}]/v{M}[.{m}]/{namespace}/{service}[/{subdomain}][/{operation}]
where:
{host}
: hostname/address of the gateway{port}
: optional port number of the gateway{M}
: MAJOR part of the service version number{m}
: MINOR part of the service version number. Use MINOR versioning if there is a need to provide many versions of the same MAJOR service version (for service version 1.0.xv1
is sufficient, so no MINOR version number should be used).{service}
: the service endpoint{operation}
: optional, and when not provided, the{service}
element represents both the service endpoint and operation name (in such case, the service has only one operation){namespace}
as well as{subdomain}
element can be a path, not only a single word
and here are sample effective service URLs:
https://services.sabre.com/v1/orders/create https://services.sabre.com/v1/orders/view https://services.sabre.com/v1/cruise/orders/createReservation https://services.sabre.com/v1/cruise/orders/getReservation http://beta.sabre.com:8080/v2/cruise/media/sailings/getDetails
-
Only the
POST
HTTP method is used -
Allowed HTTP Status codes:
- 200 (OK) The invocation of the service succeeds, regardless of application layer errors held in the response object
- 400 (Bad Request) The request object can't be properly unmarshalled by the service skeleton
- 401 (Unauthorized) The caller does not have valid credentials for gateway authentication
- 403 (Forbidden) The gateway can not authorize the caller for service operation
- 404 (Not Found) The service operation does not exist
- 405 (Method Not Allowed) The HTTP method other than
POST
is not allowed - 406 (Not Acceptable) The caller requested not supported response type specified by
Accept
HTTP header - 415 (Unsupported Media Type) The media type is not supported
- 500 (Internal Server Error) The service is malfunctioning and is not able to provide the response object
- 503 (Service Unavailable) Besides infrastructure issues, this should be returned if the service is in the initialization stage and not yet ready for traffic consumption
- Other 5xx statuses according to any network infrastructure errors
-
HTTP headers:
- Specify
Content-Type
and/or relevantContent-Encoding
of the request being sent - Specify
Accept
and/or relevantAccept-Encoding
of the response expected by the caller - Contain authentication and/or authorization details
- Provide any transport specific information
- Response message may contain
X-API-Version
andX-Implementation-Version
headers with the service API and/or the implementation version compliant with Semantic Versioning 2.0.0 schema, such as:
X-API-Version: 1.2 X-Implementation-Version: 1.2.15-alpha
- The Application Layer data is not allowed in HTTP headers
- Specify
In the event there is a possibility to return a response object, detailed Transport Layer error information should be provided. The following table shows mapping of the HTTP Status codes to the Transport Layer error categories and types (refer to the Error Categories and Types section):
HTTP Status codes mapped to the Transport Layer error categories and types:
HTTP Status | Error Category | Error Type |
---|---|---|
400 (Bad Request) | BAD_REQUEST |
REQUIRED_FIELD_MISSING |
400 (Bad Request) | BAD_REQUEST |
INVALID_VALUE |
400 (Bad Request) | BAD_REQUEST |
UNPARSEABLE_REQUEST |
404 (Not Found) | RESOURCE_NOT_FOUND |
RESOURCE_NOT_FOUND |
405 (Method Not Allowed) | UNSUPPORTED_TRANSPORT |
METHOD_NOT_ALLOWED |
415 (Unsupported Media Type | UNSUPPORTED_TRANSPORT |
UNSUPPORTED_MEDIA_TYPE |
500 (Internal Server Error) | INTERNAL_SERVER_ERROR |
INTERNAL_SERVER_ERROR |
Note: The 404 (Not Found) HTTP Status code is only used for the Transport Layer error. If the
RESOURCE_NOT_FOUND
category or type is returned to indicate the Application Layer error, the 200 (OK) HTTP Status code is used.
5.2 JSON
There is no specific structure for request and response objects in JSON format. Any JSON compliant messages may be exchanged between clients and services; however, the message schema must be consistent across all service(s) endpoints within the same API. It is recommended to follow Sabre's RESTful API Style Guide for request and response payload schema design in JSON format. Even though the RESTful API Style Guide is dedicated for RESTful services, general recommendations for designing payload schema are universal (particularly the Attribute Names and Prefer Shallow over Deep sections) and can also be utilized for RPC type services.
For JSON message format, used together with the HTTP transport protocol (refer to the HTTP section), the following HTTP headers are required to be provided with the service request:
Content-Type: application/json
Accept: application/json
where:
Content-Type
header specifies the Media type of the body of the requestAccept
header specifies Media type(s) that is/are acceptable for the response
5.2.1 Error element
JSON elements representing a list of errors in a response object must follow Error Format specifications. Here is an example of the response object containing only a list of returned errors:
{
"errors": [
{
"category": "BAD_REQUEST",
"type": "REQUIRED_FIELD_MISSING",
"description": "must not be null",
"fieldName": "toAirportCode",
"fieldPath": "ShoppingRequest.oneWay",
},
{
"category": "BAD_REQUEST",
"type": "INVALID_VALUE",
"description": "must match \"^[A-Z]{3}$\"",
"fieldName": "fromAirportCode",
"fieldPath": "ShoppingRequest.oneWay",
"fieldValue": "Dallas"
}
]
}
5.2.2 Service version
A service operation providing the service version (such as getVersion
operation) should have the following JSON format:
{
"serviceName": "Create Order",
"apiVersion": "1.2",
"implementationVersion": "1.2.15-alpha"
}