It is simply impossible to adequately describe REST in this document. There will be some effort in this article to offer some understanding because it is the key reason for developing the SRP HTTP Framework in the first place.
In short, REST is an architectural style, or approach, of communications between different computer systems. While the theory of REST lends itself to any computing system, it was given birth and lives primarily in the web. REST is arguably a formalized explanation of the way the internet (via HTTP) is meant to be used. REST offers a set of constraints that guide how the communications are to be properly handled. These constraints aim to build systems with greater visibility, reliability, and scalability. A full implementation of the REST architecture extends beyond APIs, but APIs are where REST principles are most actively used.
It is helpful to understand REST APIs by first looking at an alternative API style that is more familiar to us: Remote Procedural Call (RPC). RPC APIs treat the server primarily as an engine to execute procedures, and these procedures are named either in the URL (e.g., typical CGI) or in the payload (e.g., SOAP). RPCs leverage HTTP as a transport mechanism, while generally not giving much attention to the broader design and features that HTTP provides. Consider APIs that are needed to provide full management of system users. In an RPC approach, this would likely require at least four unique APIs (or URLs):
GET /GetUsers
(Retrieves a list of all users from the server.)GET /GetUsers?UserID=GeorgeWashington
(Retrieves the user with an ID of GeorgeWashington from the server.)POST /CreateUser
(Assuming there is a payload with user information, this will create a new user on the server.)POST /UpdateUser
(Assuming there is a payload with updates user information, this will update the user on the server with only the information provided.)GET
(orPOST
)/DeleteUser?UserID=GeorgeWashington
(Deletes the user with an ID of GeorgeWashington from the server.)
Note that the emphasis is on the URL rather than the HTTP method. The only reason POST must be used in two of the APIs is because GET normally cannot send payload content. The main point is that there are four different APIs (/GetUser
, /CreateUser
, /UpdateUser
, and /DeleteUser
) that have to be documented and supported by the client. REST APIs treat the server as a destination where resources are accessed. While the server may indeed be executing procedures, this is obscured from the URL itself, allowing the user to think about the resource as an item rather than an action. REST APIs rely upon the HTTP method (GET, POST, PUT, DELETE, etc.) to determine what should happen to that resource. Hence, through the use of these HTTP methods, a single URL can take on several meanings. This simplifies API design and the need for extensive documentation, as seen below:
GET /Users
(Retrieves a list of all users from the server.)GET /Users/GeorgeWashington
(Retrieves the user with an ID of GeorgeWashington from the server.)PUT /Users/GeorgeWashington
(Assuming there is a payload with user information, this will create a new user with an ID of GeorgeWashington on the server.)PUT /Users/GeorgeWashington
(Assuming there is a payload with updates user information, this will update the user with an ID of GeorgeWashington on the server with only the information provided.)- DELETE
/Users/GeorgeWashington
(Deletes the user with an ID of GeorgeWashington from the server.)
With the RESTful approach, there is only one API, /Users
, which is much easier to remember and document than four APIs. The HTTP methods are what define the behavior of the API. Since these methods are formally established in the HTTP protocol, they are not subject to redefinition, change, or republication with each set of RESTful APIs.
Another important constraint of the REST architecture, but often underutilized, is HATEOAS. This difficult to pronounce abbreviation stands for Hypermedia As The Engine Of Application State. A key feature of HATEOAS is that server responses include more than just content, they also contain the necessary hypermedia (i.e., URLs) necessary to move forward into the API. This is incredibly powerful because it allows APIs to be self-documenting. If clients are designed to anticipate URLs in the response then the server can change the URL to access a given resource at anytime, and this will not break the client or require new programming. To demonstrate:
Request
GET /Users
Response
HTTP 1.1 200 OK
Content-Type: application/hal+json
Content-Length: ...
{
"_embedded" : {
"item" : [
{
"_links" : {
"self" : {
"href" : "/users/GeorgeWashington"
}
},
"UserID" : "GeorgeWashington",
"FirstName" : "George",
"LastName" : "Washington"
},
{
"_links" : {
"self" : {
"href" : "/users/AbrahamLincoln"
}
},
"UserID" : "AbrahamLincoln",
"FirstName" : "Abraham",
"LastName" : "Lincoln"
},
{
"_links" : {
"self" : {
"href" : "/users/TheodoreRoosevelt"
}
},
"UserID" : "TheodoreRoosevelt",
"FirstName" : "Theodore",
"LastName" : "Roosevelt"
}
]
},
"_links" : {
"self" : {
"href" : "/users"
}
}
}
In the above JSON formatted response, each user is listed with its relevant field content (UserID, FirstName, and LastName). Each user also includes a self link, associated to the href field, that informs the client how to retrieve this resource. Thus, RESTful responses include content that is both meaningful to humans and machines. As can be seen, clients do not need to be programmed how to retrieve specific users. This information will always be provided in the API response.
There is no established method for handling HATEOAS (or Hypermedia) responses. There are several formats which have been proposed, but a few have risen to notable prominence. One of them, known has HAL (Hypertext Access Language), is what is represented in the above response. This is why the Content-Type response header has a value of application/hal+json
. To help API developers generate hypermedia responses (and thus make their APIs more REST compliant), the SRP HTTP Framework provides several application services (located in the HTTP_JSON_Services function) to make it easier to build HAL+JSON formatted responses.
The API developer is encouraged to study REST principles and practical examples beyond this rather brief introduction. There are many good online resources. Among these, there is a split between advocates for a more practical approach to REST and those who advocate a more principled approach (these are often referred to as REST purists, or RESTafarians). For those who desire to achieve fully RESTful APIs, The Richardson Maturity Model article provides a nice stepping-stone approach. Thus, it begins with some practical examples that will be easy to adopt, while providing a pathway toward full REST implementation.
It should be noted that while the SRP HTTP Framework is designed around the REST API model, it does not enforce it. Indeed, it can nicely work with any API methodology and replace the standard RUN_OECGI_REQUEST
(i.e., INET) utility, although some additional work would need to be done to replace pre-built INET routines. Note, while the SRP HTTP Framework can support INET style applications, RUN_OECGI_REQUEST
cannot support REST APIs. The primary reason is that RUN_OECGI_REQUEST
intentionally obscures the URL in favor of the INET routine that is named in the end point. Hence, there is no easy way to glean semantics out of the rest of the URL, thus rendering RESTful approaches useless.