The purpose of this document is guidance for designing and building RESTful APIs.
[Introduction statement here…]
In 2000, Roy Fielding proposed Representational State Transfer (REST) as an architectural approach to designing web services.
REST APIs are designed around resources, which are any kind of object, data, or service that can be accessed by the client. A resource has an identifier, which is a URI that uniquely identifies that resource.
Clients interact with a service by exchanging representations of resources. Most web APIs use JSON as the exchange format.
REST APIs use a uniform interface, which helps to decouple the client and service implementations. For REST APIs built on HTTP, the uniform interface includes using standard HTTP verbs to perform operations on resources. The most common operations are GET, POST, PUT, PATCH, and DELETE.
REST APIs also use a stateless request model.
Focus on the business entities that the web API exposes. Resource URIs should be based on nouns (the resource) and not verbs (the operations on the resource). Use plural nouns for URIs that reference collections.
A resource does not have to be based on a single physical data item. While it can represent a data item, avoid creating APIs that simply mirror the internal structure of a database. Also avoid introducing dependencies between the web API and the underlying data sources.
It is also best to avoid resource URIs more complex than “/collection/item/collection”.
The HTTP protocol defines several methods that assign semantic meaning to a request. The common HTTP methods used by most RESTful web APIs are:
GET
POST
PUT
DELETE
GET requests over collection resources can potentially return a large number of items. Therefore the API should be designed to limit the amount of data returned by any single request. Also the API should be designed to allow passing of a filter in the query string of the URI.
Consider supporting query strings that specify the maximum number of items to retrieve and a starting offset into the collection.
Example: /orders?limit=25&offset=50
One of the primary motivations behind REST is that it should be possible to navigate the entire set of resources without requiring prior knowledge of the URI scheme.
Each HTTP GET request should return the information necessary to find the resources related directly to the requested object through hyperlinks included in the response, and it should also be provided with information that describes the operations available on each of these resources.
HATEOAS = Hypertext as the Engine of Application State.
NOTE: Currently there are no standards or specifications that define how to model the HATEOAS principle.
Example: GitHub @ https://api.github.com/
It is important to version APIs. There are many approaches to versioning APIs. Here are some examples:
No Versioning
https://adventure-works.com/customers/3
URI Versioning
https://adventure-works.com/v2/customers/3
Query String Versioning
https://adventure-works.com/customers/3?version=2
Header Versioning
GET https://adventure-works.com/customers/3 HTTP/1.1
Custom-Header: api-version=1
Media Type Versioning
GET https://adventure-works.com/customers/3 HTTP/1.1
Accept: application/vnd.adventure-works.v1+json
General Guidance
Use nouns and NOT verbs
GOOD = /products
BAD = /getAllProducts
Use Plurals
GOOD = /products
BAD = /product
Use proper HTTP methods: GET, POST, PUT, PATCH, DELETE
User proper HTTP Response Codes: 200, 201, 204, 400, 404, 500
Use Query String Parameters (for filtering)
/products?name=ABC should be preferred over /getProductsByName
/products?type=xyz should be preferred over /getProductsByType
Provide Pagination
Version your APIs
Use forward slash (/) in URIs to indicate a hierarchical relationship
Do NOT use a training forward slash (/) in URIs
Use hyphens (-) to improve readability of URIs
Do NOT use underscores (_) in URIs
Use lowercase letters in URIs
Do NOT use file extensions (in URIs)
Never use CRUD function names in URIs
Do not expose the internal business objects or database objects; use DTOs
Query string parameters and object properties should use “camelCase”
GET /customers
GET /customers/{customerId}
GET /customers/{customerId}/orders
GET /customers/{customerId}/orders/{orderId}
GET /customers?lastnameStartsWith=smith&pageSize=25&pageIndex=100&orderby=FirstName
POST /customers
POST /customers/{customerId}/orders
PUT /customers/{customerId}
PUT /customers/{customerId}/orders/{orderId}
PATCH /customers/{customerId}
PATCH /customers/{customerId}/orders/{orderId}
DELETE /customers/{customerId}
DELETE /customers/{customerId}/orders/{orderId}
API Design @ https://docs.microsoft.com/en-us/azure/architecture/best-practices/api-design
RESTfulAPI.net @ https://restfulapi.net/
API Gateway @ https://docs.microsoft.com/en-us/azure/architecture/microservices/design/gateway
REST Security Cheat Sheet @ https://cheatsheetseries.owasp.org/cheatsheets/REST_Security_Cheat_Sheet.html