Skip to content

Instantly share code, notes, and snippets.

@bert2
Last active May 8, 2019 09:06
Show Gist options
  • Save bert2/cb113b4b103f67919a1d15341f083212 to your computer and use it in GitHub Desktop.
Save bert2/cb113b4b103f67919a1d15341f083212 to your computer and use it in GitHub Desktop.
A very brief intro to REST

RESTful Web API Design

What is REST?

  • Buzzword
  • Short for REpresentational State Transfer
  • Architectural style invented by Roy Fielding
  • Set of constraints, rules, and conventions
  • Very hard to do 100% right
  • Replacement for RPC style applications

But what was RPC again?

  • Remote Procedure Calls are the "old way" of implementing client-server communication
  • RPC style applications implement their own protocols on top of HTTP (e.g. by using SOAP)
  • HTTP requests sent by an RPC style application will usually look something like this:
POST /searchUser HTTP/1.1
Host: www.myapp.com
...

<SearchUserRequest name="Ernie" />
POST /deleteUser HTTP/1.1
Host: www.myapp.com
...

<DeleteUserRequest name="Ernie" />
  • All the data needed to process a client request is inside the HTTP request body
  • URI path is only an arbitrary identifier to select the correct endpoint
  • All the data required to understand a server response is inside the HTTP response body
HTTP/1.1 200 OK
Content-Length: 81
...

<DeleteUserResponse>
  <Error>User could not be found</Error>
</DeleteUserResponse>

So what do RESTful applications do then?

  • Use HTTP features to design client-server communication
    • But actually... RESTfulness does not require HTTP--it's just typically used, because it aligns well with the requirement to provide a standardized application interface

Identify data and functionality using URIs

  • RESTful applications use Unique Resource Identifiers to identify the target of a request
    • /users represents a collection of users in the system
    • /users/ernie represents a specific user
  • Resources are hierarchical
    • /users/ernie/messages represents the messages of a user
  • Everything is a resource--even operations
    • /users/ernie/block represents an operation on a user
  • Use query parameters to filter a resource
    • /users/ernie/messages?contains=bert

Support HTTP methods on resources

  • Clients can act upon resources using the HTTP methods/verbs GET, PUT, POST, and DELETE
    • GET /users retrieves the list of users in the system
    • DELETE /users/ernie deletes a user from the system
    • POST /users creates a new user which is specified by the request body
    • PUT /users/ernie2 updates a user
  • PATCH should be used when partially updating a resource
  • But actually... RESTfulness does not require HTTP methods--they are just typically used, because they suit the requirement to have a set of simple, well-defined operations

Respond with helpful HTTP status codes

  • The status code of a server response should actually convey meaning
  • Of course the body of the response can still contain additional information
POST /users HTTP/1.1
Host: www.myapp.com
...

{ "name" = "ernie" }

========================

HTTP/1.1 400 Bad Request
Content-Length: 21
...

"User already exists"
DELETE /users/ernie HTTP/1.1
Host: www.myapp.com
...

========================

HTTP/1.1 403 Forbidden
Content-Length: 21
...

"Missing permission to delete users"

Have self-explanatory resource representations

  • Responses not only contain the resource data but also meta-data
GET /users HTTP/1.1
Host: www.myapp.com
...

========================

HTTP/1.1 200 OK
Content-Length: ...
...
{
  "self": "/users",
  "users": [{
    "name": "ernie",
    "links": [
      { "rel": "detail", "href": "/ernie", "type": "GET" },
      { "rel": "remove", "href": "/ernie", "type": "DELETE" }
    ]
  ]
}
  • Resource links depend on application state (e.g. what permissions does the client have)

Make the API discoverable

  • Clients only need to know a single starting URI (the bookmark)
  • All other resources are discoverable through resource meta data
  • Think of the resources as a set of websites with links between each other and the client as a human browsing those websites
  • This concept is called HATEOAS: Hypermedia As The Engine Of Application State
  • The client no longer needs to know how to reach certain resources and what operations it is allowed to perform on them
  • Such state information is dynamically generated by the server and transferred to the client as hypertext
  • Client only renders the data and links the server provided

Conclusion

  • REST + CRUD = BFF
  • Enables design of consistent and lightweight web APIs
  • There are intentionally no interface contracts between applications, since in HATEOAS the client must react dynamically to what the server provides
  • Not a silver bullet (e.g. over- and underfetching are typical problems)
  • Aims for standardization but guidelines/tutorials are sometimes fuzzy and unclear
  • Asking "But is this RESTful?" is an excellent way to start endless discussions and make your colleagues hate you
  • Hard to find any real world examples of 100% RESTful APIs--in fact the WWW seems to be the only one

Further Reading

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment