Author: Shawn Wildermuth
Too often, APIs were developed around a remote procedure call (RPC), so that APIs looked and felt like locally executing code. While this made APIs look and feel like functions, it also made it more difficult to transition them to the Web. This is because the HTTP protocol is naturally connection-less and it required developers to think about it differently.
Along the way, many technology stacks tried to solve this problem by giving developers an RPC-like stack that tried to hide the details. This approach helped move applications to the Web faster, but left developers writing inefficient code. In the midst of this, an influential paper surfaced that talked about building Web-based APIs in a better way: REpresentational State Transfer (REST).
How REST can help
REST is an architectural style that uses simple HTTP calls for inter-machine communication instead of more complex options like CORBA, COM+, RPC, or even SOAP. Using REST means your calls will be message-based and reliant on the HTTP standard to describe these messages.
Using the HTTP protocol means REST is a simple request/response mechanism. Each request returns a subsequent response. You can see what a simplified request and response look like below:
Requests are made up of a verb (POST, in this example), headers that describe the message, and a body (Hello World, in this example). The request is a message that describes what you want the server to accomplish. Likewise, the response consists of three pieces: a status code (200), headers describing the response and the body itself.
HTTP Verbs describe the type of operation:
- GET: Retrieve a resource
- POST: Create a resource
- PUT: Update a resource
- DELETE: Delete a resource
On the Web, the most common verb is GET. This is because the main purpose of a Web page's function is to request different resources that make up a page. In REST-based APIs, we leverage these verbs to describe the types of operations we want.
How is REST useful here?
It works because you're not tying your API to your client-side technology. You could imagine that this API is accessible from a client-side Web project, an iOS app, an IoT device and even a Windows Phone. This allows you to build the infrastructure for your organization with fewer worries about the longer-term marrying to a particular client-side stack. The server lives longer than the client. It always does.
Another key idea in this architectural philosophy is that the server supports caching and is stateless. These ideas are very important to how REST works. Caching is important, as if multiple requests for the same resource are requested, caching of the result of the request means that the scalability of the server should increase.
Likewise, statelessness is about making sure that calls to the API aren't tied to a particular server, which increases the likelihood of building scalable server infrastructures. Because the server is stateless, every call to it must include all the data required to execute the request. The HTTP protocol is connectionless (there's no guarantee that your request is going to the same server, or how long it will be between those calls to the server).
Stateless is a good thing, but if you're a seasoned enterprise developer, you might already be concerned about the message size. That's the trade-off here. By keeping the server stateless, you're paying with larger payloads. But the reality is that in most situations, this pays off by handling load better in a data center.
Roy Fielding outlined REST in a doctoral dissertation, and that paper has been the basis of much discussion and dissent. There's a difference between REST and being REST-ful. I believe that there are great benefits of using the philosophy of REST in your web-based APIs. But at the same time, I've seen the REST moniker used as a cudgel to beat down implementations.
REST means different things to different people. For example, if you look at RPC over HTTP, REST, and HATEOAS (e.g Hypermedia), the stack of REST becomes complicated:
If you're implementing a REST-ful API, that means you're going to build a lot of code to accomplish every task. There are benefits to building this code in most situations, but it's a cost you have to see a benefit in. If your APIs don't include all the pieces of REST and HATEOAS, there are some true believers who criticize APIs. It's as if they're saying, “If it isn't fully REST-compliant, it's worthless.” By adhering the dogma instead of the reality that most developers need to get work done and move on, I think these true believers are causing more harm than help.
My answer is pragmatism. I use REST-ful APIs to build many of my projects. I build them to be resource-based, use HTTP verbs and headers, and keep my servers stateless and cache-able. For some systems, I find it useful to use hypermedia to build the APIs. In my thought, most of my APIs are pretty REST-ful, but it's not 100 percent.
The pragmatism comes in when I need something specialized. Even in a perfect system, not everything can be thought of as a resource. Customers, orders and products are all resource,s so using REST-ful APIs to interact with them makes sense. But what happens when you need a RPC-style call? In my world, that's fine. So, don't worry if you have the occasional APIs that look like this:
This works because it lets us lean back into the world of being pragmatic. You could build a whole system for functional-style APIs and separate them from your REST-ful API so you can tell people at the user-group that your API is pure. But who does that serve? At the end of the day, REST is incredibly useful for building large, scalable systems. Just remember that our jobs is to provide great solutions, and succumbing to dogma only gets in the way of that.
Want to learn more about REST? See Shawn's courses on REST and more.