• Bytes Route logo

RESTFul APIs: Definition

This is the second article in a five part series on RESTful APIs.

Architecture style, stateless, and design constraints

Everybody uses REST applications to access information from the internet. REST APIs are everywhere, in news sites, blogs, social media, etc.

But what is REST? REST is an application architecture style defined by Roy Fielding in his dissertation from 2000.

RESTful APIs started being used right away, first @ eBay (±2000) and Amazon(2002), then it became more popular and others followed including Facebook & Twitter (2006). Before REST people used SOAP (a different architecture style) for client-server communication and XML as a data format (different from JSON). The protocols were HTTP/TCP/IP. For REST the typical data format used is JSON. JSON has a bunch of benefits by being easily parsed by Javascript which is the language used in all browsers, is human-readable, and not that verbose as XML.

Every style implies constraints, if you have no constraints you have no style. To be considered a RESTful API, it has to satisfy all the constraints that define it. If it does not satisfy all the constraints it is considered REST-based.

Constraints

1. Use of uniform interface. This means that whatever service you are creating and whatever client consumes the API it has the same interface. Does not matter if you have a news site, a forum, telehealth application, social networks, etc, you use the same interface of having an URL for a resource and manipulation it via HTTP verbs like GET and POST. Request, type, resource, and content and format. We need the JSON format. Resource manipulation through representation. HATEOS. Once it has access, it can see everything. Does not care who consumes the data and how. Web app, mobile app, IoT device.

2. Server-client architecture. Having the server-client architecture means there are several benefits like loose coupling between server and client, a highly portable system and a clear separation of concerns between content and presentation.

3. Stateless, the state should be kept on the client, separation of concerns, redeploy fast, scale up as needed. All requests should be self-contained. Sessions are not stateless. If something is stored on the server for requests then this constraint is violated.

4. Caching, all resources should be cached by default unless explicitly indicated that cannot be done. Performance optimization for rest. ETag header is used.

5. Layered system. This implies the composition of higher-order systems.

6. Code on demand. JavaScript code from the client, this implies that we can create a new application on the client. Transfer just the state and there are no issues. Just update the data without creating a whole new page.

Richardson maturity model

According to the Richardson maturity model, there are 4 levels for REST APIs:

1. Everything is a single endpoint, no resources, no verbs, no HATEOS

2. Uses resources properly but not verbs and no HATEOS. Basically dividing the app complexity in more resources to be used.

3. Uses resources, status codes, and verbs properly but no HATEOS, applying a uniform interface for the resources that were divided from the business model.

4. Uses resources, verbs, and HATEOS properly, applying discoverability in the application.

Clarifications

Even though there is no strict requirement that REST is to be done via HTTP, REST being an architectural style, merely a definition, a convenient pairing has been formed between the REST style, HTTP, and networked/cloud applications.

REST and HTTP have such a strong synergy that the entire net is at its very nature a giant REST application with small exceptions and varying maturity levels. Both HTTP and REST have no memory of previous requests.

Everything can be a resource, usually in the domain of the problem you should find nouns for resources(sometimes adjectives) and HTTP verbs for actions.

There are 2 kinds of resources, collections, which implies a list of elements and singletons which are a specific instance of the resource.

Resources can be narrowed down through specificity in the API. Usually, endpoints are used in singular if they represent a resource and plural if they represent a collection, a verb might be used for some action that is not CRUD, checkout for example.

/user => collection of users

/user/1234 => a unique user-specified via id

/user/happy/1234 => a happy user with a specific id, singleton

/cart/1234/checkout => a happy user with a specific id, singleton

The resource is the data at the end of the resource URL and the representation is the data obtained when accessed. A resource might be held in a Mongo database, accessed via an URL but the format of the HTTP response might be JSON, which is the representation of the resource.

Designing RESTful APIs

The game is hard, a good engineer makes the proper decisions of implementation trade-offs and naming/explanations of the API. You have to think about your user, who will consume the API.

Understand the business process, participants and activities, break them into steps and write them down. After writing find the nouns (sometimes the adjectives) in the text.

Create the API definitions and validate them with the people involved. I always design the system based on the KISS principle and the principle of least surprise.

Consistency is key. Make some decisions and keep ‘em. It will save you a lot of headaches.

Don’t use underscores, uppercase letters, and trailing slash ‘/API/v1/user-management’ >> ‘/API/v1/User_Management/’

Use query params for searching/filtering of resources of type collections. Example: add items to the cart, we have items and cart as the resources and can choose the HTTP verbs to manipulate them.

That's all for now, next Servers & Node.js.