Skip to content

Ground up API Design Workshop

Matt Campo edited this page Aug 5, 2013 · 4 revisions

In this workshop we designed an API from the ground-up, for a theoretical university course registration/student information system. The goal of the workshop was to determine the best approach for writing a useful API. Here's what we came up with:

1) Understand the business requirements

  • user stories
  • use cases
  • visualization feedback
  • ACL restrictions
  • existing data model

2) Extract nouns & verbs

  • nouns are your resources (e.g. students, courses, buildings)
  • verbs correspond to CRUD functionality & map directly to HTTP request methods (POST, GET, PUT, DELETE) note: keep your URIs short
  • /courses
  • /cources/{id}
  • /courses/{id}/students (this route represents a relationship between resources)

3) Handle exceptions using HTTP response codes

  • 200 - General use, you may want to only use 200 errors and return an error message in JSON format
  • 201 - Used in response to a POST, PUT or DELETE request to indicate successful execution of request
  • 202 - Similar to 201, except indicates an asynchronous process is executing. Basically, this says "I successfully received your request. Give me some time to work on it."
  • 301 - Redirect; used primarily to handle versioning. (E.G.: version 1 has /students and /professors, but version 2 only has /persons. A 301 redirect would send API requests to /persons)
  • 403 - This error code admits that the resource exists, but that the user is unauthorized to view it. Not the most secure - you're admitting the resource actually exists. ( request: /students/12345 response: "You're not student 12345 so I'm not going to show you that information.")
  • 404 - A bit more secure. Your system plays dumb. ( request: /students/12345 response: "I have no idea what you're talking about, dude.")
  • 503 - Service unavailable (for many reasons; maybe the user reached their request limit for the day/hour).

4) Handle querystring parameters

  • Search: ?q=key:=value+key2:<value2...
  • Returning only certain fields: ?fields=id,name...
  • Pagination: ?offset=25&limit=5 OR ?page=3&records_per_page=10

5) Metrics & logging
Generally, you want to track:

  • Who is accessing the API?
  • How many requests is each user making?
  • How many 404s are we returning?
  • Do we need to use more 301s?
  • Which endpoints are being used the most/least/not at all?

6) Authentication
OAuth is the best bet, but you can also choose to pass a non-oauth token through the Authorization header.

Additional notes
Use hypermedia to represent relationships:

  • /courses/12345
  • {"id":"12345","title":"foo","students":"/courses/12345/students",...}

Version numbers can be passed either through HTTP headers or in the route (no consensus was reached in this regard).

Images from the workshop can be found here.