Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.


Expand
titleContents

Table of Contents

...

Section

URLs

Panel
borderColor#ffab00
bgColorwhite
titleColorwhite
borderWidth1
titleBGColor#ffab00
borderStylesolid

There are four parts to the URI of a REST service: the host, context, API version, and the desired resource.

{host}/{context}/{api-version}/{resource}

Each part may be comprised of more granular elements and will be described in their respective sections.

  • Each of the URL elements listed above MUST use snake_case

Host

The host will be in the following format:

Info
iconfalse

https://api[-qa].ucsd.edu

The –qa indicator represents a non-production deployment.  When no indicator is present then the stage is production.

Context

The API context is used to determine which API an incoming request is attempting to access. The API Context MUST be unique and snake_case. When viewing APIs in the store and publisher the API Name is used. The API Name should be unique and human friendly. It is our recommendation that the context be a URL-friendly version of your API Name. Often we suggest removing special characters and setting it to lower case. Some long API Names can also be abbreviated. It should be clear which API Name and API Context is referencing, so when a developer is reading code and finds the URL that is invoked, they can find that API in the store.

API Version

The API version is used to determine which iteration of an API an incoming request is attempting to access. It is used in conjunction with the API context.  API version indicates breaking change in the interface (request or response) or functionality that prevents existing consumers from consuming this API successfully.

  • Version only when needed. A new version of API also requires multiple runtime binaries and many times, backend database changes.

  • Work with clients to see if they can be upgraded without increasing the version

  • Support at the most 2 versions

  • Version if the response has breaking change as well.

How to version:

There are different ways to version an API. Various techniques are based on indicating version number in:

  • Headers

  • URLs

  • Headers & URLs both, using a Hybrid approach. Use the latest version by default unless a specific version is provided in the header or in URL

It is recommended to use URL based versioning as it specifically indicates what version is being used by the consumer. A version number should be appended to the host to allow for versioning of the resources.

Version Format:

It is recommended to format the version like: v1, v2, etc.  Optionally you can omit the “v” or include a minor version like: v1.2, 1.2, etc.  However, minor versions shouldn’t cause breaking changes so minor versioning in the url is discouraged.

Resource

The resource URL element specifies an entity in the current context.  A resource by itself represents a collection of entities. You can refer to a single entity by specifying a unique identifier.

General Conventions

  • Resources MUST use snake_case

  • Resources SHOULD be nouns and not verbs

  • Resources SHOULD be plural

  • Concrete resources are better than abstract

    • e.g. /dogs better than /animal

Single Entity Resource

A specific resource entity can be targeted by adding the identifier to the URL.  For example:

Info
iconfalse

https://api.ucsd.edu/context/v1/articles/1234

The identifier MUST uniquely identify a specific resource entity.

Compound Resource Identifiers

If more than one identifier is needed to identify a resource, they MUST be concatenated with commas:

Info
iconfalse

/classes/CSE,100,SP18 instead of /classes/CSE/100/SP18

Qualified Resource Identifiers

When there are multiple types of resource identifiers, it is a good practice to qualify the identifier.

Info
iconfalse

/employees/employee_id=123 or /employees/racfid=AAAZZZ

Sub Resources

Sub resources are used to interact with entities that can be uniquely identified by a higher level resource and have a direct relationship to the higher level resource.  For example:

Info
iconfalse

https://api.ucsd.edu/context/v1/articles/1234/comments

This sub resource could be used to create a comment and associate it with an article.

Sub resources can also be identified with the same rules as top-level resources. For example:

Info
iconfalse

https://api.ucsd.edu/context/v1/articles/1234/comments/1

Query Parameters

Query parameters can be used to specify the desired format of a response, for example: filtering, paging, sorting, etc.  Query parameters MUST be camelCase.


...

Section

Resource representation

Panel
borderColor#ffab00
bgColorwhite
titleColorwhite
borderWidth1
titleBGColor#ffab00
borderStylesolid

It is recommended to use the HAL specification to represent responses in json or xml.  HAL provides a set of conventions to express HATEOAS linking consistently.

Content negotiation

Content negotiation allows an API to provide multiple representations of a resource with the same URL.  Two headers primarily used to enable this are Accept and Content-Type.

  • Accept - used by the client to specify which representation type is preferred in the response when there are multiple options available.
  • Content-Type - used by both the client and API to specify the representation of the request / response bodies.

Single resource

Single entity resources are targeted with urls that end in a unique identifier.  For example:

Info
iconfalse

https://api.ucsd.edu/context/v1/articles/1234

Resources are composed of name / value pairs where the values can be basic data types, objects, or arrays.

Basic data types

Strings:

Code Block
{
	"title" : "REST API Guidelines"
}

Numbers:

Code Block
{
	"integer" : 1234,
	"negativeInteger" : -1234,
	"decimal" : 1234.01,
	"scientificNotation" : 1.2E+3
}

Boolean:

Code Block
{
	"flag" : true
}

Date/Time:

Date and time formats MUST follow the ISO8601 format specified in RFC3339 Section 5.6.  Examples:

Code Block
{
	"date" : "2019-03-25",
	"timeLocal" : "13:30:57",
	"timeUTC" : "13:30:57Z",
	"timePSTOffset" : "13:30:57-08:00",
	"dateTimeUTC" : "2019-03-25T13:30:57Z",
	"dateTimePSTOffset" : "2019-03-25T13:30:57-08:00" 
}

Objects

Resources can have attributes values represented as other objects.  If object is a sub-resource, meaning that can be specifically accessed via a URL, then it SHOULD be listed under the _embedded attribute following the HAL specification.  A self link should be provided as well for easy access to the sub-resource.

Arrays

Attributes values can also be arrays.  Arrays are collections of homogeneous values.  The values can be basic data types or objects.

Links are used to provide possible actions that can be made on a resource given its current state.  More information can be found later in this document in the Links section.

Collections of resources

Resource collections are targeted with URLs that don’t specify a single resource with an identifier.  For example:

Info
iconfalse

https://api.ucsd.edu/context/v1/articles

Even if a filtering option is provided that results in a single resource, an array of resources should still be expected by the user agent.  Collections of resources SHOULD be listed under the _embedded attribute, following the HAL specification, indicating that individual resources can be directly accessed via a self URL.

If the resources in the collection are large, then a reduced representation can be used that only contains the minimum attributes necessary for identification.  The reduced resources MUST be accompanied by a self link to retrieve the full resource by itself.

Paging

It is recommended to provide paging options on large collections of resources to let the user agent limit the number of resources retrieved at one time.  Additionally, links SHOULD be provided to facilitate the traversal of the paged collection.

More information can be found later in the document under the Pagination section.

Sorting

It is recommended to provide sorting options on large collections of resources.  Even if sorting options are not provided, it is recommended to specifically order the collection by default for consistent responses.

More information can be found later in the document under the Sorting section.

Filtering

It is recommended to provided filtering options on large collections of resources.

More information can be found later in the document under the Filtering section.


...

Section

HTTP

Panel
borderColor#ffab00
bgColorwhite
titleColorwhite
borderWidth1
titleBGColor#ffab00
borderStylesolid

Request

The API MUST use proper HTTP methods, and operation idempotency* MUST be respected. Below is a list of methods that APIs SHOULD support. Not all resources will support all methods, but all resources using the methods below MUST conform to their usage.

MethodDescriptionIs Idempotent*

Is
Safe**

Example

Response

GETRetrieve a collection of objectsTrueTrue
GET /dogs
  • 200 (OK), with list
    • list can be empty
  • 404 (NOT FOUND)
    • when resource doesn't exist
GETRetrieve a specific objectTrueTrue
GET /dogs/10
  • 200 (OK), with data
  • 404 (NOT FOUND)
POSTCreate a new objectFalseFalse
POST /dogs
  • 201 (CREATED)
    • upon successful creation
    • with Location header with link to newly created resource
    • optionally, with HATEOAS link
PUTReplace a specific objectTrueFalse
PUT /dogs/10
  • 200 (OK), with data
  • 204 (NO CONTENT)
  • 404 (NOT FOUND)
PATCHPartially update a specific objectFalseFalse
PATCH /dogs/10
  • 200 (OK), with data
  • 204 (NO CONTENT)
  • 404 (NOT FOUND)
DELETEDelete a specific objectTrueFalse
DELETE /dogs/10
  • 204 (NO CONTENT)
  • 404 (NOT FOUND)
OPTIONSGet information about a request, notably which other methods are supportedTrueTrue
OPTIONS /dogs
  • 200 (OK), with Allow header
HEADIdentical to GET, except MUST NOT return a body
Response headers SHOULD be the same as equivalent GET request
TrueTrueHEAD /dogs/10
  • 200 (OK)
  • 404 (NOT FOUND)

*Idempotence is the idea that a client can make the same call repeatedly while producing the same result. In other words, making multiple identical requests has the same effect as making a single request.

**An operation is considered safe if the operation does not significantly alter the state of the application

Response Codes

HTTP status codes are used to categorize a response and MUST be implemented.  A description of the most commonly occurring status codes is listed below and a full list of status codes and their definitions can be found here.

Success Scenario

  • 200 Default success response code when response data is required.
  • 201 Response to a POST that results in a creation of a resource. Should be combined with a Location header pointing to the location of the new resource.
  • 202 Operation deleted has not been committed yet.
  • 204 Request successful but no content.
  • 304 Not Modified - Used in response to conditional GET calls to reduce bandwidth usage. If used, must set the Date, Content-Location, ETag headers to what they would have been on a regular GET call. There must be no response body.

Client Error Scenario

  • 400  The request is syntactically malformed.  Can apply to both request body and query parameters.
  • 401  Unauthenticated. When no or invalid authentication details are provided. Also useful to trigger an auth popup if the API is used from a browser
  • 403  The request is a legal request but user is unauthorized.  While none of the HTTP response codes match well with a business rule exception, use of the HTTP code 403 indicates that the server is refusing to fulfill the request.  This status code can be used when a business rule won’t allow fulfillment of the request - e.g. Enrollment when a class is full.
  • 404  Not Found - When a non-existent resource is requested
  • 405  When an HTTP method is being requested that isn't allowed for the authenticated user. 
  • 409  Resource Conflict can be possible in complex systems. It can be caused by fulfilling the request. Duplicate entries, deleting root objects when cascade-delete not supported are a couple of examples.
  • 410  Gone - Indicates that the resource at this endpoint is no longer available. Useful as a blanket response for old API versions
  • 415  Unsupported Media Type - If incorrect content type was provided as part of the request
  • 422  Unprocessable Entity - Used for validation errors
  • 429  Too Many Requests - When a request is rejected due to rate limiting

Server Error Scenario

  • 500 INTERNAL SERVER ERROR – The general catch-all error when the server-side throws an exception
  • 501, Not Implemented. The server does not support the functionality required to fulfill the request. This is the appropriate response when the server does not recognize the request method and is not capable of supporting it for any resource
  • 503 Service Unavailable. The server is currently unable to handle the request due to a temporary overloading or maintenance of the serve

Errors and Exceptions:

Errors should be as descriptive as possible. The following format is recommended

Code

Error code (over and above HTTP code) to describe the error message

Message

User-friendly message

Developer message

Message to debug the problem

More info

Link to additional information


JSON payload

Code Block
languagejava
{
  "message": string,
  "developerMessage": string,
  "moreInformation": string,
  "errors": [
    {
      "message": string
    }
  ],
  "code": string
}

JSON payload (API Archetype example automatically generated upon an improper post)

Code Block
languagejava
{
    "errors": {
        "code": 400,
        "status": "BAD_REQUEST",
        "timestamp": {
            "year": 2019,
            "monthValue": 5,
            "month": "MAY",
            "dayOfMonth": 3,
            "dayOfYear": 123,
            "dayOfWeek": "FRIDAY",
            "hour": 23,
            "minute": 44,
            "second": 25,
            "nano": 132000000,
            "chronology": {
                "calendarType": "iso8601",
                "id": "ISO"
            }
        },
        "message": "Malformed JSON request",
        "debugMessage": "Required request body is missing: public org.springframework.http.ResponseEntity<?> edu.ucsd.its.dis.auditservice.controller.AuditController.postAudits(edu.ucsd.its.dis.auditservice.persistence.db1.domain.AuditWrapper,java.util.Map<java.lang.String, java.lang.String>,java.lang.String) throws java.lang.Exception",
        "subErrors": null
    }
}

Note:

  • Either message or errors array MUST exist.
  • All other elements MAY be used. If the value is null, the element SHOULD be omitted. An element SHOULD NOT be an empty string.
  • Use an array of messages to capture multiple validation errors.


...