HOW TO
CREATE A
WEB API
NO ONE WANTS TO USE
By /Karoline Klever @karolikl
THE GAME
NO ONE WANTS TO USE MY API
I have never created a public web API
TAKING A LOOK
at the world of Web APIs...
YOUR CAR HAS ONE
CHUCK NORRIS HAS
ONE
YOUR DOG HAS ONE
THE NUMBER OF WEB
APIS
is increasing fast
1995
"Why do we need a website?"
2000
"Of course we have a website!"
2005
"Why do we need an API?"
2010
"Of course we have an API!"
URI DESIGN
Badly named and inconsistent URIs that violate the
Principle of Least Astonishment will make your web API
just as disappointing as the movie "Mega Shark vs Giant
Octopus"
PRINCIPLE OF LEAST
ASTONISHMENT
"[...] a programmer should try to think of the
behavior that will least surprise someone
who uses the program, rather than that
behavior that is natural from knowing the
inner workings of the program."
PROBLEM #1
INCONSISTENT URI STRUCTURE
We cannot guess the URI of an endpoint based on our
experience with the other endpoints.
PROBLEM #2
URIS ARE NOT HACKABLE
/all_links_for_city_of/chicago/il.json
/all_links_for_city_of/chicago/il.json
/all_links_for_city_of/chicago/il.json
PROBLEM #3
LINK TYPES
/all_links_for_city_of/chicago/il.json
/all_links_for_county_of/cook%20county/i
/primary_links_for_city_of/chicago/il.js
/primary_links_for_county_of/cook%20coun
POSSIBLE SOLUTION
(ONE OF MANY)
/links
/links/il
/links/il/cook%20county
/links/il/cook%20county/chicago
/links/il/cook%20county/chicago?
type=primary
THE GAME
NO ONE WANTS TO USE MY API
Inconsistency
Violation
HTTP VERBS
Why do we need anything other than GET?
THE MOST COMMONLY
USED
GET
PUT
POST
DELETE
SAFE METHODS
"... the convention has been established that
the GET and HEAD methods SHOULD NOT
have the significance of taking an action
other than retrieval. These methods ought
to be considered "safe"."
ARE THEY SAFE?
GET: Yes
PUT: No
POST: No
DELETE: No
IDEMPOTENT METHODS
Methods we can issue the same request against as many
times as we want without changing the result.
ARE THEY IDEMPOTENT?
GET: Yes
PUT: Yes
POST: No
DELETE: Yes
GET CLIMATE
GET/vehicles/{id}/command/climate_state
{
"inside_temp":17.0,
"outside_temp":9.5,
"driver_temp_setting":22.6,
"passenger_temp_setting":22.6,
"is_auto_conditioning_on":false,
"is_front_defroster_on":null,
"is_rear_defroster_on":false,
"fan_status":0
}
OPEN SUNROOF
GET/vehicles/{id}/command/sun_roof_control?state=open
POSSIBLE SOLUTION
GET/vehicles/{id}/command/sun_roof_control
{
"state":"open"
}
PUT/vehicles/{id}/command/sun_roof_control?state=open
{
"result":true
}
THE OTHER VERBS?
GET Returns the state of the sun roof (open/closed)
PUT Open/close the sunroof
POST Not supported, cannot create new sun roof
DELETE Not supported, cannot delete sun roof
THE GAME
NO ONE WANTS TO USE MY API
Only GET
Wrong verb
HTTP STATUS CODES
Everyone just loves an "error in disguise"
PROBLEM #1
DISGUISING YOUR ERRORS
Invalid requests return with a 200 OK status code, giving the
impression that the request was successful.
PROBLEM #2
DISPLAYING YOUR INTERNALS
Including a detailed error report or stacktrace makes your
Web API vulnerable to attack
THE BASICS
200 OK Awesome!
400 Bad Request The user of the API made a
mistake
500 Internal Server
Error
The creator of the API made a
mistake
POSSIBLE SOLUTION
GEThttp://api.worldbank.org/countries/a?format=json
400BadRequest
GEThttp://api.worldbank.org/topic?format:json
400BadRequest
THE GAME
NO ONE WANTS TO USE MY API
Error in disguise
Displaying internals
RESULT FORMATTING
Dictating the format will drive developers away
XML IS ON DECLINE
Hurray!
POSSIBLE SOLUTIONS
URL extensions
Query string parameters
Content negotiation
THE GAME
NO ONE WANTS TO USE MY API
Dictation
VERSIONING
However perfect you make your web API, you're bound to
find a way that's even more perfect before long, and then
you'll need to launch a new version.
Capture5 -> Complete / Cancel2
URL VERSIONING
GEThttps://api.twitter.com/1.1/trends/place.json?id=1
QUERY STRING
PARAMETERS
GEThttp://api-public.netflix.com/catalog/titles/series/7002352?v=1.5
GEThttps://api.foursquare.com/v2/venues/40a55d80f964a52020f31ee3?oauth_token=XXX&v=YYYYM
VENDOR SPECIFIC
ACCEPT HEADER
HEADERAccept:{type}/vnd.{company}.{version}+{type}
HEADERAccept:application/vnd.github.v3+json
CUSTOM REQUEST
HEADER
HEADERx-ms-version:2014-02-14
HEADERapi-version:2
THE GAME
NO ONE WANTS TO USE MY API
No planning
Broken
SUMMARY
URI design
HTTP Verbs
HTTP Status Codes
Result Formatting
Versioning
QUESTIONS?
Thank you!
By / /Karoline Klever @karolikl karolikl@gmail.com

How to create a Web API no one wants to use