You're breaking into web development, terms are flying and your head is spinning. What's a REST API?!
For some of the younger generation who are reading this, believe it or not, there was a time when web development was a lot more simple. Write some HTML, tell the user, "welcome to my site!" and copy and paste a visitor counter - done 🎉
Now-a-days web sites need to do more than just connect to a database and display information. They need to connect to other web apps to display information, sync information and perform a myriad of automated and supplementary tasks. It's inevitable, so let's just say it: you need to learn how REST APIs work so you can create and consume them.
If you're just being introduced to REST this post is for you.
Web development practices, including REST, are like politics: there are some elements that everyone can agree on and a lot that are contested and debated. Usually these cordial disagreements end up looking like this...
...Yeah, developers are a special kind of gregarious folk - but we mean well.
I'm not going to delve deeply into the theological aspects of REST here, because this is meant to give you a simple look at some of the most basic principles of REST APIs. So, let's get started.
You can't really begin to understand RESTful architecture until you know your HTTP methods. Let's start with the fab-five. These 5 HTTP methods are the most commonly used in modern day web apps.
GET - Show me information (a list of products, a specific blog post).
POST - Create a new resource (order, register a user).
PUT - A method that will either create a new resource or update an existing resource. It should contain all of a resource's required fields. I.e. if your user resource has 8 required fields, all 8 need to be present.
PATCH - When you need to update a resource, but are not providing all of the resource's required fields. This HTTP method will always be targeting an existing resource where you know the identifier (/users/1482).
DELETE - When you want to delete a resource entirely.
Now, the straggling four. These HTTP methods are not always used in many web APIs, but they do exist and you should know what they do.
OPTIONS - This method is useful for telling developers what HTTP methods a given resource supports. Say I want to know what I can do with the /products endpoint. I send an OPTIONS request and the endpoint will basically tell me, "you can retrieve a list of products ([GET] /products) or a specific product ([GET] /products/32) and update a product ([PATCH] /products/42)". Now I know that resource does not support creating (POST) or deleting (DELETE) products. Responses to this method are not to be cached.
HEAD - This method is very close to a GET request but with one clear difference: there is no request body returned. If you made a GET request to /products and a HEAD request to /products, the GET request would return the normal response headers plus a response body containing products. The HEAD request would only return the response headers with no response body.
Why is HEAD useful? There's a few reasons. First, you might want to check if the resource exists before trying to do anything with it. Second, you might want to check the resource's cache state, which should be returned in the response headers. HEAD is perfect for these use cases.
CONNECT - This method establishes a connection between the client and host, usually for the purposes of creating an SSL tunnel. Usually this method does not contain any data in the request body or response body and favors simply telling whether the connection was successful or not in the response header.
TRACE - This method is used primarily during debugging purposes. It will return the trail of where the HTTP request was sent which could include redirects by the server. This is probably the least used HTTP method of the list.
Quite simply: Representational State Transfer. Got that? It's okay, nobody does when they first hear it.
REST was coined by Roy Fielding in 2000 when he wrote his doctoral dissertation. It was not without good reason that it was picked up and achieved wide range adoption across the web. Previously, developers were stuck with architectural patterns like SOAP (gag), which was not at all simple. The web was the wild west. Roy advocated that developers were not utilizing HTTP as it was originally intended and had a solution: REST.
You see, REST has a few core concepts. We won't take time to review them all, but here's a few important ones:
Statelessness - When you're making API calls (requests) to the server, it doesn't save anything about who you are. Every request you make requires you to provide your authentication information. Usually that comes in the form of tokens.
Proper request methods - In some obvious circumstances the HTTP method you choose to make an API call is not up for debate. If you want to be shown information you use GET. If you want to create information you use POST. You would never perform an action that updates or creates a resource using a GET request.
I once visited a web site while logged in and clicked a link in my dashboard only to be surprised that my account was upgraded to a trial of their premium plan. WHAT? The concept is easy to understand. I clicked a link expecting to see some information and instead they modified my account. The same is true in REST. The GET HTTP method means, "show me information" nothing else.
GET, HEAD, OPTIONS and TRACE are never to be used in directly changing the resource on the server.
Separation of concerns - The client (you, or your web app) has its duties and the server has its own duties. Don't try to force one side to do more than it was intended. Sometimes this means making more separate API calls.
For example, I may want to retrieve data from a server so I have to make several API calls to the server to traverse the various pages, then perform several more separate update API calls to change the data. Your first instinct might be to say, "why not just lump all of that into one endpoint and make one API call?" It seems easier at first, but you'll quickly realize it creates more problems down the road. Not only that, but you've just forced way more work onto the server and absolved the client of its responsibilities to interpret and handle the data.
Caching - It's entirely reasonable to expect the client (your site or person) to cache the data it receives from an API. It's also equally reasonable for the server to cache its response in the interest of speed. Usually the freshness of data is communicated from the server through response headers so your application can know if the response is cached and when it expires. There are also ways for the client to request the server not to return a cached response and fetch fresh data, but the means varies per API application.
When working with RESTful APIs, request methods are not a concrete one-to-one connection with your code. REST is a way of thinking which shapes the way you structure and write your code. Your programming language may or may not go out of its way to make that clear to beginners.
My first introduction to REST APIs came by way of PHP. I read through the various HTTP methods and got confused, "why is there no super global corresponding to
$_DELETE?!" The answer is rather obvious now, looking back. GET, POST, PUT, PATCH and DELETE are HTTP methods. It's up to you to find out how your language will allow you to read and send using these HTTP methods. The good news is that many language frameworks handle this for you and make it easy.
You need to start viewing your data as resources. A resource can be anything. Here are some examples of resources: users, orders, products, posts, order statuses, tracking numbers, etc. You get the idea, right?
Now that you're seeing data as a resource, you should be thinking about what operations can be applied to a resource. Say my resource is books:
Get a list of books: [GET] /books/
Get a specific book: [GET] /books/13
Create a book: [POST] /books/
Update some of the books attributes: [PATCH] /books/13
Update every attribute of the book: [PUT] /books/13
Delete the book: [DELETE] /books/13
Notice how the url structure didn't really change much between the operations? The difference was the HTTP method! My API was reading the method and deciding what to do with the resource based on the method and the data supplied (if any). That's a RESTful approach!
Separate resources are the goal. For example, let's say you were designing an API that had countries and their states/provinces. When a request was made for the United States should I send back all 50 states that belong to it? You could, but I would recommend separating them. Make one API call to get the country ([GET] /countries/US), take the country's
idand make a separate API call to get the states ([GET] /states?country_id=1).
You're going to find that as your API grows the separation of resources will make it easier to maintain. Does this means you never want to group resources and their children in API calls? No, not necessarily. But don't let your default answer be, "yes" without thinking about it. By making your resources separate you are introducing simplicity into your API and thats a good thing. Each resource endpoint now only needs to worry about itself instead of its children resources.
When creating your REST API make a determination to follow best practices and stick with it consistently. Here are a few examples:
- Use JSON for your request body. It is simpler and smaller compared to XML.
Use nouns instead of verbs for your uris. Your HTTP methods should be specifying what the operation does, not the url.
Correct: [POST] /books
Incorrect: [POST] /add-books
Use plural names for your resource uris. E.g. /products or /products/my-product-slug. Many well-established APIs follow the plural rule because the base endpoint indicates you want a list of that resource.
Use resource nesting to denote ownership - but don't go crazy with deep nesting. Keep it at 2, maybe 3 at the most. E.g. /users/1482/orders - will give me all of user 1482's orders.
Standardize your error messages. Nobody wants to work with an API that gives vague errors or sometimes shows errors in the response headers while other times showing errors in the response body.
REST really isn't that hard to grasp. I think a lot of people just struggle separating the principles from the implementation. I hope you found this article useful in helping you begin to grasp the basic concepts of REST - I know I wish someone had told me these things when I was getting started.
Did you learn anything valuable? Did I miss anything? Let me know down in the comments. Thanks for reading!