Common Mistakes In REST API Design

I was thinking API design is pretty easy and intuitive. But actually it’s not.

Just like the famous difficulty of naming things(functions, variables, modules).

Designing clean and just-enough API takes experience and efforts.

Your experiences? Leave Me Comments.

How To Design REST API



Similar Posts:


Good Examples/Resources:

How To Design REST API


Common Mistakes:

  • In GET requests, add parameters inside the body, instead of in URL
  • Use lengthy names, while we have better choices
project_id -> id
project_name -> name
err_msg -> message
  • Define our own error code and error message. Try to re-use HTTP protocal first.
curl -i https://api.github.com -u foo:bar
HTTP/1.1 401 Unauthorized
{
  "message": "Bad credentials",
  "documentation_url": "https://developer.github.com/v3"
}
curl -i https://api.github.com -u valid_username:valid_password
HTTP/1.1 403 Forbidden
{
  "message": "Maximum number of login attempts exceeded. Please try again later.",
  "documentation_url": "https://developer.github.com/v3"
}
  • Better use dash(-), instead of underline(“_”)
From:
http://api.dennyzhang.com/books/my_first_post

To:
http://api.dennyzhang.com/books/my-first-post
  • Missing API protocal version in the URI. It would be hard to manage, when we have API breaking changes.
From:
> GET /projects

To:
> GET /v1/projects
  • No authentication to protect system from malicious requests.

See example from GitHub.

There are three ways to authenticate through REST API.

Requests that require authentication will return 404 Not Found, instead of 403 Forbidden.
This is to prevent the accidental leakage of private repositories to unauthorized users.

1. Basic authentication
curl -u "username" https://api.github.com

2. OAuth2 token (sent in a header)
curl -H "Authorization: token OAUTH-TOKEN" https://api.github.com

3. OAuth2 token (sent as a parameter)
curl https://api.github.com/?access_token=OAUTH-TOKEN
  • Unnecessary or useless parameters in the BODY of request or response
  • Make sure the APIs are logically correct
  • Remember to support pagination, if too much data involved
GET /v1/projects?page=${page}&per_page=${per_page}

# page: page numbering is 1-based

# per_page: How many bid counts we want to see for each page
  Sorted in ascending order.
  The default is 30. The valid range is [1, 400] (inclusive)
HTTP/1.1 200 OK
{
  "count": 2,
  "projects":[
    {
      "id": int,
      "summary": string,
      "description": string
    },
    {
      "id": int,
      "summary": string,
      "description": string
    }
  ]
}
  • Response a json with a embeded list. Make sure it’s a valid json.
HTTP/1.1 200 OK
{
  "project_id": int,
  "name": string,
  "description": string,
  "budget": float,
  "deadline": timestamp,
  "item_list": [
      id1: int,
      id2: int,
      id3: int
     ]
}

  • Sample: startMachine
curl -X POST -H "Content-Type: application/json" \
     -H "Authorization: Bearer b7d03a6947b217efb6f3ec3bd3504582" \
     -d '{"type":"reboot"}' "https://api.digitalocean.com/v2/droplets/3164450/actions"

This is how digitalocean deals with it.

Resource is actions. HTTP method is POST.

linkedin
github
slack

PRs Welcome

Blog URL: https://www.dennyzhang.com/design-rest-api


Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.