• REST API Design Guide

    This design guide or style guide contains best practices suitable for most REST APIs.

  • Overview

    Our goal is consistency, maintainability, and best practices across applications. APIOps aim to balance a truly RESTful API interface with a positive developer experience (DX).

     

    In a nutshell:

    • Keep APIs’ functionalities as simple as possible. The endpoints do only one thing, but they do it well.

    • Avoid overlapping functionalities between different APIs.

    • In case of an error include the API response verbose description. Include also a description of the erroneous parameter value, if it is feasible.

    • Implement in each API (or bundle of APIs) ability to generate its own machine-readable document about its functionality.

    • API must have support for the OPTIONS endpoint, which is needed for example in a preflight request in SwaggerUI

     

    Minimum developer experience

    • Each API must have a descriptive title

    • The description of API has to be sufficient.

    • Each API must have documentation, either an OpenAPI file or other standard specification that is supported by the API management solution used.

    • Each API should have a getting started section to provide a low learning curve and fast 1st positive experience for the consumer

     

    The format of API specification

    Use the most recent OpenAPI version supported by the API management platform to describe your API, unless you are developing your API using GraphQL, AsyncAPI, gRPC or some other standard. OpenAPI Specification (Wikipedia) originally known as the Swagger Specification, is a specification for machine-readable interface files for describing, producing, consuming, and visualizing RESTful Web services.

    Information about supported versions

    Use examples-attribute with JSON schemas (validated) to provide automatically generated documentation and smart mock data to help use the API.

    Naming standards

    • All URI parts including resource names are written in small letters.

    • Use only camelCase in all attribute (field) names.

    • Do not use special characters in URI or in attribute names.

    • Use English only in OpenAPI specification.

    • Use common legally used or industry-specific (not company-specific) words about resources and attributes. Refer to ISO standards as a primary source, then use WTO, EU or other trade area-specific vocabularies, http://schema.org/ or industry-specific vocabularies for naming. As a last resort, refer to company-specific vocabularies before inventing your own.

    • Avoid using generic names like “type”, “status” etc. without specifying what type, what status or better yet, avoiding those words altogether.

    • Use ISO standard or other generally used (see above) values for attribute values such as languages, country names etc. Avoid using magic numbers as values or provide also the human language alternative, preferably according to the Accept-Language header in the request.​​

    Localization

    The Accept-header should be used to support localized strings and possible localized logic. All timestamps should be in ISO format which contains timezone information. All dates and clock times with no specific timezone information associated should be informed in UTC +0.

     

    All money values should be informed in specific currency and currency information should be contained in a custom x-companyname-currency header (in both request and response). Currency values should default to some provider or consumer based base currency if no specific currency has been requested.

    Privacy and security

    Private or confidential data should not be passed in URI, Query or header parameters as they are logged and cached. Security constraints are defined in API Product level, but privacy and security should be considered when splitting requirements to APIS and endpoints, as security schemes are easier to implement on API level than endpoint level or by reflecting authorization in the allowed operations or response payloads.

    Versioning

    Private or confidential data should not be passed in URI, Query or header parameters as they are logged and cached. Security constraints are defined in API Product l

    Each API consumer needs to know which version of the API they are using and to be able to subscribe and use the version they need. There are mixed opinions about the way the versioning is indicated: whether API version should be included in the URL or in the header.

     

    The common convention is to have the version in the URL of APIs. The reason is to ensure that the browser is able to explore the resources across versions.

     

    In some API management systems, the version does not need to be in the URI nor in the header because each API product has its own version and each API consuming client application is only able to use 1 version of the API at a time. If the same client used multiple versions of the same API at a time, they would need different subscriptions. This versioning strategy works with all clients and is suited for caching and HATEOAS.

     

    Versioning in - Azure API Management

     

    When the version number is used it should always be in the URI since not all clients (for example marketing tools) can set headers and using version number as a query parameter might cause slowness as query parameters are not cached. Also, most API management platforms require that the URIs are unique if multiple versions of the same API are deployed at the same time.

     

    The URI should include /vN with the major version (N) as a prefix. Having the letter v in front of the number is important to separate the version number from a resource identifier.

     

    When APIs are upgraded with a breaking change, it may lead to breaking existing products or services using upgraded APIs.

     

    Privacy and security should be considered when splitting requirements to APIs and endpoints, as security schemes are easier to implement on API level than endpoint level or by reflecting authorization in the allowed operations or response payloads.

     

    Examples of breaking changes

    • renaming fields or resource paths or endpoints

    • changing field type (e.g. from string to a list of strings)

    • changing the structure of payload (removing/renaming/retyping fields)

    • altering HTTP verbs

    • changing response HTTP codes

     

    In case of breaking changes making a new version of the updated API is mandatory.

     

    URI Template

    /v{version}/

     

    Example

    https://domain.com/v1/apis

     

    If there is any major breaking update, the new set of APIs is named as v (version number as integer).

    Namespaces

    In any URI, the first noun (which may be singular or plural, depending on the situation) should be considered a “namespace”. Namespaces should reflect the customer’s perspective on how the product works, not necessarily hierarchy in the company.

     

    Namespace separates different logical APIs from each other, which is useful if you have lots of APIs with different purposes and they may end up using same resource or operation names.

     

    Namespaces in different API management solutions:

    • IBM API Connect uses organizations, catalogs and spaces to organize publishing of APIs. These are useful when there are multiple teams in charge of different APIs. Organization and catalog form the namespace of the API and those are always added automatically before version number or anything defined in the OpenAPI document basepath value or path-variable of each operation.

    • Azure API management requires you to define a URI template when adding a new operation or by setting it for all operations in the OpenAPI document basepath value (required).

     

    URI Template

    /{namespace}/{version}

     

    Example

    /hardware/v1/

    Resources and HTTP methods

    Try to use only one resource level, absolutely avoid using more than two levels to keep the URLs short to allow room for using variables.

     

    URI Template

    /{namespace}/{version}/{resource}/{resource-id}/{sub-resource}/{sub-resource-id}

    Endpoints

    Resource endpoints should follow at least View and CRUD (Create, Read, Update, Delete) operations. These should be handled by using the same URI but using different HTTP verbs (POST/GET/PUT/PATCH/DELETE, more details about each verb in ( https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html ) ).

     

    Use nouns in the plural as resource names e.g. /products.

     

    All used methods and their parameters have to be described in generated documentation endpoint by endpoint.

     

    GET (read)

    The GET method requests data from the resource and should not produce any side effect. The possible parameters are sent as part of the URL or as query parameters.
    • E.g GET /users

      • return a list of all users

    • E.g GET /users?limit=10&skip=30

      • returns a list containing 10 users after skipping 30 users

    POST (create, do partial updates)

    The POST method requests the server to create a resource in the database. The payload is sent in the request message body.

     

    POST is a non-idempotent operation which means that multiple requests targeted to the same endpoint with the same payload will have a different outcome.

    • E.g POST /organizations/:id/managers

      • The first attempt creates a new Manager of Organization identified with :id. (If it did not exist already).

    • E.g POST /organizations/:id/managers

      • The second attempt with the same payload fails (because manager already existed) and an error response (4xx, manager already exists) is returned.

    PUT (create and update complete resources)

    The PUT method requests the server to update a resource, but it can also create it. The payload is sent in the request message body.

    Normally it is not possible to create a resource with PUT method, because resources are referenced with :id. In case resource with :id does not exist, a response with 404 Resource not found is sent unless you give a resource name (like file name) in the PUT request. Use POST to create a new resource and POST or PATCH to do partial updates.

     

    PUT is an idempotent operation which means multiple requests with the same payload targeted to the same endpoint will have the same effect and outcome, either successful update or resource not found.

    • E.g. PUT /organizations/:id

      • The first attempt will request the server to update the resource (identified with :id) in Organizations collection.

        • A successful response with 2xx is returned, if a resource is found.

        • In case the resource is not found, an error response with 4xx is returned.

    • E.g. PUT /organizations/:id

      • Second attempt (with the same payload) will request the server to update the resource (identified with :id) in Organizations collection.

        • A successful response to 2xx is returned, if the resource is found.

        • In case the resource is not found, an error response with 4xx is returned.

    DELETE (delete)

    DELETE method requests that the resource, or its instance, should be removed from the database. The operation is irreversible.
    • E.g DELETE /apis/:id

      • Will request the server to delete the API identified with :id from Apis collection.

        • In a successful case a response with 204 is returned (no payload included).

        • In an unsuccessful case, a response with 4xx is returned.

    Error handling

    Just like an HTML error page shows a useful error message to a visitor, an API should provide a useful error message in a known consumable format. The representation of an error should be no different from the representation of any resource, just with its own set of fields.

     

    The API should always return sensible HTTP status codes. API errors typically break down into 2 types: 400 series status codes for client issues & 500 series status codes for server issues. At a minimum, the API should standardize that all 400 series errors come with consumable JSON error representation. If possible (i.e. if load balancers & reverse proxies can create custom error bodies), this should extend to 500 series status codes.

    A JSON error body should provide a few things for the developer - a useful error message, a unique error code (that can be looked up for more details in the docs) and possibly a detailed description.

     

    JSON output representation for something like this would look like:

    { "code" : 1234, "title" : "Organization is not found", "detail" : "Organization with specified ID is not found" }

     

    Validation errors for PUT, PATCH and POST requests will need a field breakdown. This is best modeled by using a fixed top-level error code for validation failures and providing the detailed errors in an additional errors field, like so:

     

    { "code" : 1024, "title" : "Validation Failed", "detail" : [ { "code" : 5432, "title" : "first_name", "detail" : "First name cannot have fancy characters" }, { "code" : 5622, "title" : "password", "detail" : "Password cannot be blank"} ] }

    Filtering

    Paging

    Pages of results should be referred to consistently by the query parameters page and pageSize, where pageSize refers to the number of results per request, and page refers to the requested page.

    Fields like totalItems and totalPages help provide context to paged results. Use the same fields with all resources to be consistent.

     

    Hypermedia links

    Hypermedia links are high value in navigating paged resource collections, as page/pageSize query parameters can be maintained while navigating pages of results.

    Links should be provided with reels of next, previous, first, last wherever appropriate.

     

    Time selection

    startTime or {propertyName}After, endTime or {propertyName}Before query parameters should be provided if time selection is needed. All time values in the parameters and in the data have to be in the ISO format including timezone.

     

    Sorting

    sortBy and sortOrder can be provided to allow for collection results to be sorted. sortBy should be a field in the individual resources, and sortOrder should be asc or desc.

     

    URI Template

    GET /{namespace}/{version}/{resource}

     

    Example Request

    GET /hardware/v1/products

    Resource collection

    A list of all of the given resources, including any related metadata. The array of resources should be in the items field to help handle other fields than the actual resources being returned in the response.

     

    Plan for security and provide a list of only those resources the requesting party is allowed to see.

    If the resource response is really big, provide a possibility to include only those fields the client requires. Also add only those fields in the response, that you consider absolutely necessary. It’s easier to add more later when needed instead of removing that would be a breaking change.

    Single resource

    A single resource, typically derived from the parent collection of resources (often more detailed than the collection resource items).

     

    All identifiers for sensitive data should be non-sequential, and preferably non-numeric. In scenarios where this data might be used as a subordinate to other data, immutable string identifiers should be utilized for easier readability and debugging (i.e. “nameOfValue” vs 1421321).

     

    URI Template

    GET /{namespace}/{version}/{resource}/{resource-id}

     

    Example Request

    GET /hardware/v1/products/6438313255314

×
Privacy policy
SECTION 1 - WHAT DO WE DO WITH YOUR INFORMATION?
When you browse our website, we automatically receive your computer’s internet protocol (IP) address in order to provide us with information that helps us learn about your browser and operating system. 

With your permission, we may send you emails about our site, new services, events and other updates.
SECTION 2 - CONSENT
How do you get my consent? 
When you provide us with personal information to complete a transaction, verify your credit card, place an order, arrange for a delivery or return a purchase, we imply that you consent to our collecting it and using it for that specific reason only. 
If we ask for your personal information for a secondary reason, like marketing, we will either ask you directly for your expressed consent, or provide you with an opportunity to say no.
How do I withdraw my consent? 
If after you opt-in, you change your mind, you may withdraw your consent for us to contact you, for the continued collection, use or disclosure of your information, at anytime, by contacting us at [email protected]
SECTION 3 - DISCLOSURE
We may disclose your personal information if we are required by law to do so or if you violate our Terms of Service.
SECTION 4 – SERVICE PROVIDERS
Our website is hosted on Strikingly Inc., a Delaware, US based company. They provide us with the website platform including the subscription and web form data you submit to us.
Your data is stored through Strikingly’s data storage, databases and the general Strikingly application. They store your data on a secure server behind a firewall. More information can be optained from their Privacy policy https://support.strikingly.com/hc/en-us/articles/214364818 
We use Google’s application suite for email, documents and calendar and Campaign monitor for sending email campaigns. We only allow dedicated personnel to get access to these systems. Emails sent to our general email [email protected] are also stored in PlanMill, our ERP system, for customer service and archiving.
SECTION 5 - THIRD-PARTY SERVICES
In general, the third-party providers used by us will only collect, use and disclose your information to the extent necessary to allow them to perform the services they provide to us. 
However, certain third-party service providers, such as payment gateways and other payment transaction processors, have their own privacy policies in respect to the information we are required to provide to them for your purchase-related transactions. 
For these providers, we recommend that you read their privacy policies so you can understand the manner in which your personal information will be handled by these providers. 
In particular, remember that certain providers may be located in or have facilities that are located a different jurisdiction than either you or us. So if you elect to proceed with a transaction that involves the services of a third-party service provider, then your information may become subject to the laws of the jurisdiction(s) in which that service provider or its facilities are located. 

Links 

When you click on links on our store, they may direct you away from our site. We are not responsible for the privacy practices of other sites and encourage you to read their privacy statements.
SECTION 6 - SECURITY
To protect your personal information, we take reasonable precautions and follow industry best practices to make sure it is not inappropriately lost, misused, accessed, disclosed, altered or destroyed. 

SECTION 7 - COOKIES
You are asked separately for accepting cookies on the site.
SECTION 8 - AGE OF CONSENT
By using this site, you represent that you are at least the age of majority in your state or province of residence, or that you are the age of majority in your state or province of residence and you have given us your consent to allow any of your minor dependents to use this site.
SECTION 9 - CHANGES TO THIS PRIVACY POLICY
We reserve the right to modify this privacy policy at any time, so please review it frequently. Changes and clarifications will take effect immediately upon their posting on the website. If we make material changes to this policy, we will notify you here that it has been updated, so that you are aware of what information we collect, how we use it, and under what circumstances, if any, we use and/or disclose it. 
If our store is acquired or merged with another company, your information may be transferred to the new owners so that we may continue to sell products to you.
QUESTIONS AND CONTACT INFORMATION
If you would like to: access, correct, amend or delete any personal information we have about you, register a complaint, or simply want more information contact our Privacy Compliance Officer at [email protected]
-----