Вы находитесь на странице: 1из 42

October 2017

Best Practices for Enterprise APIs


A Reference Guide to Developing Harmonized REST
Application Programming Interfaces in the SAP® Ecosystem
TABLE OF CONTENTS
1 SUMMARY ..................................................................................................................................4
2 INTRODUCTION .........................................................................................................................4
3 PRINCIPLES OF SAP’S FUTURE API HARMONIZATION ..........................................................6
3.1 Using Standards as a Foundation .............................................................................................6
3.2 Creating the Basis for Future Extensions.................................................................................6
3.3 Using OData and Plain REST.....................................................................................................7
3.3.1 Your Decision: OData or Plain REST? ......................................................................................8
3.4 Exposing APIs ............................................................................................................................9
3.4.1 SAP API Business Hub ..............................................................................................................9
3.4.2 API Definition .............................................................................................................................9
3.4.3 API Documentation ....................................................................................................................9
3.5 Common Characteristics of REST APIs ..................................................................................10
3.5.1 Protocol Binding ......................................................................................................................10
3.5.2 API Versioning .........................................................................................................................10
3.5.3 API Features: Invalid, Unimplemented, and Unknown ...........................................................10
3.5.4 URI Formatting .........................................................................................................................12
3.5.4.1 API Namespaces ......................................................................................................................12
3.5.5 Modeling of Resources ............................................................................................................12
3.5.6 Transactional Constraints .......................................................................................................13
3.5.7 State Management ...................................................................................................................13
3.5.8 HTTP Verbs ..............................................................................................................................14
3.5.8.1 Standardized Semantics ..........................................................................................................14
3.5.8.2 Location of a Created Resource ..............................................................................................15
3.5.8.3 Upsert Semantics of PUT.........................................................................................................15
3.5.8.4 Partial Updates and Use of PATCH .........................................................................................16
3.5.8.5 Modeling of Actions .................................................................................................................16
3.5.8.6 Asynchronous Operations ......................................................................................................17
3.5.8.7 Bulk Modifications ...................................................................................................................17
HTTP Status Codes...................................................................................................................................20
3.5.9 Custom HTTP Headers ............................................................................................................20
3.5.10 Error Response: Common Structure ......................................................................................20
3.5.11 Preference Handling ................................................................................................................21
3.5.12 Naming Conventions ...............................................................................................................21
3.5.12.1 General .....................................................................................................................................21
3.5.12.2 Resource ..................................................................................................................................21
3.5.12.3 Resource Attributes .................................................................................................................22
3.5.12.4 Query Parameters ....................................................................................................................22
3.5.13 System Query Parameters .......................................................................................................22
3.5.14 Custom Query Parameters ......................................................................................................23
3.5.15 Data Query Patterns.................................................................................................................23
3.5.15.1 Pagination ................................................................................................................................23
3.5.15.2 Filtering ....................................................................................................................................24
3.5.15.3 Searching .................................................................................................................................24
3.5.15.4 Ordering ...................................................................................................................................24
3.5.15.5 Expand......................................................................................................................................25

2
3.5.15.6 Projection .................................................................................................................................25
3.5.15.7 Number of Elements ................................................................................................................26
3.5.15.8 Inline Count ..............................................................................................................................26
3.5.16 Data Conventions.....................................................................................................................28
3.5.16.1 Currency ...................................................................................................................................28
3.5.16.2 Country Codes .........................................................................................................................28
3.5.16.3 Languages and Language Variations .....................................................................................28
3.5.16.4 Units of Measure ......................................................................................................................29
3.5.17 Content Handling .....................................................................................................................29
3.5.17.1 JSON as Content Type.............................................................................................................29
3.5.17.2 Content Negotiation .................................................................................................................30
3.5.18 Cache Handling ........................................................................................................................30
3.6 Hypermedia/HATEOAS ............................................................................................................31
3.7 Authentication and Authorization ...........................................................................................31
3.8 Plain REST API .........................................................................................................................33
3.8.1 Serialization of Collections......................................................................................................33
3.8.2 Partial Content .........................................................................................................................33
3.8.3 Error Response ........................................................................................................................33
3.8.4 Server-Driven Pagination: Page Size ......................................................................................33
3.8.5 Data Conventions.....................................................................................................................34
3.8.5.1 Date...........................................................................................................................................34
3.8.5.2 Time ..........................................................................................................................................34
3.8.5.3 Timestamp (Datetime) ..............................................................................................................35
3.8.6 Hypermedia Links ....................................................................................................................35
3.9 OData Version 4 API ................................................................................................................36
3.9.1 OData Conformance ................................................................................................................36
3.9.2 URI Formatting .........................................................................................................................36
3.9.3 Error Response ........................................................................................................................36
3.9.4 Modeling of Actions .................................................................................................................37
3.9.5 Naming Conventions: Functions and Actions ........................................................................37
3.9.6 Data Conventions.....................................................................................................................37
3.9.6.1 Date and Time ..........................................................................................................................37
3.9.6.2 Bulk Modifications ...................................................................................................................37
4 APPENDIX ................................................................................................................................38
4.1 Glossary ...................................................................................................................................38
4.2 REST Principles .......................................................................................................................39
5 REFERENCES ..........................................................................................................................40

3
1 SUMMARY
Developers working for customers and partners of SAP build extension applications that consume
application programming interfaces, or APIs (hereinafter we talk only about REST APIs), from various
SAP® application providers, such as SAP S/4HANA®, and from SAP Concur®, SAP SuccessFactors®, and
SAP Ariba® solutions, to name a few. They expect that the APIs that SAP provides are of high quality and
conceptually consistent across all software-as-a-service SAP products, regardless of the SAP development
organization that provides them. To put it simply, consumers expect APIs from SAP to be harmonized.

SAP acknowledges this consumer expectation and recognizes the need for harmonizing APIs throughout
SAP software. In response to this need, SAP defined API harmonization guidelines for its developers to help
them carry out this challenging task in the future. However, since customers and partners of SAP also build
their own APIs that they might want to offer to other consumers in the ecosystem, we decided to make these
guidelines available to them in this reference guide.

The intention of this paper is to cover as many aspects of APIs as possible. Nevertheless, we could not
always formulate standard procedures. For example, the question of when to select OData or plain REST
can be answered only with “it depends.” In addition, business case–specific requirements and technical
conditions may also lead to constraints or even exceptions to the guidelines contained in this document.

Ideally, API implementation teams at customer and partner sites can directly apply the guidelines provided
in this document. If necessary, of course, they also have sufficient flexibility to adapt them to the special
requirements of their respective business scenarios. Nevertheless, if possible, these specific adaptations
should not contradict the core statements of the guidelines provided here.

2 INTRODUCTION
A lot of reasons speak in favor of harmonizing REST and OData APIs. It is a matter of fact that services are
more attractive to the ecosystem if the APIs are consistent, both conceptually and technically. SAP has set
itself the goal of harmonizing its APIs in the future. The practical implication of this initiative should be that
consumers using an API from any SAP provider application can readily understand and use another API
from a different SAP provider application if the concepts of the APIs are identical. From the consumption-
experience perspective, this approach is expected to reduce the learning curve significantly, not only for
developers working for SAP but also for customers and partners. The proposed approaches to achieve this
objective have been condensed in this reference guide to let external API developers benefit from our
experience.

Therefore, the purpose of this document is to provide practical guidance to API developers, basically by
putting the consumer experience at the center of design decisions. Clear guidance is given on how to
design high-quality and conceptually consistent APIs that are compliant with (at least) maturity level 2 of
Richardson’s REST Maturity Model (RMM). 1 RMM Level 2 targets consistent use of the resource concept
and HTTP verbs. Further thoughts on reaching RMM level 3 (hypermedia controls) can be found in the
section Hypermedia/HATEOAS.

This reference guide focuses on the technical characteristics of APIs. The business semantics that APIs
expose are explicitly not in the scope of this document. 2

1
Richardson’s REST API Maturity Model.
2
See the CIO Guide, “SAP Vision for Integrating SAP Applications in Cloud and Hybrid Environments,” which contains
some information on how SAP plans to deal with business semantics of APIs, among other subjects.

4
From a technical point of view, APIs may be classified based on the following attributes:
1. Visibility: Public (customer facing) APIs versus internal or private APIs
2. Access protocol: HTTP, remote function call (RFC) in the ABAP® programming language, message
bus, plain data access (ODBC/JDBC), and others
3. Data object paradigm: Plain REST, OData, BAPI® programming interface, SOAP, and others

We consider only sensible combinations of these attributes. Therefore, this guide deals with public HTTP-
based OData or plain REST APIs. For more details on the OData and plain REST concepts, see the
section Using OData and Plain REST.

The guidelines contained in this document apply only to net-new API development in the first instance.
Nevertheless, by gradually replacing old APIs with new ones, we expect to approach the long-term goal of
having a unified API landscape, where the clear majority of APIs follow the harmonized conventions.

The guidelines provided here apply to technical characteristics of net-new HTTP-


based public APIs implemented using plain REST or the OData paradigm.

This document is intended as a reference guide for developers working for customers and partners of SAP
who build extension applications or design and implement APIs that they want to offer to the ecosystem (see
the section Creating the Basis for Future Extensions).

Document Conventions
As an API developer, you are not forced to adhere to the guidelines provided in this document. However, we
think it useful to state them the same way we did in our internal guidelines. These conventions rely on RFC
2119: The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD
NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” must be understood as described in that best current
practice. 3

The most important usages of these key words can be summarized as follows: MUST (in uppercase letters)
means that the guideline is mandatory, and SHOULD (in uppercase letters) stands for a reasonably good
implementation (a best practice). Following a SHOULD will help achieve further harmonization and ease the
lives of API consumers. If applying the best practice is not feasible (for example, if it is too expensive in the
concrete case), it might be possible to deal with the given characteristic in a different way.

The guideline statements are mostly accompanied with an example, which is set in a monospace font.
The HTTP communication is shown schematically. It does not contain all the technical details but only the
relevant parts. The examples, for which it is important to separate request and response data, mark the
requests with the symbol ‘’, and the responses with ‘’. For the sake of brevity, the examples use relative
Uniform Resource Identifiers (URIs). The examples are fictional and not part of any SAP API or service
offering.

Terminology
In the Appendix section, you will find additional information that may prove helpful to understand some
aspects of the guidelines. Additionally, we explain some terms and provide you with a short recap of REST
principles.

3
RFC 2119: Key Words for Use in RFCs to Indicate Requirement Levels.

5
3 PRINCIPLES OF SAP’S FUTURE API HARMONIZATION

3.1 Using Standards as a Foundation


In this reference guide, we follow industry standards (IETF, ISO, and OASIS) where possible and
appropriate, naturally preferring them over locally optimized solutions.

If the guidelines provided here do not cover certain aspects you need to implement, you, as the API owner,
MUST apply the following approach:
1. Search for an appropriate industry standard: IETF RFC MUST be your preferred source of
information; if you do not find the appropriate industry standard in RFC, you SHOULD search ISO
and OASIS.
2. If you still cannot find any appropriate industry standard, look for a corresponding best practice. 4
3. If your needs are not addressed there (which means that you have a very specific use case), look for
internal best practices.
4. If you fail to find an appropriate best practice, you will need to define your own specific
way to fulfill your requirement. In such a case, the design decisions MUST be
adequately documented.

IETF, ISO, and OASIS are the primary sources of information to look at
when performing the task of harmonizing REST APIs.

3.2 Creating the Basis for Future Extensions


This reference guide can be used as a starting point for more business-specific REST API guidelines if
required. We aimed at formulating these guidelines so that they are generally applicable. Therefore, we
make as few assumptions about business specifics as possible (for example, regarding the authentication or
support infrastructure that a certain business organization is using). More specialized guidelines SHOULD
consider such specifics to address more concrete requirements of the business APIs. However, these
special guidelines MUST NOT contradict the core elements of the guidelines provided here. (Core elements
are those defined as MUST requirements.) They MAY set additional constraints on top of the guidelines and
MAY redefine SHOULD requirements derived from the particularities of the business.

MUSTs are hard requirements, but SHOULDs can be redefined by more


specific API guidelines.

You are not required to implement all the characteristics described in this document (pick-and-choose
principle). You SHOULD pick the characteristics depending on your concrete use case. This common
development principle in software is important and you SHOULD adhere to it when implementing API
features.

For example, if the logic of an API requires only an equal or nonequal comparison for filtering, the
corresponding API implementation MAY include only needed capabilities (excluding lt, gt, and so on)
These partial implementations MUST be adequately documented in API Documentation. At runtime, the
proper reactions of a given API to calls requesting features that are not implemented or only partially
implemented are described in the section API Features: Invalid, Unimplemented, and Unknown.

4
See, for example, Apigee Web API Design, Microsoft REST API Guidelines, and Zalando RESTful API Guidelines.

6
3.3 Using OData and Plain REST
Both OData and plain REST APIs implement REST principles (are RESTful in this sense) and often also
express very similar concepts, such as pagination and filtering.

OData is a REST protocol standardized by OASIS and ISO. 5 It offers a highly consistent specification that
allows implementation of high-quality APIs based on entity relationship models. In addition, it offers stacked
compliance levels. On the higher optional levels, it standardizes the following aspects: query language,
interaction patterns, metadata for self-describing services and APIs, and metadata extension mechanisms
through vocabulary-based annotations. OData was initially created by Microsoft Corporation and is currently
being used by a growing ecosystem of enterprise software companies (IBM Corporation, Red Hat Inc., and
others). 6 In addition, it is being widely adopted by other large firms and governmental institutions.

Plain REST (lacking a better term) is a community-driven flavor of REST. In the absence of a common
specification, plain REST is mainly based on different best practices suggested by different community
groups. Consequently, it is highly fragmented in numerous implementations. Nevertheless, the lack of a
specification may also be regarded as an advantage, because it enables development of APIs with relatively
low effort and high flexibility, putting the focus on the use cases rather than on fulfilling the requirements of
a standardized framework such as OData. Currently, large service providers such as Facebook Inc. and
LinkedIn Corporation expose plain REST APIs. You can find some best practices for designing plain REST
APIs in Apigee Web API Design, Microsoft REST API Guidelines, and Zalando RESTful API Guidelines.

The following observations complement the above explanations:


• REST itself specifies only very few aspects, such as the semantics of HTTP verbs. The REST
community, however, has defined best practices that specify more aspects. These community-
defined best practices sometimes compete against each other. The best practices to declare a data
query filter are an example of this competing situation. When using plain REST, it is up to the API
provider to select the concepts that should be used. In the past, we at SAP often made different
decisions for the same aspect, which resulted in heterogeneous APIs.
• OData and plain REST conventions show some differences. Nevertheless, we observed that these
differences are, in the end, not larger than the differences between two arbitrarily chosen plain REST
implementations.

Currently, SAP provides applications and services that historically expose either OData or plain REST APIs
in their respective customer and partner ecosystems. Therefore, it is not a matter of preferring one over the
other. In other words, SAP will continue to support both conventions equally.

SAP will continue to support and expose APIs that are built following either
the plain REST or OData conventions.

5
ISO/IEC JTC 1 Approves OASIS OData Standard for Open Data Exchange.
6
For example, Red Hat Teiid.

7
Nevertheless, our goal is to minimize inconsistencies among plain REST APIs and among them and OData
APIs. For this purpose, we aim to standardize our plain REST conventions and bring the conventions for
plain REST and OData APIs closer together. The resulting approach assumes the following:
• Plain REST APIs follow selected OData Version 4 conventions where possible and appropriate.
For example, if a plain REST API implements data filtering, the format of the expression language
for filtering MUST be OData Version 4–compliant. This approach in turn will make consumption
easier for customers and partners, especially if they consume OData and plain REST APIs from a
REST client because both have a similar look and feel. Note that this assumption does not imply
that everything plain REST APIs provide should conform with OData. For example, plain REST APIs
do not need to implement runtime metadata access by providing a $metadata endpoint.
• Consumers of REST APIs know and respect the conventions reflected in plain REST APIs by
Concur and SAP Ariba solutions (as well as in the APIs implemented and promoted by other market
players such as Facebook Inc., Google Inc., Twitter Inc., and others). To enable consumers to
project their knowledge about these APIs to the entire set of SAP APIs, selected OData
conventions converge in community-based conventions. For services that use the OData format
for their APIs, SAP chooses OData Version 4 because this version substantially increased its
openness toward different API conventions compared to OData Version 2. 7 OData Version 4
(specifically, upcoming version 4.01) allows developers to implement community-based conventions
in OData-conforming APIs. OData Version 4 fixes many of the undesirable attributes of earlier
versions that prevented harmonization with plain RESTful interfaces. One prominent example is
the URI formatting convention with forward slashes instead of brackets (also known as key-as-
segment). 8 This approach enables consumption of OData Version 4 and plain REST APIs in the
same way.

We are unifying selected conventions in plain REST and OData APIs to


provide a harmonized consumption experience.

3.3.1 Your Decision: OData or Plain REST?


The policies the API provider adheres to often influence the decision to use OData or plain REST. For
example, does an internal development policy exist within the provider’s organization that prescribes either
of these flavors of REST? Another important consideration is the target consumer ecosystem of the provider.
Is it biased toward OData or plain REST?

Although the decision to use OData or plain REST may go beyond the responsibility of the implementation
team (and be made at the organization’s top level), we would like to provide some indicators to help make
the decision:
• If business or architectural decisions exist within your organization that may be based on the target
ecosystem and the infrastructure used, you will naturally comply with the respective guidelines for
developing APIs associated with them.
• OData is usually indicated if you intend to expose APIs that will be consumed by user interfaces
(UIs) of SAP Fiori® apps (browser-based or iOS-native).
• OData is also the right choice if you are relying on core data services (CDS) as a descriptive
model of a data layer.
• Implementing OData on target technology platforms other than Java, node.js, .Net, or ABAP may be
difficult because they lack library support. In such cases, plain REST would be the better option.

7
OData Version 4.01. Part 1: Protocol.
8
OData Version 4.01. Part 2: URL Conventions.

8
3.4 Exposing APIs

3.4.1 SAP API Business Hub


At SAP, all public APIs MUST be exposed in SAP API Business Hub, which enables consumers to discover
and try them out easily. Additional requirements regarding API definition and documentation are described in
the following sections.

APIs MAY be additionally exposed through local API publishing solutions that target business-specific
ecosystems.

APIs that were developed for specific customer groups or single customers MAY NOT be published in
SAP API Business Hub.

3.4.2 API Definition


An API definition is a description of the API in terms of a metamodel like OpenAPI, 9 EDM (Enterprise Data
Modeling), or RAML. 10 Explicit definition of APIs in these metamodel languages offers great benefits for both
consumers and providers. Normally, APIs defined by using these metamodels lead to better-designed APIs
because the design is more explicit for the provider and acts as a single source of truth for consumers.
It represents a machine-readable document that enables generation of other artifacts from it, such as
documentation and client-side consumption libraries.

Every API MUST be explicitly defined. Plain REST APIs SHOULD be described in the OpenAPI model (also
known as Swagger), version 2.0 and higher. Owners of OData APIs MUST use the OData standard model
language (EDM) to describe them.

3.4.3 API Documentation


API documentation MUST include the following information:
1. API version (see the section API Versioning)
2. API classification tags
3. Information about the semantics of API elements (normally generated from API Definition)
• Resources
• Resource attributes
• API-specific query parameters
• API-specific error responses
4. Behavioral restrictions and distinctive features such as:
• The API is not designed for retrieval of mass data (all records in one request)
• The API call violates the atomicity assumption (all or nothing)
• The API implements partial updates, but they are not idempotent

Furthermore, the API documentation SHOULD include:


• Examples of API usage (normally generated out of corresponding model parts of the API Definition)
• API terms of use (such as the promised time frame for the availability of the version)

9
OpenAPI Initiative.
10
RAML (RESTful API Modeling Language).

9
3.5 Common Characteristics of REST APIs

3.5.1 Protocol Binding


REST APIs MUST be exposed as HTTPS (TLS/HTTP) endpoints. The Minimum Hypertext Transfer Protocol
(HTTP) version MUST be 1.1; the minimum Transport Layer Security (TLS) version MUST be 1.1.

3.5.2 API Versioning


All APIs MUST be versioned. An API version has the semantics of a compatible state. Changes inside a
given API version MUST NOT lead to a compatibility breach on the consumer side. 11

Every API version is assigned to the corresponding namespace. As stated in the section API Namespaces,
the semantics of namespaces is flexible. Therefore, the API owner has some flexibility to define the
granularity of the versioned API.

Although an API SHOULD keep the compatibility guarantee as long as possible, incompatible changes
cannot always be avoided. If incompatible changes are necessary, the API owner MUST increase the API
version to account for this fact.

Every API version MUST be represented as whole number. Semantic versioning such as
<major.minor.patch> MUST NOT be used. The version number increases sequentially in response to
the need for introducing incompatible changes. This number always corresponds to the major part of the
semantic versioning notation.

Every API version MUST be part of the API URI. In the URI, the version MUST be encoded as a single
decimal integer, which SHOULD be preceded by a lowercase “v”.

The decision to encode the API’s version in the URI was motivated by the necessity to maintain several
implementations of the API in parallel. This approach enables consumers to bind to an implementation
without taking the risk of unexpected disruptions due to incompatible changes. Besides, this information
makes the client logic more straightforward.

Example:
https://api.sap.com/retail-store/v1/products/123

3.5.3 API Features: Invalid, Unimplemented, and Unknown


Applying the pick-and-choose principle may lead to exposing features that are not yet implemented or only
partially implemented. Data query parameters are examples of such features ($filter, $orderby, and
others).

By definition, a feature that is not implemented is a feature that is completely missing in the API
implementation. A partially implemented feature is a feature for which some of the options are missing,
while others are available. Filtering operations are examples of such options (for instance, lt, gt,
and eq).

Although API Definition and API Documentation should contain information for the consumer about the sets
of features and options the API implements, the client requests may assume some features that are not or
are only partially implemented. At the same time, a request can contain invalid values or values that are
unknown to the API. The API should behave differently depending on the case at hand. We need to consider
three fundamentally different situations:

11
An extensive list of compatible changes can be found in OData Version 4.0. Part 1: Protocol Plus Errata 03. Model
Versioning.

10
The API Detects Invalid Values in the Request
The API MUST return 400 Bad Request. The error response MUST indicate the erroneous value.

Example:

GET /products?$filter=a xx 'b'

400 Bad Request
{
"error": {
"code": "98698676",
"message": "Illegal operation in $filter: xx"
}
}
Because xx is an invalid operation in the $filter context, 400 Bad Request is sent as a response.

The API Detects Unknown, Syntactically Valid Values


The API SHOULD ignore the values and process the request as if the values were not present. This
approach matches the programming paradigm of the major implementation frameworks (Spring MVC,
JAX-RS, and Node Express), letting you define the processing rules for relevant (and known) features
(for example, injecting relevant query parameters into a controller) and ignoring all others by default.

Example:

GET /products?unknownParameter=unknownValue

200 OK
{
"value": {[{
"id": 123,

}]}
}

The API Detects Valid Values That Require Features or Options That Are Not Implemented
It may happen that the API implemented only part of a closed enumerable set of options for the features
(for example, only eq out of eq, ne, lt, gt, le, ge, not, and has for $filter) or is planning a
feature that is not yet completely done. In both cases, the API knows about the feature or option, unlike
the previous case (unknown values). Note that for open sets of options (for example, content types for the
OData $format query parameter), as well as for valid but not planned features (and hence not known to
the API), the handling is fundamentally the same as for the case with unknown values.

If valid values are detected that require features or options that are not implemented, the API MUST
consistently return 501 Not Implemented. The error response MUST contain an indication of the
not-implemented feature or option.

Example:

GET /products?$filter=(name eq 'KittyFood' and availableAmount gt 30)

501 Not Implemented
{
"error": {
"code": "0989890",
"message": "gt operation is not supported"
}
}

11
3.5.4 URI Formatting
The convention for URI formatting is:
<host>/<API namespace>/<API version>/<Resource>

Overall, the URI MUST comply with IETF RFC 3986. 12

The syntax and semantics of the host part MAY vary depending on several things, such as the concrete
organization, topology of their network, and the API gateway being used. Other parts are described in the
concrete naming conventions below (OData and plain REST).

Example: https://api.sap.com/retail-store/v1/products/123

3.5.4.1 API Namespaces


The API namespace is a grouping mechanism that keeps together APIs that are semantically close to each
other.

The APIs that belong to a namespace have a common lifecycle. Therefore, they MUST be versioned
together. The granularity of a namespace MAY be selected on a case-by-case basis. However, this
approach is a trade-off. If the granularity is too coarse, you lose flexibility to separate versions of the
contained moving parts. If it is too fine, the consumer may have to deal with too many version permutations.
A common best practice is to use the notion of bounded context, as known in the domain-driven design
methodology. 13

The API namespace generally reflects the business specifics (from business model to API gateway
configuration) and hence cannot be standardized beyond a given business area.

The API namespace SHOULD contain parts that identify the line of business to avoid name collisions.
Furthermore, it SHOULD sufficiently describe in the namespace the functionality of the API.

The API namespace SHOULD follow the lowercase naming convention.

Example: https://api.sap.com/sap/retail-store/v1/products/123

An API namespace defines a unit of versioning. Its granularity depends


on the business specifics.

3.5.5 Modeling of Resources


REST APIs SHOULD be generally modeled as a resource hierarchy, where each node is either a simple
resource or a collection of resources. For brevity, they are often called resource or collection, respectively.
• A collection (known as entity set in OData terms) MAY contain resources, in which case they MUST
have the same type. For example, a user has a collection of contacts.
• A resource (known as entity in OData terms) has a certain state and MAY have zero or more
subresources. Each subresource can be either a simple resource or a collection resource.

For example, an online store API has a collection of products. Each product can have a collection of
categories it is assigned to (for example, <clothes>, <fashion>, and so on), a collection of variants (for
example, color, size, or localization), and an associated discussion forum resource.

12
RFC 3986: Uniform Resource Identifier (URI): Generic Syntax.
13
Domain-driven design.

12
A resource in a collection SHOULD be identified either by a simple or a complex identifier. A simple identifier
SHOULD be modeled as a single segment in the URI. A complex identifier SHOULD be modeled as multiple
segments in the URI, separated by forward slashes. Natural singletons (for example, a user profile) MAY be
treated as a simple resource without an explicit identifier.

Examples:
https://api.sap.com/retail-store/v1/users/123/profile
https://api.sap.com/retail-store/v1/categories/456/789
https://api.sap.com/retail-store/v1/categories/456/789/products

For more information on resource naming conventions, see the Resource section.

Resources are modeled as collections or simple resources. Resource


models should be as decoupled from the persistence model as possible.

Although some conceptual alignment between the persistence layer of the API implementation and REST
APIs exists, an implementation with a resource-oriented API is not necessarily a database and has
enormous flexibility regarding how it interprets resources and methods. For example, creating a calendar
event (resource) may create additional events for attendees, send e-mail invitations to attendees, reserve
conference rooms, and update video conference schedules.

3.5.6 Transactional Constraints


A REST API SHOULD guarantee that the changes made in an API call are atomic (all or nothing). This
guarantee is true for both synchronous and asynchronous calls. The latter merely indicate that the operation
is not finished upon returning from the call, as described in the section Asynchronous Operations, but the
operation itself is expected to be atomic. If the API deliberately violates this principle, the API owner MUST
appropriately document this situation in API Documentation. (For example, leftovers may result from a failure
situation, and hence compensation actions may be required to bring the system back into a consistent state).

3.5.7 State Management


Following the REST principles, state management must be dealt with on the client side.

Stateful REST APIs (where the API implementation keeps the state on the server side and typically requires
an HTTP session-handling mechanism to manage it) SHOULD be avoided. Stateful implementations
typically impose issues with elastic horizontal scalability and are therefore considered an antipattern in the
cloud.

The primary HTTP means for client-side state management is described in IETF RFC 7232. 14

On the implementation side, the data state is transferred to the client by means of an entity tag (passed by
the ETag HTTP header) within a response that retrieves a data set. Afterward, this value may be used in
subsequent requests to reference the state by using the ETag value in conditional HTTP headers, such as
If-Match, If-None-Match, and others, as generally described in IETF RFC 7231 and 7232. 15

The client can use this mechanism for cache management (conditional GET), optimistic locking (conditional
PUT), and idempotent partial update (conditional PATCH).

Every API SHOULD be able to calculate and provide a value for the ETag in the output. Remember that
missing implementation of ETag handling prohibits implementation of idempotent partial updates, as
described in Partial Updates and Use of PATCH.

14
RFC 7232: Hypertext Transfer Protocol (HTTP/1.1): Conditional Requests.
15
RFC 7231: Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content (and previous footnote).

13
An exact mechanism of calculation of ETag values is to be decided by the API implementation. A
nonexhaustive set of options may include values, based on a modification time stamp, data hash value, or
incremental data version number.

Every API SHOULD be able to process conditional HTTP requests, based on corresponding HTTP headers.

3.5.8 HTTP Verbs

3.5.8.1 Standardized Semantics


IETF RFC 7231 16 and IETF RFC 5789 17 standardize the semantics of HTTP verbs.

As described in the section REST principles, a RESTful interface SHOULD implement the QCRUD (Query,
Create, Read, Update, and Delete) functionality on resources (see the section Modeling of Resources)
following the pick-and-choose principle, which states that only the functionality needed by the target usage
scenario should be implemented.

The functionalities map to:


• Query – request a collection of resources
• Create – request creation of a resource
• Read – request a single resource
• Update – request complete or partial modification of a resource
• Delete – request resource deletion

In a RESTful QCRUD interface, the HTTP verbs MUST have the meaning as established in IETF RFC 7231
and IETF RFC 5789.

Example (Query):

GET /products

{
"values": [{
"id": 123,
"productName": "Kitty Food"
}, {
"id": 456,
"productName": "Doggy Food"
}]
}
Example (Create):

POST /products
{
"productName": "Kitty Food"
}

201 Created
Location: /products/123
{
"id": 123,
"productName": "Kitty Food"
}

16
RFC 7231: Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content.
17
RFC 5789: PATCH Method for HTTP.

14
Example (Read):

GET /products/123

{
"id": 123,
"productName": "Kitty Food"
}

3.5.8.2 Location of a Created Resource


APIs SHOULD return the HTTP header Location with a URI (absolute or relative) pointing to a created
resource in response to a POST request if the resource creation was successful (response code 201
Created). In this case, APIs SHOULD also return the attributes of the created resource in the payload of
the response, to allow the client to use it without making an additional HTTP call.

Example:

POST /products
{
"productName": "Kitty Food"
}

201 Created
Location: /products/123
{
"id": 123,
"productName": "Kitty Food"
}

3.5.8.3 Upsert Semantics of PUT


Following IETF RFC 7231, 18 PUT can be used not only to express pure update semantics but also to
implement an upsert operation. The latter is an operation that creates an object with a corresponding ID and
assigns the values communicated in the request payload to the object; if the object with the same ID already
exists, the upsert operation updates it with the values.

Generally, the upsert approach has an important prerequisite from the implementation perspective: External
identifiers (like Universally Unique Identifiers [UUIDs]) must be assigned to the resources and communicated
to the client in some way. Ideally, the assignment should be decoupled from internal identifiers like database
record IDs to avoid breaking encapsulation. APIs MAY implement the upsert semantics in a PUT request
if the use case requires the API implementation to behave differently, depending on the existence of the
resource. If the resource does not exist, the request will create it in the same server-side transaction. A
valid scenario for upsert is when a system state should be replicated from a source to a target landscape.
For this purpose, the source system uses the same external IDs used to create new resources in the target
system with the same attribute values. If the resource already exists, it will be updated with the value of
the source resource. If the upsert semantics is implemented, this behavior MUST be described in the API
documentation, including information on how to get an existing valid external resource identifier or how to
build a new one.

Although there are valid scenarios for using the PUT request to carry out an upsert operation, it is not a
commonly used best practice (and, hence, not expected by the consumer). Therefore, unless the use case
demands it, APIs SHOULD NOT rely on the upsert semantics of PUT. Instead, APIs SHOULD use PUT for
updates. “Create” operations SHOULD be implemented by means of POST requests.

18
RFC 7231: Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content.

15
If upsert semantics is avoided and the addressed resource is not found, PUT MUST return 404 Not Found
(see also the section HTTP Status Codes).

3.5.8.4 Partial Updates and Use of PATCH


A partial update is an operation that updates only a subset of the data set of a resource, keeping the
remaining attributes intact. IETF RFC 5789 19 suggests using the HTTP verb PATCH for this purpose.

PATCH is generally considered not to be idempotent, because it does not transfer the content of the entire to-
be-updated data set (like PUT does), so that the result of the update operation may depend on the data set
values that are not part of the request. Hence, the same PATCH request may fail for some values of the data
set (those not part of the request) and succeed for others. This situation ultimately means that PATCH as
such is not idempotent.

A solution to this problem is suggested in IETF RFC 5789. It proposes using state management on the client
side, as described in the section State Management. A client assumes that a data set retrieved through the
service (for example, by means of a GET request) is always consistent. Data retrieved by a GET request
contains an ETag value (see State Management). It describes the state of the data (its fingerprint). PATCH
can update only some of the attributes, assuming a known state (previously retrieved ETag value) as a
consistent baseline (known basepoint according to RFC 5789). When sending PATCH, the request
references this baseline in the If-Match HTTP header.

If the state has changed since the last GET by being fired by the client (someone has modified the data in the
meanwhile, which results in updating the state fingerprint value), the assumption of the PATCH request is
broken. In this case, the value of If-Match would not be the same as the current data state fingerprint
known to the API implementation. The API in this case denies updating the data and MUST respond with
409 Conflict.

If the data has not changed since GET, the API implementation updates the data, recalculating the data state
fingerprint and, in case of success, returns 200 OK.

If an API implements partial updates, it SHOULD guarantee idempotence of partial updates by using ETag
and conditional HTTP headers.

Example:

PATCH /products/123
If-Match: "456"

3.5.8.5 Modeling of Actions


Actions SHOULD be modeled using the HTTP verb semantics. You SHOULD NOT use verbs denoting the
action in the URI itself (for example, <POST /products/123/activate>).

In the simplest case, applying a CRUD action to a resource is common best practice. Nevertheless, this
action can be modeled in different ways. The main architectural principle to be applied here is a clean
decoupling of the API resource model from the entity model in the persistence layer as described in
Modeling of Resources. This principle enables you to apply the CQRS pattern 20 to the API processing logic.
In doing so, a modification operation on a resource may apply arbitrary business logic that is basically
equivalent to the action semantics.

19
RFC 5789: PATCH Method for HTTP.
20
CQRS.

16
The sections below show examples equivalent to <POST /products/123/activate>, but using noun
notation instead of a verb in the URI. They use logical attributes or logical resources (sometimes called intent
resources), decoupled from the persistency model.

Action as an Attribute Change


If an action changes one resource attribute (or a set of resource attributes), you SHOULD model this as a
partial update of the resource, that is, an update of exactly this attribute or set of attributes. For more details,
see the sections Partial Updates and Use of PATCH and Partial Content (plain REST API–specific; delta
content syntax should be used in OData to describe a change set).

Example:

PATCH /products/123
Content-Type: application/merge-patch+json
{
"active": true
}

Action as a State Change of a Resource


In this case, you model an associated resource as a state machine. This approach is useful if the state
processing needs to be isolated (for example, because the state graph is too complex or multidimensional).
The action is then modeled as a change of the state of an associated resource – create or update request on
the resource – depending on the concrete case.

Example:

POST /products/123/state
{
"publishing": "activated"
}

3.5.8.6 Asynchronous Operations


To indicate the start of an asynchronous operation (normally POST, but it may also be applied to other
modifying HTTP verbs), every API that implements asynchronous processing MUST return the HTTP status
code 202 Accepted, accompanied by a Location HTTP header. The value of the Location HTTP
header is used to point to a resource that allows polling the result. The URI of the resource MAY be relative
or absolute with respect to the original resource.

Example:

POST /products
{
"productName": "Kitty Food"
}

202 Accepted
Location: /shelves/567

3.5.8.7 Bulk Modifications


Sometimes you need to modify (create, update, or delete) several entries at once. To implement the
modifications, APIs MUST rely on the standard meaning of HTTP verbs (see the section Standardized
Semantics). Further recommendations for implementing concrete operations are given below.

The HTTP status codes MUST indicate the results of the operation with the same semantics as for single
elements (see HTTP Status Codes).

17
If multiple errors occur (due to a multiplicity of resources in the request), the error response SHOULD
contain information about all the occurrences in the details section (see the section Error Response:
Common Structure).

The following description provides a simple and lightweight approach to implementing bulk operations under
the assumption that the entire operation is expressed by a single atomic request. This assumption may be
difficult to hold if the API implementation follows a distributed architecture (for example, an application that
is based on microservices architecture). Especially if the resources in the collections represent logical
resources (see Modeling of Resources) that are backed by resources in different parts of a distributed
application (microservices), it can be very hard to guarantee the transactional consistency of the call (see
the section Transactional Constraints). If bulk modifications are required by the business scenario, but you
cannot guarantee atomic modification, you MUST clearly document this situation in API Documentation.
If more complex semantics are required (combining different requests with multiple atomicity groups and
dependencies between requests), APIs SHOULD implement it in the same way as batch request in OData. 21

Create
In the create case, APIs SHOULD use the POST verb and expect a collection of resources (for example, a
JSON array if JSON is used as content type), instead of a single resource in the request.

Example:

POST /products
{
"value": [{
"productName": "Kitty Food",
"productDescription": "Meow!",
"productPrice": {
"value": 33.99,
"currency": "USD"
}
}, {
"productName": "Doggy Food",
"productDescription": "Woof!",
"productPrice": {
"value": 42.99,
"currency": "USD"
}
}]
}

Update
For bulk updates, APIs SHOULD use the PATCH verb with partial update semantics. Partial update
semantics is then applied on both levels: Collection level to update only a few resources in the collection
and resource level to update each resource partially.

The request content (resources to be updated) MUST contain an array with change set semantics for OData
delta changes if OData is used, and partial content if plain REST is used).

Patching of collections can have upsert or update semantics. To enforce the update semantics (preventing
the creation of a new resource in the collection and only updating existing ones), APIs MUST use the If-
Match header with the value corresponding to the previously returned ETag value for the collection.

21
OData Version 4.01. Part 1: Protocol.

18
Example:

PATCH /products
Content-Type: application/merge-patch+json
{
"value": [{
"id": 123,
"productName": "Tasty Kitty Food",
"productPrice": {
"value": 34.99,
}
}, {
"id": 456,
"productDescription": "Woof!",
"productPrice": {
"value": 42.99,
"currency": "USD"
}
}]
}
Delete
Applying deletion semantics on the collection level with a list of entries is difficult because a DELETE HTTP
request does not have a body. Therefore, there is no technical way to express a change set.

For a bulk delete operation, APIs SHOULD rely on tombstoning (see the Glossary) rather than on the
physical deletion of entries.

Note: An exception to this rule may be indicated if processing of person-related data is required. Depending
on the legal requirements, such data may need to be deleted physically.

Tombstoning is a special case of bulk update, where a deleted attribute is set to true. Consequently, to
perform tombstoning, APIs SHOULD rely on the PATCH verb for implementing the operation.

Example:

PATCH /products
Content-Type: application/merge-patch+json
{
"value": [{
"id": 123,
"deleted": true
}, {
"id": 456,
"deleted": true
}]
}

19
HTTP Status Codes
APIs MUST consistently use the meaning of HTTP status as described in IETF RFC 7231.

3.5.9 Custom HTTP Headers


If an API requires using custom HTTP headers to avoid conflicts with other APIs (consuming APIs may
belong to different organizations), the headers MUST be assigned to a specific namespace. Custom HTTP
headers starting with the “X-” prefix MUST NOT be used. Note that IETF has deprecated this form of custom
HTTP headers. 22

The naming convention for custom HTTP headers is <organization>-<header name>, where
<organization> and <header> MUST follow the lowercase-dashed convention.

Example:
concur-correlationid: 456

3.5.10 Error Response: Common Structure


Error handling is carried out on two levels: On the protocol level (HTTP) and on the application level. On the
protocol level, the error handler of the API MUST return an appropriate HTTP status code as described in
HTTP Status Codes.

On the application level, the handler MUST return a payload that contains the following attributes (wrapped
in the error field):
• Code: Technical code of the error situation to be used for support purposes
• Message: User-facing (localizable) message describing the error

The error structure MAY contain a target attribute that describes a data element (for example, a resource
path).

If error processing requires nesting of error responses, it MUST use the details field for this purpose.
The details field MUST contain an array of JSON objects that shows code and message properties with
the same semantics as described above.

Plain REST and OData implementations MAY use response extension mechanisms as described in the
corresponding sections below.

Example:

404 Not Found
{
"error": {
"code": "0977658587",
"message": "Product with ID 123 not found",
"target": "/online-store/v1/products/123",
"details": [{
"code": "9827389374",
"message": "Empty result set"
}]
}
}

22
Deprecating the "X-" Prefix and Similar Constructs in Application Protocols.

20
Error response messages SHOULD be localizable. They SHOULD react in a standard way 23 to the presence
of an Accept-Language HTTP header.

3.5.11 Preference Handling


If an API allows a client to configure values and therefore to influence how the API implementation
processes the request, it SHOULD use a protocol as described in IETF RFC 7240. 24

The client requests applying a preference by passing the Prefer HTTP header as a part of the request.

Example:
Prefer: maxpagesize=X
If the API implementation respects the client preference, it SHOULD return the Preference-Applied
header with the corresponding preference and value.

Example:
Preference-Applied: maxpagesize=X
The API implementation MAY disregard the client preference. In that case, it MAY return the Preference-
Applied header with its own value or not return the header at all.

The nomenclature of preferences that may be set by using the Prefer header MUST be recorded in
API Documentation.

3.5.12 Naming Conventions

3.5.12.1 General
We aim to establish a unified naming convention for resource names, resource attributes, custom query
options, functions (OData), and actions (OData). In all these cases, camelCase is the preferred convention
(meaning either lowerCamelCase or UpperCamelCase, see also the Glossary). Use of other conventions
(lowercase, lowercase-dashed, lowercase_underscore, and so on) SHOULD be avoided.

The camelCase convention:


• Provides good readability
• Maps the names to the entities in programming languages without further interaction

Good examples of camelCase are accountDetails (for lowerCamelCase) or AccountDetails


(for UpperCamelCase).

3.5.12.2 Resource
A resource is that part of a URI that denotes a type for the subject of an operation. Operations normally
address either a group of resources or only one. In both cases, a resource SHOULD be named in plural
(even if it is one resource of a group), followed by a unique identifier. This approach addresses a concrete
specimen of the resource type.

An exception to this rule is a natural singleton, where only one resource of a type exists (for example, a user
profile). In this case, a resource MAY be named using the singular form.

For naming resources, APIs MUST use correctly spelled American English words or combinations of them.
You MUST avoid using words in other languages in your APIs, except for resources that are localized due to
business requirements. In such cases, the resource names MUST be represented by correctly spelled words
or combinations of them in the target language.

23
RFC 7231: Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content.
24
RFC 7240: Prefer Header for HTTP.

21
Resource names MUST follow the camelCase naming convention. The association paths MUST be
separated with forward slashes.

Examples:
https://api.sap.com/retail-store/v1/products
https://api.sap.com/retail-store/v1/products/123
https://api.sap.com/user-management/v1/users/123/profile
https://api.sap.com/user-management/v1/users/123/accountDetails

Resource names are case sensitive. That is, accountDetails and AccountDetails represent different
resource names.

3.5.12.3 Resource Attributes


Resource attributes are represented by fields in the payload.

For naming resource attributes, APIs MUST use correctly spelled American English words or combinations
of them. You MUST avoid using words in other languages in your APIs, except for resources that are
localized due to business requirements. In such cases, the resource names MUST be represented by
correctly spelled words or combinations of them in the target language.

Resource attributes MUST follow the camelCase naming convention.

Example:
{
"id": "123",
"productName": "Kitty Food",
"productDescription": "Yummy!",
"productPrice": {
"value": 33.99,
"currency": "USD"
}
}

Resource attribute names are case sensitive. That is, productPrice and ProductPrice represent
different attribute names.

3.5.12.4 Query Parameters


Query parameters 25 are expressed in one of the following formats:
• <query parameter name>
• <query parameter name>=<query parameter value>

Error handling for not-implemented, partially implemented, and invalid query parameters MUST follow the
rules described in API Features: Invalid, Unimplemented, and Unknown.

3.5.13 System Query Parameters


System query parameters have reserved names and a predefined meaning. The names of system query
parameters are preceded by a “$” sign, which corresponds to the OData convention. System query
parameters are currently used in Data Query Patterns.

25
RFC 7231: Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content.

22
3.5.14 Custom Query Parameters
Custom query parameter names MUST follow the camelCase naming convention.

Example:

GET /products?availableBy=2017-09-04

3.5.15 Data Query Patterns


Note: OData APIs fulfill the requirements automatically because the conventions are taken from the OData
specification. 26

Plain REST APIs should follow the pick-and-choose principle and select the appropriate set of operations to
be implemented based on the use case requirements.

3.5.15.1 Pagination
Pagination is a mechanism for a client to retrieve data in portions. It is mostly intended for APIs that serve
data for multiscreen UIs (for example, a product catalog). Normally, a paginated request does not create a
snapshot of the data, that is, data is delivered without guaranteeing idempotence. That means that the same
request with the same query parameters can deliver different results if the data set is changed between the
requests.

There are two ways to implement pagination: Client-driven (the consumer decides what portions of the
data are to be retrieved) and server-driven (the server establishes page-cutting and provides additional
information about the locations of the previous and next page; the client still may have the possibility to
configure the page size).

Client-driven pagination is normally chosen for consumer flexibility, and server-driven pagination is used for
achieving optimizations on the server side (for example, caching, protection against denial of service by
selecting a too large page size, and others).

Client-Driven Pagination
To implement client-driven pagination, APIs MUST use the following syntax:

$top=<number of items to deliver>&$skip=<number of items to skip>

Where $top is the number of items to be returned (page size), and $skip the number of items to be
skipped (offset).

Example:

GET /products?$top=10&$skip=20

Server-Driven Pagination
To implement server-driven pagination, the API that returns pages of data MUST include a link that allows
retrieving the next page in the response. In addition, it MAY include a link to retrieve the previous page. The
final partial set of items MUST NOT contain a link to the next page. The first partial set of items MUST NOT
contain a link to the previous page.

The links MUST use relation names in a way that is compliant with IETF RFC 5988. 27 The link to the next
page MUST use the relation name next. The link to the previous page, if implemented, MUST use the
relation name previous.

26
OData Version 4.01. Part 1: Protocol.
27
RFC 5988: Web Linking.

23
In case the API should be designed to support the option of letting the client change the page size, this
MUST be implemented by using Preference Handling.

Page-size handling for server-driven pagination in OData Version 4 is described by the specification 28
(preference odata.maxpagesize); further guidance for the plain REST APIs can be found in Server-Driven
Pagination: Page Size.

3.5.15.2 Filtering
If an API is required to filter data, meaning that it is expected to restrict the set of resources that is returned
in a collection using certain criteria (a selection operation in relational algebra), it MUST express this by
using the construct:

$filter=<expression>

Where <expression> is a combination of resource attributes, values (literals), and operators, as described
in the OData Version 4 specification. 29

Example:

GET /products?$filter=name eq 'KittyFood'

200 OK
{
"value": [{
"id": "123",
"name": "Kitty Food",
"description": "Meow!",
"releaseDate": "2017-03-24",
"price": 40
}]
}

3.5.15.3 Searching
If the use case requires a search data query pattern (search on API-specific resource attribute), APIs MUST
support search by using the following syntax:

$search=<string literal>

Example:

GET /products?$search="Kitty"

3.5.15.4 Ordering
If the use case requires ordering the results of a request, APIs MUST use the syntax:

$orderby=<comma-separated list of attribute names, attributed with asc or desc>

28
OData Version 4.01. Part 1: Protocol.
29
OData Version 4.01. Part 1: Protocol.

24
Example:

GET /products?$orderby=releaseDate asc,price desc

200 OK
{
"value": [{
"id": "123",
"name": "Kitty Food",
"description": "Meow!",
"releaseDate": "2017-03-24",
"price": 40
},{
"id": "456",
"name": "Doggy Food",
"description": "Woof!",
"releaseDate": "2017-04-02",
"price": 42
}]
}

3.5.15.5 Expand
If the API needs the expand capability (by which associated resources are included into the response
payload), it MUST support the following basic syntax:

$expand=<comma-separated list of resources to expand to>

The API MAY support more sophisticated forms of $expand (for example, embed $filter, $orderby,
and others), in which case they MUST comply with the OData syntax requirements. 30

Example:

GET /products/123?$expand=availability

200 OK
{
"id": "123",
"name": "Kitty Food",
"description": "Meow!",
"availability": {
"warehouseId": "890",
"availableAmount": 530
}
}

3.5.15.6 Projection
If an API needs to express projection, which means returning only the resource attributes that the client
explicitly requests, it MUST use the syntax:

$select=<comma-separated list of attribute names or asterisk>

The asterisk is equivalent to the absence of the $select option.

30
OData Version 4.01. Part 1: Protocol.

25
Example:

GET /products/123?$select=name,description

200 OK
{
"name": "Kitty Food",
"description": "Meow!"
}

3.5.15.7 Number of Elements


If an API returns the number of elements in a collection, it MUST support the following syntax as a path
segment:

$count

The call MUST return a plain text string (content type text/plain) containing the number of elements in
the collection as a decimal integer.

Example:

GET /products/$count

200 OK
Content-Type: text/plain
39

3.5.15.8 Inline Count


If an API returns the number of elements in a collection inline (as the part of the response that contains the
collection itself), it MUST support the following syntax as a query option:

$count=true

The API MUST include the attribute count in the payload that contains the number of elements in the
collection as a decimal integer. The attribute MUST reside on the same level as the root object for the
collection (for example, JSON array).

Example:

GET /products?$count=true

200 OK
{
"count": 2,
"value": [{
"id": "123",
"name": "Kitty Food",
"description": "Meow!",
"releaseDate": "2017-03-24",
"price": 40
},{
"id": "456",
"name": "Doggy Food",
"description": "Woof!",
"releaseDate": "2017-04-02",
"price": 42
}]
}

26
If the $count=true option is combined with pagination options (see the section Pagination), such as $top,
the response still MUST return the overall number of elements in a collection, not the page size.

Example:

GET /products?$count=true&$top=1&$skip=1

200 OK
{
"count": 2,
"value": [{
"id": "456",
"name": "Doggy Food",
"description": "Woof!",
"releaseDate": "2017-04-02",
"price": 42
}]
}
If the $count=true option is combined with data query options (see the sections Filtering and Searching),
such as $filter, the response still MUST return the number of elements in a collection after applying the
data query operation.

Example:

GET /products?$count=true&$filter=name eq 'KittyFood'

200 OK
{
"count": 1,
"value": [{
"id": "123",
"name": "Kitty Food",
"description": "Meow!",
"releaseDate": "2017-03-24",
"price": 40
}]
}

27
3.5.16 Data Conventions

3.5.16.1 Currency
For passing currencies, APIs MUST use standardized currency codes as described in ISO 4217. 31 The
guidance is explicitly valid for the currency code representation. The precision of the value (number of digits
after the decimal point) MAY vary depending on the requirements of the business.

Example:
{
"id": "123",
"productPrice": {
"value": 33.99,
"currency": "USD"
}
}

3.5.16.2 Country Codes


APIs MUST support the country codes as described in ISO 31661 alpha-2 (two-letter acronyms for country
codes). 32 API developers MAY decide to support additional conventions (for example, three-letter acronyms
as described in ISO 3166-1 alpha-3). 33 If an additional convention is used, it MUST be stated in the API
documentation.

Example:
{
"id": "123",
"targetMarket": "US"
}

3.5.16.3 Languages and Language Variations


To express a language (for example, to get the localized results of a resource query), APIs MUST use
two-letter acronyms as per ISO 639-1. 34 Language variations (for example, Austrian German) MUST be
expressed as described in IETF Best Current Practice BCP-47. 35 In the mentioned case, it will be de-AT.

Example:
{
"id": "123",
"descriptionLanguage": "de-AT"
}

31
ISO 4217: Currency Codes.
32
ISO 3166-1 alpha-2: Two-Letter Acronyms for Country Codes.
33
ISO 3166-1 alpha-3: Three-Letter Acronyms for Country Codes.
34
ISO 639-1: Language Codes.
35
IEFT BCP-47: Tags for Identifying Languages.

28
3.5.16.4 Units of Measure
APIs SHOULD use units of measure as described in The Unified Code for Units of Measure, 36 which is
based on ISO 80000 definitions.

Example:
{
"id": "123",
"productWeight": { // 2 kilogram
"value": 2,
"unit": "kg"
}
}

3.5.17 Content Handling

3.5.17.1 JSON as Content Type


APIs MUST support JSON as the preferred content type.

A valid exception of this rule is using other formats, usually based on industry standards (such as EDI)
required to enable integration with third-party systems.

If JSON is used, the content type MUST be manifested in the API response by using the HTTP header
Content-Type as required by IETF RFC 7231: 37

Content-Type: application/json

APIs MAY additionally support other content types as appropriate for the use case.

JSON payload for a single resource SHOULD pass the root attributes of the resource as root JSON
properties.

Example:
{
"id": "123",
"description": "Meow!"
}

The JSON payload for a collection of resources should wrap the JSON array, representing the collection
as a root object. This approach is to prevent JSON hijacking in older browsers 38 and to be able to inject
collection-related metadata on the collection level.

36
The Unified Code for Units of Measure.
37
RFC 7231: Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content.
38
JSON Hijacking.

29
Example:
{
"value": [{
"id": "123",
"description": "Meow!"
},{
"id": "456",
"description": "Woof!"
}]
}

The payload MAY contain additional metadata (for example, to express Inline Count or Hypermedia Links).

3.5.17.2 Content Negotiation


APIs MUST support content negotiation upon reaction to the Accept HTTP header communicated by the
consumer as required by IETF RFC 7231. 39

APIs MAY support other ways to negotiate content (for example, when communicated through a query
string).

3.5.18 Cache Handling


Handling client-side cache is an important performance aspect for REST APIs. Generally, cache handling
must comply with IETF RFC 7234. 40

HTTP caching mostly targets Internet browsers as clients. Still, in many cases, application-to-application
(A2A) integration may profit from this approach when using a client-side framework like Spring
RestTemplate, which implements HTTP cache.

API implementations SHOULD support cache handling where possible and appropriate for the use case.

APIs MUST support caching of GET results that deliver content in the response. They MAY support cache
handling resulting from other HTTP verbs.

APIs SHOULD provide the Cache-Control header in response to every supported request. They MUST
then support the following directives:
• max-age to communicate the cache lifetime
• private to indicate sensitive data
• no-cache and no-store to disable caching on the client side (because of different browser
expectations)

APIs MAY support the Expires header additionally to the Cache-Control max-age pragma to support
legacy browsers.

APIs SHOULD support content-based resource validation (entity tag and ETag HTTP header). They MAY
support time-based resource validation (Last-Modified HTTP header).

39
RFC 7231: Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content.
40
RFC 7234: Hypertext Transfer Protocol (HTTP/1.1): Caching.

30
3.6 Hypermedia/HATEOAS
We have observed in the past few years that some big players in the API-intensive industry (for example,
PayPal) 41 are moving toward HATEOAS as the architecture paradigm that implements level 3 of RMM. 42

While writing this document, we thoroughly analyzed the topic and arrived at the following conclusions:
• Implementation of full-scope HATEAOS requires significant conceptual and development-related
investment from providers and consumers alike. At the same time, it does not immediately benefit
consumers, because a completely HATEOAS-driven client is a rather theoretical concept today.
Taking this factor into account, some large API providers simply omit mentioning hypermedia/
HATEOAS in the REST API guidelines (for example, Microsoft) 43 and some even explicitly advise
against it (for example, Zalando). 44
• Significant effort must be spent on the domain model registry that allows describing the semantics
of the types and augmenting navigation links. Otherwise, the entire goal of HATEOAS is difficult to
achieve.
• Harmonization between OData and plain REST with respect to the use of hypermedia controls
requires additional effort because OData already has a hypermedia framework in place, but it is
OData specific and has limited capabilities when compared to modern frameworks (for example,
HAL 45 and JSON-LD. 46)

In light of these findings, we decided to postpone issuing concrete guidance on hypermedia handling and
target RMM 47 level 2 as the goal of the guidelines given in this document. However, this decision does not
prevent API implementation teams from investing in hypermedia controls. OData APIs then SHOULD rely
on the OData-provided facilities; for plain REST APIs, we give additional guidance in Hypermedia Links.

3.7 Authentication and Authorization


APIs MUST support authorization (permission for a caller to execute operations on resources). A
prerequisite for authorization is authentication (identification of the caller, based on credentials) – it is
impossible to authorize properly a caller whose identity is not known.

Caller Identity
Two different, orthogonal types of caller identity are relevant for API authorizations: A business user and a
calling application 48 owner.

Business user (see the Glossary) is an important notion since APIs MAY have a permission concept based
on the roles of business users (for example, managers can see the compensation statements of their entire
staff, whereas members of the staff can see only their own).

Business-user identities SHOULD be maintained (user management) and verified (authentication) by user
identity provider (IdP) solutions. These solutions usually support standard protocols (SAML 2.0 or OAuth 2.0)
for verifying and communicating the identity to the API. Our preferred solution is the SAP Cloud Platform
Identity Authentication service. 49

41
PayPal HATEOAS.
42
Richardson’s REST API Maturity Model.
43
Microsoft REST API Guidelines.
44
Zalando RESTful API Guidelines.
45
HAL.
46
JSON-LD.
47
Richardson’s REST API Maturity Model.
48
Calling application is sometimes called “client,” for example, in the OAuth 2 specification.
49
SAP Cloud Platform Identity Authentication: Product Overview.

31
Technical user is a special variant of business user. The main difference is that a technical user does
not stand for an individual. It is mostly used to integrate different technical processes with each other.
A technical user is often authenticated by certificates (for example, X.509), which are maintained directly
in the target system.

Client owner is also defined in the Glossary. For various reasons, it is necessary to check and monitor
the calling client. These tasks involve, among others, checking the authorization to consume a certain
functionality, metering, and billing as well as recording possible malicious actions of the client. Client owner
is an additional identity that is required to allocate the findings of this monitoring service to the organization
that owns the calling client (and not the business user). Therefore, APIs MUST know the identity (the owner)
of the calling client.

Different patterns are used to communicate the credentials of a client owner to the API. The accepted best
practice for identifying a calling application owner is the API key, which is an encoded form of credentials
(often OAuth client ID and client secret. 50) This key is normally processed by an API gateway. A dedicated
process for a consumer to acquire the API key is in place. It adds information about calling application
owners to the authentication infrastructure.

Caller Permissions
APIs MUST support authorization models based on caller permissions. Authorization rules (user roles and
client authorizations) for the API MUST be clearly stated in API Documentation.

APIs MUST check permissions for both the calling application owner (entitlement to use certain API
functionality) and the business users (check if the business role of the business user has permission to call
the API).

Semantics, granularity, and technical description of the caller permissions are under the responsibility of the
business area–specific infrastructure.

Use of JSON Web Token (JWT)


JWT (as described in the Glossary) may be implemented behind the API gateway. It offers multiple benefits.
It makes sense to use it as a transport format for user and calling application owner authentication and
authorization data, mainly for two reasons:
• No additional calls to the authorization server are required to decode a token, as is the case for an
OAuth-opaque token, which improves performance. This feature is particularly relevant in
microservice architectures, where hundreds of API calls may be triggered by one API call, and each
call in the chain must be authenticated and authorized.
• The ability to combine the authorizations for a business user and calling application owner in one
container minimizes the number of headers in the request.

The final decision to use JWT depends on the used infrastructure. Therefore, more specialized guidelines
SHOULD provide the final guidance.

50
The OAuth 2.0 Authorization Framework: Bearer Token Usage.

32
3.8 Plain REST API

3.8.1 Serialization of Collections


APIs SHOULD prefer the uniform name value for the root object in the collection to stay harmonized with
the OData Version 4 specification (see the section JSON as Content Type).

3.8.2 Partial Content


If an API implements partial updates (see Partial Updates and Use of PATCH), it MUST use the JSON
merge-patch data to describe the partial change set, as described in RFC 7386 51 (Basically, it is about using
the payload with change semantics and content type application/merge-patch+json.)

Example:

PATCH /products/123
If-Match:456
Content-Type: application/merge-patch+json
{
"productName": "Dog Food"
}

This example demonstrates two important points:


• The client uses the value of the previously retrieved ETag in the If-Match header to guarantee
the idempotence of the partial update.
• The client uses JSON merge patch to express change set semantics.

3.8.3 Error Response


In addition to the attributes referred to in Error Response: Common Structure, an error response MAY
include:
• status: Duplicate of the HTTP status code to propagate it along the call chain or to write it in the
support log without the need to explicitly add the HTTP status code every time
• moreInfo: Array of links containing more information about the error situation, for example, giving
hints to the end user
• internalMessage: Technical message, for example, for logging purposes

3.8.4 Server-Driven Pagination: Page Size


Generally, the implementation of server-driven pagination in a plain REST API MUST follow the rules
described in Pagination.

The API implementation MAY support configuration of the page size, as described in Preference Handling.
To do that, it SHOULD use the preference name maxpagesize. The value of the preference MUST be a
decimal number that denotes the page size (number of items to be returned).

The API implementation MAY disregard the maxpagesize preference. In that case, it MAY return the
Preference-Applied header with its own value, or not return the header at all.

The API SHOULD use the Link HTTP header (IETF RFC 5899) to communicate the links back to the client.
Another option is to use hypermedia links in the payload itself as described in Hypermedia Links.

51
RFC 7386: JSON Merge Patch.

33
Example:

GET /products/pages/2
Prefer: maxpagesize=2

200 OK
Link: </products/pages/1>; rel="previous", </products/pages/3>; rel="next"
Preference-Applied: maxpagesize=1
{
"value": [{
"id": "123",
"productName": "Kitty Food",
"productDescription": "Yummy!",
"productPrice": {
"value": 33.99,
"currency": "USD"
}
}]
}

3.8.5 Data Conventions


In this section, we describe conventions for data formats transmitted over the wire (data transfer objects
[DTO]). This material does not relate to the formats used for persisting data. The data is requested or
received as HTTP content (see the section Content Handling).

3.8.5.1 Date
For resource attributes requiring a date, APIs MUST use the format described in IETF RFC 3339, 52 which
represents a profile of ISO 8601. 53 APIs MAY provide handling of date in other nonstandard formats in
addition to the standard one.

Example:
{
"id": "123",
"productBestBeforeDate": "2017-02-14"
}

3.8.5.2 Time
For resource attributes requiring time data, APIs MUST use the format described in IETF RFC 3339, 54 which
represents a profile of ISO 8601. 55 APIs MAY provide handling of time in other nonstandard formats in
addition to the standard one.

APIs SHOULD use time zone information (following IETF RFC 3339, 56 positive or negative offset in hours
relative to UTC), otherwise the time value would be ambiguous.

52
RFC 3339: Date and Time on the Internet: Timestamps.
53
ISO 8601: Date and Time Formats.
54
RFC 3339: Date and Time on the Internet: Timestamps.
55
ISO 8601: Date and Time Formats.
56
RFC 3339: Date and Time on the Internet: Timestamps.

34
Example:
{
"id": "123",
"productBestBeforeTime": "20:54:21+00:00"
}

3.8.5.3 Timestamp (Datetime)


For resource attributes requiring date and time data, APIs MUST use the format described in IETF RFC
3339, 57 which represents a profile of ISO 8601. 58 APIs MAY provide handling of date and time in other
nonstandard formats in addition to the standard one.

APIs SHOULD use time zone information (following IETF RFC 3339, 59 positive or negative offset in hours
relative to UTC), otherwise the time value would be ambiguous.

Example:
{
"id": "123",
"productBestBefore": "2017-02-14T20:54:21+00:00"
}

3.8.6 Hypermedia Links


If the use case requires it, APIs MAY implement hypermedia controls. Given that case, APIs SHOULD stick
to the nomenclature of attributes to denote the information on the hypermedia links, as defined in IETF RFC
5988, which is now the most standardized source. 60

RFC 5988 defines the semantics of Web linking in a serialization-agnostic way, while setting the focus on
plain text serialization as content for the HTTP header Link (see the section Pagination). The same
semantics may apply to JSON or XML content. The set of attributes from the RFC is used, for instance, by
the Spring HATEOAS framework. 61

The minimal set of attributes is:


• href – The target URI
• rel – The meaning of the target URI
o self – The URI references the resource itself
o next – The URI references the next page (see Pagination)
o previous – The URI references the previous page (see Pagination)
o Arbitrary name – denotes the custom meaning of a relation.

The information on the hypermedia link SHOULD be enclosed into a JSON attribute link.

57
RFC 3339: Date and Time on the Internet: Timestamps.
58
ISO 8601: Date and Time Formats.
59
RFC 3339: Date and Time on the Internet: Timestamps.
60
RFC 5988: Web Linking.
61
Spring HATEOAS Project.

35
Example:
{
"link": {
"href": "/products",
"rel": "self"
},
"value": [{
"link": {
"href": "/products/123",
“rel”: “self”
},
"id": "123",
"description": "Meow!"
},{
"link": {
"href": "/products/456",
“rel”: “self”
},
"id": "456",
"description": "Woof!"
}]
}

3.9 OData Version 4 API


The OData Version 4 is a preferred way to expose OData APIs. The Version 4 specification standardizes
many things, while leaving some extension points explicitly to the implementation. For example, it allows
custom query parameters. The Version 4 specification also allows other things implicitly, for example, by not
defining a precise format for the OData service name. Apart from that, the Version 4 specification enables
developers to configure some parameters so that OData conventions get closer to the community best
practices.

This reference document brings the conventions used in OData APIs closer to the ones used for plain REST
APIs described in Plain REST API.

3.9.1 OData Conformance


OData APIs MUST support a minimum compliance level as described in the OData Version 4 specification.
They MAY support higher compliance levels if required.

3.9.2 URI Formatting


OData API implementations MUST use the forward-slash convention, controlled by the key-as-segment
setting, introduced in the OData Version 4.01 specification, 62 as soon as the implementation of 4.01 is
available in the technology used (for example, ABAP/Gateway, Olingo, and others).

3.9.3 Error Response


OData API implementations MAY extend the error response following the OData Version 4 specification.

62
OData Version 4.01. Part 1: Protocol.

36
3.9.4 Modeling of Actions
API developers SHOULD follow the guidance given in Modeling of Actions (avoid using verbs in the URI).
However, if they are developing OData APIs, they MAY decide to model actions using OData means. If they
decide to use the latter, they MUST consider the following rules:
• Function imports and action imports SHOULD NOT be used.
• APIs SHOULD rely on resource-bound actions and functions.

3.9.5 Naming Conventions: Functions and Actions


Functions and actions MUST follow the general camelCase naming convention.

3.9.6 Data Conventions


This section describes conventions for data formats transmitted over the wire. Note that this material does
not relate to the formats used for persisting data.

Data is requested or received as HTTP content (see Content Handling).

3.9.6.1 Date and Time


For resource attributes that require date and time, APIs SHOULD model the corresponding properties using
standard OData CSDL type 63 Edm.DateTimeOffset.

3.9.6.2 Bulk Modifications


The lightweight approach described in Bulk Modifications of Common Characteristics of REST APIs works
for plain REST and OData. Additionally, OData-based APIs can use OData batch requests as described in
the OData Version 4.01 specification.

63
OData Version 4.01. Part 3: Common Schema Definition Language (CSDL).

37
4 APPENDIX

4.1 Glossary
This (short) glossary contains definitions of some of the terms used in this document.
• API – As Wikipedia states, “in computer programming, an Application Programming Interface (API)
is a set of subroutine definitions, protocols, and tools for building application software.” 64 In the
guidance given in this paper, we are more precisely talking about HTTP REST APIs, that is,
APIs that are exposed through the HTTP protocol 65 and based on the REST architectural style
(see REST Principles).
• API Gateway – An architectural pattern that separates the external landscape (to which APIs are
exposed) from the landscape where the APIs are implemented.
An API gateway typically supports the following scenarios:
o Implementation of authentication policies, including single sign-on for an external application
that accesses multiple APIs, or a policy that settles token exchange
o Separation between public APIs (re-exposed to the external landscape) and internal APIs
(available only in the internal landscape)
o Reverse proxy scenario, in which an externally exposed API endpoint is connected to the
implementation endpoints.
Other scenarios may also be supported, depending on the concrete capabilities of the API gateway.
• Business User (also known as end user) – A human being who consumes the API indirectly
through a user interface.
• Consumer – A human being (normally a software developer) who creates an application (client) that
consumes the APIs.
• (Technical) Client (also referred to as “calling application”) – A technical actor (program) that
programmatically calls the APIs (“client” is used in the same sense as in the OAuth 2.0
specification. 66)
• Resource – According to the REST definition, it is an object that is being addressed. The resource
is encoded as part of the URI in a plain REST API (for example, in
http://api.sap.com/products/123, “products” is a resource).
• Entity – A resource having an ID. It is used as a synonym for a resource in the OData world.
• Data Field – A resource attribute (part of the request/response payload).
• lowerCamelCase – A format for a naming convention which uses a lowercase first letter and
uppercase letters for separating logical parts of the name.
• UpperCamelCase (also known as PascalCase) – A format for a naming convention that uses an
uppercase first letter and uppercase for separating logical parts of the name.
• camelCase – Either lowerCamelCase or UpperCamelCase
• lowercase – A format for a naming convention in which all letters are lowercase and there is no
separation between logical parts (one word).
• lowercase-dashed – A format for a naming convention in which all letters are lowercase and logical
parts are separated by a dash ('-’).
• lowercase_underscore – A format for a naming convention in which all letters are lowercase and
logical parts are separated with an underscore (‘_’).
• API namespace – A logical grouping of uniquely named elements for APIs (such as bounded
contexts in domain-driven design). A namespace may group API implementations (it is an
aggregation and not a containment in the sense of a UML class diagram). A namespace represents
a functional view of the API.

64
Wikipedia: Application Programming Interface (retrieved on September 26, 2017).
65
RFC 7231, RFC 7232, and RFC 7234.
66
The OAuth 2.0 Authorization Framework: Bearer Token Usage.

38
• JSON Web Token (JWT) – A data format for carrying payload in a tamper-proof form that is
standardized in RFC 7519: JSON Web Token, 67 and typically used for identity and authorization
data. It has the following benefits:
o Integrity guarantee
 JWT content is protected against tampering with a digital signature of the issuer.
The API implementation must have a trust relationship with the issuer and know its
public key to be able to verify the content. The issuer signature may be verified
offline if the API implementation imported the public key of the issuer before the
runtime phase (for example, as part of the configuration).
o Self-containment
 JWT contains the entire information inside its body and does not need to make
an additional call to get it (as opposed to opaque OAuth tokens, where the API
implementation needs an additional call to token or user-information endpoints
of the authorization server). This feature leads to performance and reliability
improvements for the API implementation because it reduces the number of remote
dependencies.
• Tombstoning – The act of setting a flag for logical deletion of a resource, instead of removing it
physically. For example, deleting a database record from the persistence layer is a physical removal.
To implement tombstoning, an additional attribute (such as deleted) must be modeled for a
resource. This makes sense not only from the API harmonization perspective but also as a useful
pattern for handling distributed data, which is especially relevant in the microservices world.

4.2 REST Principles


Representational state transfer (REST) is the design philosophy 68 upon which the World Wide Web is based.
HTTP is an example of a protocol that fully complies with the six architectural design constraints of REST
(see below).

The Six Design Constraints of REST:


1. Implement the Client-Server Model
This architectural style allows independent development of two communicating software parties: client
and server. It further assumes that the client will take no part in long-term data storage and that the
server will take no part in the presentation of the data it supplies.

This principle is known as the separation of concerns.

2. Use Layered Communication


When a client communicates with a server, usually it should not be able to distinguish whether it has
communicated directly with the actual endpoint server or through some intermediate server used for
system scalability or security reasons.

3. Use Stateless Communication


A stateless interface relieves the server from the need to keep track of the progress each of its clients
has made during a sequence of communication events. The client bears the burden of keeping session
(or state) information, and the client is therefore required to supply all the necessary information to the
server during each request.

It is not forbidden to have the server hold client state information. The only thing to consider is that the
client must know the state information and be able to address this information.

67
RFC 7519: JSON Web Token.
68
Roy T. Fielding, Architectural Styles and the Design of Network-Based Software Architectures.

39
4. Implement a Uniform Interface
This constraint implies that:
• The server must provide the client with a representation of its resources
• The client must be able to perform at least the following basic operations on server-side resources:
o Query
o Create
o Read
o Update
o Delete
• All responses sent to the client must be self-describing. That means that the client cannot be
expected to know a priori the communication schema that the server is using.
• The client may manipulate the server-side resources by using hypermedia that the server supplies.

5. Server Responses Must Be Cacheable


To improve performance and scalability, any information supplied by a server must carry with it an
indicator describing whether the client is permitted to cache the data for future use.

Any system involved in layered communication is permitted to act as a cache.

6. Code-On-Demand
Upon request of the client, the server should be able to supply additional executable code to extend the
client’s capabilities.

This principle is used every time a browser requests a JavaScript file from a Web server.

5 REFERENCES
• OData Version 4.01. Part 1: Protocol:
http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.pdf.
• Apigee Web API Design: https://pages.apigee.com/web-api-design-register.html?int_source=hpt
-main&int_medium=website&int_campaign=ebook&int_content=web-api-design-missing-link.
• Zalando RESTful API Guidelines: https://github.com/zalando/restful-api-guidelines.
• CIO Guide: SAP Vision for Integrating SAP Applications in Cloud and Hybrid Environments:
www.sap.com/documents/2017/05/eebd96bd-b97c-0010-82c7-eda71af511fa.html.
• 4.0. Part 1: Protocol Plus Errata 03. Model Versioning:
http://docs.oasis-open.org/odata/odata/v4.0/errata03/os/complete/part1-protocol/odata-v4.0
-errata03-os-part1-protocol-complete.html#_Toc453752210.
• RFC 7231: Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content:
www.ietf.org/rfc/rfc7231.txt.
• RFC 7386: JSON Merge Patch: www.ietf.org/rfc/rfc7386.txt.
• Roy T. Fielding. Architectural Styles and the Design of Network Based Software Architectures:
www.ics.uci.edu/~fielding/pubs/dissertation/top.htm.
• RFC 7519: JSON Web Token: www.ietf.org/rfc/rfc7519.txt.
• RFC 3986: Uniform Resource Identifier (URI): Generic Syntax: www.ietf.org/rfc/rfc3986.txt.
• Deprecating the "X-" Prefix and Similar Constructs in Application Protocols:
https://tools.ietf.org/rfc/rfc6648.txt.
• The OAuth 2.0 Authorization Framework: Bearer Token Usage: https://tools.ietf.org/rfc/rfc6750.txt.
• The Unified Code for Units of Measure: http://unitsofmeasure.org/ucum.html.
• ISO 8601: Date and Time Formats: https://en.wikipedia.org/wiki/ISO_8601.
• RFC 2119: Key words for use in RFCs to Indicate Requirement Levels: www.ietf.org/rfc/rfc2119.txt.
• Idempotence: https://en.wikipedia.org/wiki/Idempotence.
• ISO 4217: Currency Codes: www.iso.org/iso/home/standards/currency_codes.htm.
• RFC 7232: Hypertext Transfer Protocol (HTTP/1.1): Conditional Requests:
www.ietf.org/rfc/rfc7232.txt.
• RFC 7234: Hypertext Transfer Protocol (HTTP/1.1): Caching: www.ietf.org/rfc/rfc7234.txt.
• ISO/IEC JTC 1 Approves OASIS OData Standard for Open Data Exchange:
www.oasis-open.org/news/pr/iso-iec-jtc-1-approves-oasis-odata-standard-for-open-data-exchange.

40
• RFC 5988: Web Linking: https://tools.ietf.org/rfc/rfc5988.txt.
• OData Version 4.01. Part 2: URL Conventions:
http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.pdf.
• ISO 3166-1 alpha-2: Two-letter acronyms for country codes:
https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2.
• ISO 3166-1 alpha-3: Three-letter acronyms for country codes:
https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3.
• ISO 639-1: Language codes: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes.
• IEFT BCP-47: Tags for Identifying Languages: https://tools.ietf.org/rfc/bcp/bcp47.txt.
• OpenAPI Initiative: www.openapis.org.
• RAML (RESTful API Modeling Language): http://raml.org.
• OData Version 4.01. Part 3: Common Schema Definition Language (CSDL):
http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part3-csdl.pdf.
• RFC 5789: PATCH Method for HTTP: https://tools.ietf.org/rfc/rfc5789.txt.
• JSON Hijacking: http://haacked.com/archive/2009/06/25/json-hijacking.aspx.
• CQRS: https://martinfowler.com/bliki/CQRS.html.
• Richardson’s REST API Maturity Model:
https://martinfowler.com/articles/richardsonMaturityModel.html.
• Netflix Zuul: https://github.com/Netflix/zuul.
• SAP Cloud Platform Identity Authentication: Product Overview:
www.sap.com/documents/2015/07/e4803e8e-5b7c-0010-82c7-eda71af511fa.html.
• RFC 3339: Date and Time on the Internet: Timestamps: www.ietf.org/rfc/rfc3339.txt.
• Wikipedia: Application Programming Interface:
https://en.wikipedia.org/wiki/Application_programming_interface.
• Red Hat Teiid: http://teiid.jboss.org.
• HAL: http://stateless.co/hal_specification.html.
• JSON-LD: https://json-ld.org.
• Microsoft REST API Guidelines:
https://github.com/Microsoft/api-guidelines/blob/vNext/Guidelines.md.
• Spring HATEOAS Project: http://projects.spring.io/spring-hateoas.
• PayPal HATEOAS Links: https://developer.paypal.com/docs/api/hateoas-links.
• RFC 7240: Prefer Header for HTTP: https://tools.ietf.org/rfc/rfc7240.txt.

41
www.sap.com/contactsap

Studio SAP | 54014enUS (18/11)

© 2018 SAP SE or an SAP affiliate company. All rights reserved.


No part of this publication may be reproduced or transmitted in any form or for any purpose without the express permission of SAP SE or an SAP affiliate company.

The information contained herein may be changed without prior notice. Some software products marketed by SAP SE and its distributors contain proprietary software components of other software vendors.
National product specifications may vary.

These materials are provided by SAP SE or an SAP affiliate company for informational purposes only, without representation or warranty of any kind, and SAP or its affiliated companies shall not be liable
for errors or omissions with respect to the materials. The only warranties for SAP or SAP affiliate company products and services are those that are set forth in the express warranty statements
accompanying such products and services, if any. Nothing herein should be construed as constituting an additional warranty.

In particular, SAP SE or its affiliated companies have no obligation to pursue any course of business outlined in this document or any related presentation, or to develop or release any functionality
mentioned therein. This document, or any related presentation, and SAP SE’s or its affiliated companies’ strategy and possible future developments, products, and/or platform directions and functionality are
all subject to change and may be changed by SAP SE or its affiliated companies at any time for any reason without notice. The information in this document is not a commitment, promise, or legal obligation
to deliver any material, code, or functionality. All forward-looking statements are subject to various risks and uncertainties that could cause actual results to differ materially from expectations. Readers are
cautioned not to place undue reliance on these forward-looking statements, and they should not be relied upon in making purchasing decisions.

SAP and other SAP products and services mentioned herein as well as their respective logos are trademarks or registered trademarks of SAP SE (or an SAP affiliate company) in Germany and other
countries. All other product and service names mentioned are the trademarks of their respective companies. See www.sap.com/copyright for additional trademark information and notices.

Вам также может понравиться