Aleksandar Susnjar July 7, 2023
If you search the internet for “RESTful API,” you’ll get a flood of results from thought leaders, industry experts, and engineers, fueling the perception that “REpresentational State Transfer” (REST) is the best approach to building APIs on the web. But is that really the case?
Many organizations are eager to tap into the uniformity and consistency that REST promises. However, there’s one problem: REST isn’t a magic wand that you can wave over an API to make it successful. The nature of REST as a set of idealistic principles makes it hard to put into practice. By definition, most APIs aren’t fully RESTful. And many technologists don’t realize that there are times when strictly adhering to REST can even undermine a platform’s success.
The best way to understand whether this approach works for (or against) you is to take a step back and examine some of the myths that have grown around REST over time. I’ll share my insights about some alternative approaches in a future blog post. Here, I’ll unpack five myths that may change how you think about REST and whether it’s the right fit for your organization.
MYTH 1: REST(ful) is a standard
RESTful isn’t a standard at all, “on paper” or in reality. There are some guiding principles, but it lacks a governing body. Often, the dissertation written by Roy T. Fielding in 2000 is cited as the origin, but the core idea was not new even then. RESTful concepts were present and used in other forms for decades before, and were not necessarily limited to HTTP. Mr. Fielding does not narrow it to HTTP, although he does rely on advancements adjacent to HTTP. He calls “REST” an “architectural style,” even years after its introduction. Those principles are noble in their intent but don’t define enough to form a standard.
The principles don’t focus much on the protocol itself. They focus on higher levels of abstraction, leaving out many details of how to map them to HTTP. For example, while there are some passing mentions of how to do PATCHing for partial updates, no common specification or guidance exists and everyone who attempts anything creates something new and distinct. A part of the challenge for REST is that the world’s requirements evolved far beyond what original REST goals could match.
It may be tempting to assume that because an API was built using REST principles, that the learnings from that project can be directly translated to future projects, and have a RESTful outcome. Unfortunately, because REST itself isn’t a standard, this isn’t the case.
MYTH 2: REST = HTTP
It’s easy to assume that REST APIs are simply those using HTTP query strings and request bodies as inputs, and try to loosely map business actions to HTTP methods when possible. It is deemed acceptable to have to create dedicated action endpoints for many others. Most of the time we’re only talking about APIs with JSON request and response bodies – anything else would be surprising, and exceptional.
That’s not REST. That’s “anything goes via HTTP.” RESTful principles restrict things we can do, so RESTful APIs are only a subset of that. It is a common misconception, though, that even Roy T. Fielding acknowledged by saying:
Keep in mind that RPC (Remote Procedure Call) isn’t bad, and in fact, it’s experiencing a resurgence with alternatives like gRPC. It is just different, and not RESTful. The RPC APIs we abandoned decades ago failed not because they were RPC but because they were verbose, cumbersome, inconsistent, and disparate and we used them incorrectly. With what we know today, we could make even those API approaches work much better.
MYTH 3: The presence of Swagger and Open API specs indicate RESTfulness
Swagger and Open API specifications can be used to describe many APIs based on HTTP, not only REST. They are best suited for JSON-based RPC via HTTP, and don’t make RESTful assumptions because that would restrict them too much. They “speak” of paths and endpoints, not resources and resource types. They indicate HTTP methods (GET, POST, PUT, DELETE, HEAD, OPTIONS and many others), not the higher-level concepts of REST which map to only a subset of those. They don’t enforce “representational states” in any fashion, they only enable requests and responses to be designed that way.
Most APIs with Swagger/Open API specifications use application/json HTTP MIME or media type for client-server exchanges. That is permitted but not required for RESTful APIs. Because they are focused on JSON, they have no way of expressing the internal structure for anything else and can only indicate the type without further details. RESTful APIs, on the other hand, are flexible and could support a mixture of any number of content types including JSON, XML, binary, or anything else. Finally, there is no single standard specification as to how one exposes a Swagger or Open API spec for a REST API.
What this means is that being able to express one’s API using Swagger or Open API specifications does not make one’s API either RESTful or standard – only specified and, perhaps, well-documented.
MYTH 4: The usage of “REST” tools makes your API RESTful
You may be using tools, libraries, and frameworks that have “REST” in their name: “RESTThis,” “ThatREST,” “REST4Xyz” (note: fictional, not intended to be real product names). These tools may be awesome in every respect, and may even be designed to help develop what their authors’ impression of REST APIs is. Even if that impression is perfect by any definition, it is how we use the tools that defines the product, not the tools themselves. Most often these tools aid in creating HTTP-based APIs in a fashion that Swagger and Open API specifications can specify. In that sense the same holds true as above – using these tools does not make one’s API RESTful, it just helps implement it.
MYTH 5: REST allows arbitrary endpoints
As noted in Myth 2, REST is not exactly the same as HTTP, although that’s a common assumption. And that brings us to our next myth: which is that REST, like HTTP, allows arbitrary endpoints. RESTful APIs aim to leverage HTTP for a limited set of prescribed actions on a distributed semantic web of resources, via “Hypermedia as The Engine of Application State” (HATEOAS). Although create, retrieve, update, and delete (CRUD) aren’t directly mandated, only these map reasonably well to HTTP’s POST, GET, PUT, and DELETE. That consistency is praised whenever it can be applied and makes it easy for developers to figure out how to execute a different action on the same “resource.”
Everything is to be triggered by submitting updated “representational states,” perhaps of a related resource. For example, adding an author to a document isn’t its own action; it could be a submission of an updated version of the complete representational state of that document. That updated state would include everything that was there already, plus an additional author. A server would have to notice the change and react to it, or simply store the given representation verbatim.
This appears simple for the client. It can make any number of changes it wants to the document instead of having to invoke multiple independent actions. The client can get a representational state, modify it into what it believes it should look like, and tell the server “make it look like this, use my copy.” Such an approach is wonderful for bidirectional caching and roundtrips. Assuming nothing else made any updates, the subsequent “GETs” will supply the same representation. Conversely, caching falls apart and becomes a fool’s errand if resources can change indirectly, via other endpoints. The apparent simplicity is offset by the extra responsibility – clients have to stay on top of knowing the proper ways of updating resources and being collectively disciplined about it at the same time.
Non-CRUD actions end up being frowned upon or downright prohibited for REST. This model falls apart as we encounter actions that work with multiple resources (e.g., transfer amounts from one account to another) or indicate transitions and not new states (e.g., restart a server). These concepts are segregated in CQRS (Command-Query Request Segregation) models. With REST, non-CRUD actions have to be made into resources of their own (e.g., “create a transfer” or “create a restart”), yielding an inconsistency – some actions map to HTTP methods while others have dedicated “action resource endpoints”. That is tunneling RPC via something that may appear RESTful but isn’t.
REST May Not Be What You Thought It Was
While pursuing the ideals of RESTful APIs may seem worthwhile for many organizations, exclusively employing tools and techniques that purport to be RESTful may not be the right path forward. Truly understanding what REST is, and dispelling the myths around it, can help you focus on your desired outcomes and assess whether REST is the right way to achieve them.
REST’s aim for uniformity and consistency turns into constraints that rarely match the real world. This is one of the reasons why, in my experience, I haven’t yet seen a single non-trivial real-world production API that strictly follows all the principles without having to work around them, e.g., by artificially turning actions into special resources or using inconsistent or overlapping representational states. Doing that may actually yield an API much more useful than what a REST API would be. However, it would no longer be RESTful; it would be some custom creation that likely does not benefit from following other, more suitable standards.
If reading this article created more questions than it answered, then it has accomplished its goal. I plan to write a series of subsequent posts to talk about better alternatives to REST that fit the needs of modern, enterprise-grade, APIs. Stay tuned!