Skip to content

Instantly share code, notes, and snippets.

@yassermzh
Last active August 29, 2015 14:05
Show Gist options
  • Save yassermzh/8996f0349b73308724e4 to your computer and use it in GitHub Desktop.
Save yassermzh/8996f0349b73308724e4 to your computer and use it in GitHub Desktop.
Restfull API examples

Introduction

Here, I've gathered best practices and guides with only tweaking their examples to match our specific project.

NOTE: Backend routes are different than front-end routes. The Restful API is about the backend routes, not the routes one sees in the web application.

URL Structure

  • A URL identifies a resource.
  • URLs should include nouns, not verb
  • Use plural nouns only for consistency (no singular nouns). Use HTTP verbs (GET, POST, PUT, DELETE) to operate on the collections and elements. You shouldn’t need to go deeper than resource/identifier/resource.
  • URL v. header:
    • If it changes the logic you write to handle the response, put it in the URL.
    • If it doesn’t change the logic for each response, like OAuth info, put it in the header.
  • Specify optional fields in a comma separated list.

from: https://github.com/WhiteHouse/api-standards

Non-standard headers should follow with X-:

  • not call-type, if any, but X-REQUEST-TYPE.

Good URL examples

  • List of Apps:
GET http://www.example.gov/api/v1/apps
  • Filtering is a query:
GET http://www.example.com/api/v1/apps?type=free&sort=desc
GET http://www.example.com/api/v1/apps?category=games&year=2011
  • A single app in JSON format:
GET http://www.example.com/api/v1/apps/1234
  • All comments in this app:
GET http://www.example.com/api/v1/apps/1234/comments
  • Specify optional fields in a comma separated list:
GET http://www.example.com/api/v1/apps/1234?fields=comments,date,draft
  • Add a new comment to a particular app:
POST http://example.com/api/v1/apps/1234/comments

from: https://github.com/WhiteHouse/api-standards

Bad URL examples

  • Non-plural noun:
http://www.example.com/app
http://www.example.com/app/1234
  • Verb in URL:
http://www.example.com/apps/delete
  • Filter outside of query string
http://www.example.com/apps/1234/screenshots/mobile

from: https://github.com/WhiteHouse/api-standards

Error Handling

An error response should consist of the following:

The appropriate HTTP error status code and any other relevant headers; A human readable message in the appropriate format (including a link to the documentation); A Link header to a meaningful state transition if appropriate. An example from the twilio api:

GET https://api.twilio.com/2010-04-01/Accounts.json

results in:

401 Unauthorized
WWW-Authenticate: Basic realm="Twilio API"
{
    "status": 401,
    "message": "Authenticate",
    "code": 20003,
    "more_info": "http:\/\/www.twilio.com\/docs\/errors\/20003"
}

from: http://blog.luisrei.com/articles/rest.html

or

HTTP/1.1 429 Too Many Requests
{
  "id":      "rate_limit",
  "message": "Account reached its API rate limit.",
  "url":     "https://docs.service.com/rate-limits"
}

Never release an API without a version number. Versions should be integers, not decimal numbers, prefixed with v. For example: Good: v1, v2, v3 Bad: v-1.1, v1.2, 1.3 Maintain APIs at least one version back.

Request & Response Examples

Getting list of resources GET /api/apps

Example: http://example.com/api/v1/apps

Response body:

{
    "metadata": {
        "resultset": {
            "count": 123,
            "offset": 0,
            "limit": 10
        }
    },
    "results": [
        {
            "id": "1234",
            "packageId": "com.oovoo",
            "title": "oovoo",
            "tags": [
                {"id": "125", "name": "Communication"},
                {"id": "834", "name": "Chat"}
            ],
            "created": "1231621302"
        },
        {
            "id": 2351,
            "packageId": "com.coursera"
            "title": "Coursera App",
            "tags": [
                {"id": "125", "name": "Education"},
            ],
            "created": "126251302"
        }
    ]
}

Getting a resource GET /api/apps/1234

Example: http://example.com/api/v1/apps/1234

Response body:

{
    "id": "1234",
    "packageId": "com.oovoo",
    "title": "oovoo",
    "tags": [
        {"id": "125", "name": "Communication"},
        {"id": "834", "name": "Chat"}
    ],
    "created": "1231621302"
},

from: https://github.com/WhiteHouse/api-standards

Minimize path nesting

In data models with nested parent/child resource relationships, paths may become deeply nested, e.g.:

/developers/{developer_id}/apps/{app_id}/comments

Limit nesting depth by preferring to locate resources at the root path. Use nesting to indicate scoped collections. Even though childs may be arbitrarily nested, it's good to keep the depth limited to 2, if possible. Longer URLs are more difficult to work with.

So the above one would be better to be called this way:

/developers/{developer_id}/apps
/apps/{app_id}/comments
/apps/{app_id}/screenshots/{screenshot_id}?screen=mobile

References

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