What Your API Would Look Like As A WebPage
... or, do you really want to write your API in .txt?
Lately, I have been in many discussions where I had to make a case for hypermedia. I have found that the easiest way to introduce folks to hypermedia is to just claim that their APIs are at a "lower maturity level" (usually L2) and point them to Richardon's Maturity Model.
What I have also found is that, while the general concept of hypermedia makes sense for some people, it is hard for them to understand what that means in practice *.
I don't blame them. There is very little on the subject in concrete terms (e.g. existing robust hypermedia APIs working in production code in a reasonably large corporation).
I thought that, if I showed them what their APIs would look like as if they were web pages, they'd get insulted enough to re-consider :) So, here it goes :)
Level 0: The Swamp Of POX
Very rarely I'd come across a L0 API in my daily job, but I understand there are a bunch of enterprise code that uses SOAP. At this level, your API calls go through one endpoint and you are only using one HTTP method.
POST / HTTP/1.1
Host: www.example.org
Content-Type: application/soap+xml; charset=utf-8
Content-Length: 299
SOAPAction: "http://www.w3.org/2003/05/soap-envelope"
<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Body>
<m:ScheduleAppointment xmlns:m="http://www.example.org/doctors">
<m:DoctorId>123</m:DoctorId>
</m:ScheduleAppointment>
</soap:Body>
</soap:Envelope>
This what your API looks like, seem from the perspective of the web for humans:
http://example.org/index.txt
Welcome to my website!
Here are some doctors available:
Mr. Jones and his ID is 123. He has the following available slots:
- Tuesday, 05/02
- Wednesday, 05/03
If you'd like to make an appointment, please, take your browser window and append act=create and doc=123 and slot=05/02 to our web site!
K THX BYE XOXO
As you could've imagined, all interactions with this website is via its root page. There is just index.txt and that HTTP servlet does it all.
It is also notable that the entire website is in a .txt file, as opposed to a hypermedia media type like .html. What that means is that the website is instructing you to manually construct their URLs to carry on. I know, right!
http://example.org/index.txt?act=create&doc=123&s=05/02
Appointment slot created!
Please, don't reload this page, or else we'll create another appointment! Just go away :)
Thanks for your business!
Because you are not using HTTP in its entirety (e.g. you are creating a reservation slot with a GET), you don't get the benefits that a HTTP client gives you (e.g. warning a user whether they want to re-submit the data when refreshing a page after a POST).
Level 1: Resources
This is a slightly more common case, but I still very rarely find this on my day job.
GET /doc/123/slots/05/02.txt?action=create HTTP/1.0
Host: example.com
At this level, you are breaking up your API in multiple resources but still using just one HTTP method.
http://example.org/index.txt
Hi Welcome to our website! Here is our directory of doctors:
- Mr. Jones and his ID is 123.
If you'd like to make an appointment, please, take your browser window and append doc/ and the doctor ID to our web site!
Because you are not using hypermedia (e.g. links), you are still making your users construct their URLs by hand. They get IDs from you, look at your documentation and construct the next step.
http://example.org/doc/123.txt
Hi! Welcome to doctor Jones appointment page! Here are the appointments available:
- Tuesday, 05/02
- Wednesday, 05/03
If you'd like to make an appointment, append /slots/ and the date you'd like to schedule!
I know, seriously, right!
http://example.org/doc/123/slots/05/02.txt
Hi! Welcome to doctor Jones appointments for 05/02!
If you'd like to make an appointment, append a ?action=create to this page to create!
Really? OK, I guess ...
http://example.org/doc/123/slots/05/02.txt?action=create
Appointment slot created! Thanks!
Please, don't reload this page, or else we'll create another appointment! Just go away :)
This is a step forward, albeit quite a small one. Breaking down your API into multiple resources gives you things like addressability (e.g. you can forward links to people now!) and a more scalable load balancing approach.
Level 2: HTTP Verbs
Now, this is where I'm almost sure you are at if you are reading this. You pay your taxes, you eat your vegetables and you went to an ivy league school. You are trying your best to be RESTful and you have an open mind.
You spent countless hours breaking up your resources into a layout that makes sense, each resource supports very specific verbs ("even PATCH and DELETE" you say, proudly!) and yet ... I'm comparing your API to a website circa 1990.
GET / HTTP/1.0
Host: example.com
HTTP/1.0 200 OK
Content-Type: text/json
{
"doctors": [{
"name": "Dr. Jones",
"id": "123"
}]
}
The problem is ... you are using a .txt file, like JSON or XML.
This is what your API look like:
http://example.org/doc/123/slots/05/02.txt
If you'd like to make an appointment, send a POST request to this page to create! As parameters, send a slot=7pm or 8pm which are available!
The issue here is that you are using out-of-band information to tell users what your API affords. You are literally asking them to "read your page" and "construct a POST request" in English, rather than something that the browser can understand (e.g. a