This is a session given by Asbjørn Ulsberg at Nordic APIs 2016 Platform Summit on October 25th, in Stockholm Sweden.
Description:
This talk is for developers dabbling in REST, but who aren’t yet invited to Roy Fielding’s thanksgiving dinner. It will go through the history of REST and how it relates to SOAP and RPC-style APIs before delving down into the concepts of hypertext and hypermedia, how to implement them in your API and last, but not least; Why!
If you’ve started exploring the world of REST and miss the comfort of safe typing and service discovery of SOAP and WSDL, this talk is for you. You will learn why this is missing in the world of REST, what alternatives exist and how your API can embrace them and become much more self-descriptive and user friendly than RPC-style APIs could ever dream of!
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
The REST And Then Some
1. GET /presentation HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json
{
"what": "The REST And Then Some",
"where": "Nordic APIs 2016 Platform Summit",
"when": "2016-10-25T14:40+02:00"
}
12. POST Does ”something” with the resource
GET Retrieves the resource
PUT Replaces or creates the resource.
PATCH Given right state in client, apply a diff operation
DELETE Delete the resource
…
Defining REST: CRUD
14. Defining REST: URIs
URI Method Description
http://api.com/v1/customers POST Creates a new customer
http://api.com/v1/customers/{id} GET Retrieves customer
http://api.com/v1/customers/{id} PUT Updates customer
http://api.com/v1/customers/{id} DELETE Deletes customer
http://api.com/v1/customers/{id}/orders GET Retrieves customer’s orders
http://api.com/v1/customers/{id}/notes GET Retrieves customer’s notes
17. Defining REST: URIs
URI Method Description
http://api.com/v1/customers POST Creates a new customer
http://api.com/v1/customers/{id} GET Retrieves customer
http://api.com/v1/customers/{id} PUT Updates customer
http://api.com/v1/customers/{id} DELETE Deletes customer
http://api.com/v1/customers/{id}/orders GET Retrieves customer’s orders
http://api.com/v1/customers/{id}/notes GET Retrieves customer’s notes
18. Defining REST: URIs
URI Method Description
http://api.com/v1/customers POST Creates a new customer
http://api.com/v1/customers/{id} GET Retrieves customer
http://api.com/v1/customers/{id} PUT Updates customer
http://api.com/v1/customers/{id} DELETE Deletes customer
http://orders.com/orders-for-customer/{id} GET Retrieves customer’s orders
http://api.com/v1/customers/{id}/notes GET Retrieves customer’s notes
19. Defining REST: URIs
URI Method Description
http://api.com/v1/customers POST Creates a new customer
http://api.com/v1/customers/{id} GET Retrieves customer
http://api.com/v1/customers/{id} PUT Updates customer
http://api.com/v1/customers/{id} DELETE Deletes customer
http://orders.com/orders-for-customer/{id} GET Retrieves customer’s orders
http://api.com/v2/customers/{id}/notes GET Retrieves customer’s notes
20. Defining REST: URIs
URI Method Description
http://api.com/v2/customers POST Creates a new customer
http://api.com/v2/customers/{id} GET Retrieves customer
http://api.com/v2/customers/{id} PUT Updates customer
http://api.com/v2/customers/{id} DELETE Deletes customer
http://orders.com/orders-for-customer/{id} GET Retrieves customer’s orders
http://api.com/v2/customers/{id}/notes GET Retrieves customer’s notes
21. What is the best practice for
versioning a REST API?
26. REST: Constraints
1. Client-Server
2. Stateless
3. Cacheable
4. Layered
5. Code on demand (optional)
6. Uniform Interface
1. Identification of resources
2. Manipulation of resources
3. Self-descriptive messages
4. Hypermedia as the engine of application state (HATEOAS)
27. REST: Constraints
1. Client-Server
2. Stateless
3. Cacheable
4. Layered
5. Code on demand (optional)
6. Uniform Interface
1. Identification of resources
2. Manipulation of resources
3. Self-descriptive messages
4. Hypermedia as the engine of application state (HATEOAS)
28. Hypermedia as the engine of
application state is a REST constraint.
Not an option. Not an ideal.
Hypermedia is a constraint. As in,
you either do it or you aren’t doing
REST.
55. Shut Down
Shutting down
Idle
Do/Turn Off
Heater
GET /toaster HTTP/1.1HTTP/1.1 200 OK
{
"id": "/toaster",
"state": "shutting-down",
"operations": []
}
56. Shutting down
GET /toaster HTTP/1.1
Off
HTTP/1.1 200 OK
{
"id": "/toaster",
"state": "off",
"operations": [{
"rel": "on",
"method": "PUT",
"href": "/toaster",
"expects": { "state": "on" }
}]
}
Hello! Thank you all for coming. I'm going to talk a bit about REST and hypermedia today.
I’m Asbjørn Ulsberg,
Business Architect for Web, API design and interfaces.
In PayEx.
Now that we have looked a bit at what REST is not, let's try to figure out what it is.
The Argentinian author Jorge Luis Borges. (Horxe Luis Borxes)
Started thinking about hypertext concepts in the 1930’s
1941: The Garden of Forking Paths: The first black on white reference to hypertext.
About the Chinese Doctor Yu Tsun, a former professor of English, now a German spy in England during World War 1.
Tsun can take multiple possible actions, but regardless of what actions he takes, he will always end up being arrested by Captain Richard Madden.
“The Library of Babel” and ”The Book of Sands” expands on the hypertext ideas.
The same concept as The Garden of Forking Paths can be found in modern RPG-style games like Bioshock Infinite and Fallout 3, where each decision forks the story in a new direction.
1963: Ted Nelson coined the terms 'hypertext' and 'hypermedia' in a model he developed for creating and using linked content
(first published reference 1965).
1967: worked with Andries van Dam to develop the Hypertext Editing System (text editing) at Brown University.
In December 1968, the first public demonstration of a hypertext interface was performed by Douglas Engelbart
oN-Line System or more commonly, NLS.
"The Mother of All Demos”: Mouse pointer, hypertext editing, word processing, e-mail and a windowing environment.
Word processing was born
Many of Engelbart's team members went on to start the Palo Alto Research Center, known as Xerox PARC, in 1971:
http://www.thocp.net/biographies/engelbart_douglas.html
In 1987, Bill Atkinson at Apple Computer created HyperCard.
It was a successor to lots and lots of things:
Xcode before Xcode (programming environment)
AppleScript before AppleScript (near-english programming language)
Java before Java (JIT)
Interface Builder before Interface Builder, which was Visual Basic before Visual Basic.
Flash before Flash (animations)
FileMaker before FileMaker (build databases)
Built-in debugger
”Fix and continue” before “fix and continue”
Tim Berners-Lee
1989: Develops "WorldWideWeb” at CERN, on a NeXTStep computer.
1991: HTTP 0.9, Formal description, no status codes, GET only.
1996: HTTP 1.0, RFC 1945
1997: HTTP 1.1, RFC 2068
1998: Dave Winer utvikler og publiserer XML-RPC
1999: HTTP/1.1 RFC 2616
2015: HTTP/2
The co-author of foundational specifications such as HTTP/1.1 (RFC 2616) and URI (RFC 2396)
2000: Roy Fielding doctorate dissertation
Architectural Styles and the Design of Network-based Software Architectures
Chapter 5: Representational State Transfer
REST
What is REST, exactly?
Difficult to answer.
What I do know is that it is surrounded with a lot of misconceptions.
I wish I had time to go through them all, but I’ve picked a couple of the most common ones here.
The first misconception I’ve chosen is that REST maps directly to CRUD. It doesn’t.
Without going into the details about REST being an architectural style and not a protocol, let’s go through the methods.
POST can create, manipulate or represent any method. It is used to tunnel the whole SOAP protocol, for instance.
PUT can both create and replace, but not really update a resource.
Only GET and DELETE map, the rest of the methods does something completely different.
Secondly, focusing on CRUD will lead to a badly designed API.
The second misconception is about URIs.
URIs, then. Are they important?
Which of these are most RESTful?
RESTful URI: You have no idea.
That doesn’t mean pretty and human readable, consistent URIs aren’t important.
But from a REST perspective, it is just an opaque identifier.
You will discover URIs through hypermedia, so what it is shouldn’t matter one ounce.
What's important is what surrounds the URI, such as the:
method
input data
response
Does this look familiar?
Who thinks this is good API documentation?
If your API is overly concerned with URIs and enumerating them in the documentation, you don't have a RESTful API.
You have what Stefan Tilkov calls a “URI API”
The bad thing about this is that you burden the clients with server details, while giving up control over something the server should be master of.
Let's say you have a database table
Wouldn't it be annoying if you couldn't rename it because a client you didn't control had the table name hard coded in its SQL statements?
The right spelling of Referer is with two r's, but since you've made the clients dependent on your spelling error, you can never rename the table.
You have what Stefan Tilkov calls a “URI API”
The bad thing about this is that you burden the clients with server details, while giving up control over something the server should be master of.
It's the same way with URI-dependent APIs.
If you want to move a resource to a different URL, every client needs to be updated.
If you want to make a backward incompatible change to the notes resource, you give it a new version number.
You now need to give all resources a new version, even though they didn’t change.
Do tedious work on your URIs and what operations you can perform on them
Don’t write it down in documentation.
Write it down into your resources instead, as inline hypermedia controls.
Makes the resources self descriptive, decouples the client from the server and makes the server much more flexible in what it can do.
URI templates are for APIs what GET <form> is for HTML.
Roy Fielding gave a talk for the Adobe Evolve conference in 2013
There, he proposed the following question: What is the best practice for versioning a REST API?
His answer?
So, now that we know what REST is not, let’s discuss what it might be.
I like to think of learning REST like learning a foreign language.
A study called:
"The Foreign-Language Effect: Thinking in a Foreign Tongue Reduces Decision Biases”
(by Boaz Keysar, Sayuri L. Hayakawa and Sun Gyu An in Psychological Science)
http://www.economist.com/blogs/johnson/2012/05/foreign-languages-and-thinking
Proves that different languages affect how we think, act and feel.
The same applies to architectural principles and programming languages.
Who here knows functional programming?
Would you say it makes you think and develop differently than you do (or did) with procedural languages?
It at least means that you can't use your RPC competency and just apply it to REST.
You will fail.
REST consists of 6 constraints.
Another way to look at it: Guarantees.
Of all the constraints, I believe the last one here is both most important and less understood.
That's why I'm going to try to explain it.
In an 2014 interview with Mike Amundsen, Roy Fielding said this.
https://www.infoq.com/articles/roy-fielding-on-versioning/
Links and operations
Those links and operations are analogous to real-life affordances, as popularized by Don Norman in his book the "Design of Everyday things”.
Like a cup “wants” to be held and lifted and a button “wants” to be pushed, hypermedia should explain to the client what the resource ”wants” the client to do.
Don Norman defines an affordance by “Do people know what to do based on what they see?”
In the same way, we can define hypermedia by “do machines know what to do based on what they see”.
So, how does hypermedia look like?
Does it look familiar?
Forms are hypermedia recipes of how the next request is going to look like
How do we transport our knowledge of hypermedia in HTML to an API?
Let's start by reformatting the HTML
Replacing all attributes with common ones, makes it more consistent and more "API-like".
Making further adjustments
Like generating a new WSDL in the response to every request.
Just like HTML.
So, how can we use hypermedia in practice?
As REST defines, hypermedia should be the engine of application state.
Here’s what that means.
Let's use a toaster as an example
Initial state of a toaster is Off.
We turn it on, and it reaches on status, eventually heating our bread.
After it has been heating for a while, it reaches an upper temperature limit
Bringing it into an idle state.
When it reaches a lower temperature limit, it will go back into heating state.
Eventually, the bread will be done and the toaster will enter the shutting down state
Ending in the off state, just as we started.
If we turn our toaster into an HTTP resource, how does it look like?
Let's try to GET it.
We can see that it has an off state
We can also see that it has an operation that allows us to turn it on
Let's look at that operation a little more closely
If we just reformat it a little
It starts looking like an HTTP request
Well, look at that! The toaster is now on.
We see that we can now turn it off again, but we can also increase the heating strength.
By the way, does anyone notice anything different hre
Well, look at that! The toaster is now on.
We see that we can now turn it off again, but we can also increase the heating strength.
By the way, does anyone notice anything different hre
Well, look at that! The toaster is now on.
We see that we can now turn it off again, but we can also increase the heating strength.
By the way, does anyone notice anything different here?
Ah. The toaster is now heating at strength 3.
We see that we can still turn it off and adjust the strength.
But what about that ID up there? Doesn't that look suspiciously like a URI?
It seems the toaster has reached an upper temperature limit, putting it into an idle state.
Although it may look like it, we did not alter the state of the toaster with our GET request.
We just discovered that the state had changed, by doing a safe, idempotent request.
Let's repeat the GET request and see what's happened.
Seems like our bread is done and the toaster is shutting down.
We now have no available operations, since we can't do anything while the toaster is shutting down.
Getting back to versioning, when you use hypermedia, you're much more flexible:
Adding properties to JSON is fine.
Adding relations to new resources is fine.
Adding new representations to the same resource is also fine.
So we have a lot of ways we can guide new clients to new content without:
Affecting old clients
Adding a version number to our URIs
You can reach me on:
Twitter
E-mail
Slack. Join the HTTP API slack! It's full of great people in love with the web and APIs.