Basic REST API Principles That make you a 1% programmer.

Design Principles and Rules For REST APIs

Alexander obidiegwu
11 min readJan 29, 2024
Are you a programmer or a fraud?

I was a fraud three days ago. I thought I fully understood the concepts behind REST API, REST / RESTful. Until a colleague of mine was trying to communicate verbally to me and all I could hear was gibberish.

Every 3 words spoken was followed by a mental freeze. Every tacit word was a foreign language. It was a spit on my reputation. One I hoped to dissolve away.

I decided to dedicate this article to do just that. To save me from who I was 3 days ago. And not just me, but everyone else who perchance comes across such a harrowing situation.

Together, we endure this brief period of redemption. In 5 minutes, we enjoy salvation.

Contact me on Upwork for software development jobs relating to Python/SQL.

What is an API?

Application Programming Interface

An API is an interface that enables communication between different applications. Interface doesn’t mean software interface i.e. the front end, but a shared boundary that allows different components of a computer system to exchange information.

Interfaces help components communicate with each other and function independently.

For example, Open the following link in your browser to request a random computer question from the Open Trivia Database:

https://opentdb.com/api.php?amount=1&category=18

If you open it, you should see a JSON like this

{
"response_code": 0,
"results": [
{
"category": "Science: Computers",
"type": "multiple",
"difficulty": "easy",
"question": "What does GHz stand for?",
"correct_answer": "Gigahertz",
"incorrect_answers": [
"Gigahotz",
"Gigahetz",
"Gigahatz"
]
}
]
}

This API helps a client (you currently) to communicate with the application’s server in order the retrieve the result when amount=1 and category=18.

What is REST?

Representational State Transfer

REST is simply a software/architectural design style that is used to guide how a client should communicate with a server. It can also be used for server-to-server communication.

In general, the one requesting the information is the client and the one (capable of) providing that information is the server.

But this doesn’t necessarily sound very intuitive given the full name, “Representational State Transfer”. What the heck could that mean?

Representational — To stand in for a particular item, object or person.
State — A given form of an entity at any particular point in time.
Transfer — To move something from one place to another.

So what exactly are we representing? A resource. A resource is simply data located on your server. This could be an image, HTML page, audio, video, etc.

So we are trying to represent that resource on an application. Not the exact state of a resource but a representation of it.

It’s like going to a high-end restaurant and while eating “high-end food”, you decide to take a picture of the food, just so others can see and use it in whatever way that’s relevant to them.

But ours is much closer to home than that. Instead of just seeing the food, we can actually get a taste of what the food is like or even eat it, but we’re not necessarily eating the exact one you ate in the restaurant. Just a representation (an image representation in this case). You get me?

So the state of the resource in the server is constant. But just the representation of it keeps changing.

This ability to transfer a resource using a representation of the resource state is what is called REST.

But what does a representation look like exactly? Let’s first see some examples of what a representation can be.

Some Examples of Representations

  • JSON
  • XML
  • HTML
  • IMAGE
  • Video

There are many more forms of representations, which usually depend on the data being sent or received, but the most common type of representation is JSON.

But if you remember, at the beginning of this blog, I defined REST as “REST is simply a software design style that is used to guide how a client should communicate with a server”.

To put that into context, when we want to access a certain resource from a server, the server sends us an appropriate representation used to access that resource eg JSON, XML, etc. This is done using the content-type parameter in the header object in the REST API.

For example, to make sure that when our REST API app responds with JSON, clients interpret it as such, we should set content-type in the response header to application/json after the request is made.

Using REST API

You can check this using developer tools in the browser. Let’s load up YouTube and see what the content type is:

As we can see the content-type is text/html for the youtube webpage. I think that makes intuitive sense.

The process of using a REST design principle is simply being RESTful. They both mean the same thing. RESTful is just the degree to which an application follows REST design principles.

Principles of REST

Client-Server

The first principle is to separate the concerns of the user/client and the concerns of the server. By separating the two, we improve the scalability of the server and the portability of the application.

Scalability is improved on the server because the server can afford to serve multiple users at once and simplify its server components while portability is improved on the applications because it can easily be deployed on multiple platforms.

This can also help both parties add new technologies and evolve without affecting how they communicate with each other.

If it were otherwise, adding new technologies would be difficult because it would obstruct the flow of the users i.e. every update/change would require users to understand the technicalities and how to adapt to the changes.

Stateless

The second principle is stateless. If you allow yourself a brief moment into the abyss of information provided on the internet relating to this principle, you would surely come out exhausted.

Stateless is simply a guiding principle whereby each request from a client must contain all necessary information for the server to process that request without taking advantage of any state or context (eg sessions) stored in the server.

Therefore an application must avoid storing a client’s state/context on the server but on the client side (eg using cookies on browsers).

The advantage of this is that our servers can free up resources and handle more load. It enhances scalability and reliability is improved because it eases the task of recovering from partial failures.

Cache

The third principle is cache. Clients need to be able to cache representations in order to improve network efficiency and reduce latency.

Cache requires that representations be explicitly or implicitly set as cacheable. If a representation is cacheable, then a client cache is given the right to store the representation for a period of time.

A benefit of cache is that it improves speed and user-perceived performance. It also reduces server load by instead serving cached data, rather than requesting for a new one every time.

One drawback with caching representations is stale data. When there’s an update to a representation or application, the client won’t be able to view the update until the cache expires or is explicitly removed.

But this is only a problem if the data cached is frequently updated or requires a critical update.

Uniform Interface

This is a major feature that distinguishes REST from other network-based architectures. It is the foundation of REST.

It suggests that there must be a generalized way for servers to transfer information or communicate with clients independent of device or application.

That is, every client should be able to communicate and receive representations from the server in the same way, irrespective of the client’s device or specialized needs.

It’s like having everyone speak English instead of each person developing their own set of language that suits them.

In order for such an interface to be adopted, a few standards must be followed:

  • Identification of resources: You use the URI (Unique Resource Identifier) to identify the resource required.
  • Manipulation of resources through representations: Using HTTP methods to describe the type of communication with the resource. So for example GET means that you want to retrieve data about the URI-identified resource. You can describe an operation with an HTTP method and a URI.
  • Self-descriptive messages: Self-descriptive messages mean that when transferring information or communicating, the media type of the representation must be clearly stated. This allows the end user to be able to understand how to parse and effectively use the data. MIME types are used when making messages self-descriptive. It consists of a type (eg application, text, etc) and a subtype (json, css, html) usually separated by a slash (application/json, text/html). This is usually set in the content_type (server) or accept (client) header parameter. Most libraries do this for you automatically.
  • Hypermedia as the engine of application state (HATEOAS): It’s a principle that suggests including hypermedia links in API responses. It gives clients related URI and resources that can be requested and accessed. It is used to provide clients with a means to access URIs without the need to follow the application’s default structure of URI paths. For instance, if you request a blog resource (/blog), in the body of the API response, it should contain links to access comments of the blog (/blog/comments) or likes of the blog (/blog/likes).
HATEOAS Example

Advantages of REST API

Widely adopted

REST API has massive users and due to this, there’s a community constantly updating documentation and building libraries that improve the speed of deployments when developing REST APIs.

Scalability

REST is highly scalable due to its approach when communicating and responding to clients.

Disadvantages of REST API

Lack of in-built security Features

REST APIs send data using HTTP(s). This is often enough for most services but when dealing with highly sensitive information (eg governmental information), it is usually an inadequate measure. This is because HTTP only encrypts data in transit but not at rest or destination. So once the data reaches its end user, it becomes highly vulnerable to attacks.

Lack of Standardization

Since REST is just a design principle but not a protocol, implementations can sometimes be inconsistent. Some might decide to adamantly follow its principles while some lethargically.

Best Practices for REST APIs

Use Nouns instead of Verbs in endpoint paths

We shouldn’t use verbs because HTTP methods (eg GET, POST) are already verbs. It would be redundant to use verbs. Instead, use nouns that describe the resource to be accessed or manipulated.

For instance, we want to get all articles www.example.com/articles instead of www.example.com/getAllArticles.

Use logical nesting on endpoints

We want to nest paths that are closely related to one another. We want to go through the house door before entering our rooms.

For instance, if we want to get the comment of an article, we can simply use the endpoint:

www.example.com/articles/12/comments/32

This points to comment 32 of article 12. This link can also be passed as a hypermedia link in an API response to www.example.com/articles/12.

But after some point of nesting, usually 2 to 3 levels, it can start to get a bit bogus and unreadable. We should instead consider creating a separate endpoint for accessing that particular resource.

So suppose we want to get the author of the comment, instead of using www.example.com/articles/:12/comments/32/author/JohnDoe, we can create an endpoint www.example.com/user/:users to get the author’s information.

Use Plurals

When creating endpoints, we want to always use plurals to refer to resources and then an `id` or unique identifier to specify the exact resource or information you want.

Wrong Format — www.example.com/article/12
Correct Format — www.example.com/articles/12

Handle Errors

We should always return custom error messages when there’s a HTTP request failure. This message would help would help the user understand what went wrong especially when business or application context is needed.

For example, instead of returning 401 Unauthorized, we could return Invalid token.

Use filtering, sorting, and pagination

Due to the extremely large amount of data that a server might have, it’s best to also apply some filtering or sorting to query to reduce server load and wait time. This would increase efficiency and avoid unnecessary calls.

We also need ways to paginate data so that we only return a few results at a time. We don’t want to tie up resources for too long by trying to get all the requested data at once.

Cache Data

Repeated requests over the same resource within a certain period can be redundant. It can also increase server load and therefore cost.

It’s a much wiser approach to cache frequently accessed resources to increase application speed and enable the server to delegate resources for other tasks.

There are many kinds of caching solutions like Redis, in-memory caching, and more. We can change the way data is cached as our needs change.

If you are caching data, you want to add the cache-control parameter in your header to signify that the resource is to be cached. This will help users effectively use your caching system.

Versioning our APIs

To make large/critical updates to our APIs over time, it’s recommended to version our APIs. This means any major change comes with a semantic version eg 1.0, 1.0.1, 2.0, 1.4.6, etc

This would allow us to provide services to our old users who still use our previous versions while servicing new clients with up-to-date technologies.

It also allows us to phase out an older version gradually and move clients to the newer version.

The v1 endpoint can stay active for people who don’t want to change, while the v2, with its shiny new features, can serve those who are ready to upgrade.

This is especially important if our API is public. We don’t want to break third-party apps when making changes to our APIs.

Versioning is usually done with /v1/, /v2/, etc. added at the start of the API path.

Some companies also prefer to have a sub-domain when accessing their API. For instance, instead of www.example.com/api/v1, we use www.api.example.com/v1. But anyone is fine.

Security Tips for REST API

  1. Always serve across HTTPS
  2. Avoid Reinventing the Wheel.
    Use frameworks that have been used and tested. Developers not familiar with designing secure systems often produce flawed security implementations when they try to do it themselves, and they leave their APIs vulnerable to attack.
  3. Don’t use a single key-based authentication, unless your API is free and public.
  4. Use Hash Message Authentication Code (HMAC) to encrypt because it’s the most secure. (Use SHA-2 and up, avoid SHA & MD5 because of vulnerabilities.)
  5. Your API should not leak exception information.
    If there is a data retrieval error in the database, your service should map it to a client-friendly exception of some kind. This is because, it gives the user some information about how your database is structured which could lead to vulnerabilities.
  6. Avoid using only Keys to handle authentication.
    Some services only use keys without a secret which is practically verifying a username without a password.

--

--

Alexander obidiegwu

Explaining foundational concepts and principles of Python, SQL and Mathematics.