REST / API best practices and functionality recommendations

Notes from designing a beautiful REST&JSON API.


  • Resources are nouns not verbs (eg accounts not creating accounting)
  • Resources are coarse grained not fine grained - resources need to encapsulate a lot
  • Your main resources should nearly always be plural

Two types of Resource

  • Collection (e.g /accounts)
  • Instance resources (e.g /accounts/123)



  • GET read
  • POST Create
  • PUT Update (unique identifier is known by client)
  • DELETE delete
  • HEAD get header information, used for cross origin resource sharing, authentication checking

Media Types

Media Types are set in your request header and response header tells you what the server is giving you.

  • Format specification + parsing rules
  • Request: Accept header
  • Response: Content-Type header


  • application/json
  • application/foo+json
  • */*

Design rather than


In the URL or in the header request: application/json;application&v=1


Use CamelCase not under_scores!


All resources should have createdAt field. Use ISO8601 standard, and use UTC so you don't have to worry about the local timezones. Use Carbon to manage date functions.


Header values are comma delimited in order preference:

Accept: application/json, text/plain

Resource extensions

Adding an extension will override the Accept header

/application/abc123.json /application/abc123.csv /application/abc123.txt

Error codes

415 - Unsupported media type


Instance resources with htef

Always return a href to the resource

    href: '',
    name: 'joe blogs'
    email: ''

Collection references

GET /accounts

 Instance reference

GET /accounts/123

Resource expnsion

GET /accounts/123?expand=directory


Collection resources should support parameters

  • Offset
  • Limit
  • Size
  • e.g /accounts?offset=50&limit=25

and return first,next,last urls:

    "href": '',
    "offset": 50,
    "limit": 25,
    "size": 250,
    "first" : {
                    "href": ''
    "next" : {
                    "href": ''
    "last" : {
                    "href": '...'
    "items": [
            name: 'joe blogs'
            email: ''

Many to Many

  • A group can have many accounts
  • An account can have many groups

Use href links to account and group details:

"items": [
            name: 'joe blogs'
            email: ''
            account: {
                "href": ''


  • Be as descriptive and give as much information as possible

    "status": 409,
    "code": 12345,
    "property": ""
    "message": ""
    "developerMessage" : ""
    "moreInfo": ""
  • status is HTTP status
  • code is your internal code
  • message is a standard field and should always be included


  • Avoid sessions
  • Authorise based on resource, not url
  • Use API keys instead of username/password
  • Use existing protocols
  • 401 (unauthorised) means unauthenticated
  • 403 (forbidden) means unauthorised


  • IDs should be opaque and unique
  • Avoid auto increment IDs, use UUID and uniqid() but be careful as it's not secure. Auto increments could allow someone to work out how big your database is and browse different endpoints by just changing the key.

Method Overrides

If you want users to use a FORM to interact with your API rather than Curl etc, attach the method at the end of the form URL.

For example:

POST /accounts/xyz123?_method=DELETE

(Laravel does this)