Created 02/27/2018 at 2018:03PM

So you've decided to create a REST service! Good for you! Here are some guidelines to help. Some you know and hopefully some you didn't.

Use generally accepted RESTful principles.

When considering endpoints and CRUD actions, use this method of mapping. It's pretty much the norm.

make it all revolve around that "orders" endpoint. In regards to relations, just extend your common sense...

Notice the URL is going to be the same? This is leveraging HTTP methods to implement significant functionality on the given endpoint.


Your API is for other developers so don't do a half-hearted job of documenting your API. Before someone uses your API they are going to want to see your documentation first. Consider making examples copyable so the developer can paste them into a browser or curl.

Once your API is public, you have an obligation to keep a changelog, so keep it updated or keep a mailing list.

Version your API

Offering use of older APIs as you improve is a good idea (within reason). Your consumer is building valuable apps on top of your services so you want to avoid their code breaking suddenly because you've improved things. How you manage goes a long way towards 100% stability across your consumer base.

Filtering, sorting and searching


Use a unique parameter for each field that has filtering. When requesting all orders that are closed, you can send a GET request like this /orders?state=closed.


You could endear yourself to developers by allowing them to query fields that can then be sorted. You could allow multiples fields to be sent comma delimited and a unary operator to designate ascending or descending.

For instance..


Sometimes you just need the power of a full search and solutions like ElasticSearch and Lucene do a wonderful job. You can expose the search as a parameter on the resource's endpoint and return it the same way you would otherwise.

GET /orders?q=banana&state=closed&sort=+priority,creation_time - This would give you a list of tickets in a closed state, ordered by ascending creation time that contain the word "banana".

Limit the response fields you return

The consumer doesn't need EVERY granular bit of information about a particular resource. Minimizing network traffic is always a best practice and you can speed their use of the API.

For example:

GET /orders?fields=id,customer_name,creation_time&state=closed&sort=+creation_time

This returns only the fields of id, customer_name and creation_time whose state is closed and ordered, ascending, by creation time.

Use HTTP 201 and a Location header on creation

When creating a new post, return the appropriate HTTP status code of 200 and include a Location header that will direct the consumer to the new resource.

'AJAX' is sexy, 'AJAJ' is not. You have to accept that.

Forget XML. Seriously. It's hard to parse, it's hard to read and it generally isn't compatible with how most modern languages model data. That being said, you may have to support XML because of legacy or stubborn customers who still insist on it. The most sensible thing to do here would be to append to .json or .xml to the endpoint URL.

snake_case or camelCase

While not quite at the level of the emacs/vi holy war, my own opinion is snake_case. Go ahead and use camelCase for field names because that just happens to be the JavaScript naming convention. Use snake_case for your JSON API though because it's just easier to read according to some.

Use SSL. Always. No excuses.

Many locations that will consume your API are potentially not secure. All it takes is an insecure internet connection to hijack credentials and you've got an impersonator on your hands. There is a wonderful advantage to SSL and that is authentication efforts are easy. You can use simple access tokens instead of having to sign EVERY request. Increase your security by throwing a hard error when non-SSL accesses your API URLs. You don't want a quiet redirection from an unencrypted endpoint to an encrypted one.

Don't use an envelope by default. Only when needed

A lot of APIs use an envelope by default.

{ "data" : { "id": 987, "name": "Billy" } }

It's not like there AREN'T legitimate reasons for an envelope. JSONP requests have no access to HTTP headers is a good one. It's also possible that the client is incapable of working with HTTP headers. Standards are emerging like RFC 5988 Link header to make enveloping irrelevant.

Limiting the rate

Build a better mousetrap and the world might unintentionally DDOS your server. That's why it's a standard practice to rate limit your API. It's a best practice to not keep your customer in the dark about where they stand on rate limiting though. Here are three you should use..... X-Rate-Limit-Reset - Number of seconds left in the current period X-Rate-Limit-Limit - Number of allowed requests in the current period * X-Rate-Limit_Remaining - Number of remaining requests in the current period

Generally a consumer just wants to know when they send it again and how often. Be practical

Authentication of service

A REST API is stateless which means that authentication sholdn't depend on cookies or sessions. Each request needs credentials. By always using SSL, credentials are provided via random generated access tokens delivered in the HTTP Basic Auth.

JSONP support in your API presents a different problem because JSONP requests can't send HTTP Basic Auth creds or Bearer Tokens ( like OAUTH 2). You could use another parameter such as access_token but remember that web servers store query parameters as part of their logs.


Last-Modified is your friend here. HTTP has built in caching (lucky you!).

Useful Error Messages

If you have spent even a small amount of time on Windows, you know how frustrating vague error messages can be. There are generally two types, 400 series for client side and 500 series for server side. Send it as a JSON representation.

{ "code" : 987, "message" : "OH NO, something went wrong", "description" : "See details here" }

Familiarize yourself with HTTP status codes

There are a bunch of pre-designed status codes for you to use and Wikipedia has a good breakdown.