Don’t read this! It makes little sense to built a RESTful API when technologies like GraphQL are being rapidly
In a perfect world code would talk with code and do so seamlessly. Sadly, as is the case with everything that man has built, APIs come in different shapes and sizes and getting them to talk with each other can sometimes be the major pain in your posterior. The most common way of thinking of APIswebservices today is going RESTful. It is common because it is efficient, simple and (if done well) can be an elegant way of opening up your system to the outside world.
I will try to list down a few best practices (as they are called) which are rather common sense checklist that one must keep in mind before venturing out to design an API: Versioning - Even if you are making an API that only talks to your own front-end code hosted on the same box, it makes sense to have a version number for your API. Most frameworks that help you build quick and robust APIs already give a provision to include a version number, if the one you are using does not, make sure you do that extra bit of adding one to the endpoint url. It would make the life of clients interacting with your API a lot easier when something changes.The way you include is a matter of aesthetics! I personally like to have something of this sort: http:/api.awesomeapp.comv1users
You can include it as a query parameter as well, which brings us to the next point.
Clean URL vs query parameters - Again, this is a matter of choice. No really! Ideally, let the juice of the request be clean and use query parameters for things like ‘offset’, etc.The ’’juice of the request’ is the end-point name, version number of the API, etc.examples: http:/api.awesomeapp.comv1usersid http:/api.awesomeapp.comv1users?offset=1000&fromId=1234
RESTFul is old school (and it kicks ass) - REST is nothing new. It is not a new protocol, just a new way of looking at API with old (experienced) eyes. REST is built on the good old http protocol. The basic idea is to use the http methods (GET, POST, PUT, DELETE) along with an end-point (and throw in your common sense along).Here’s the common sense bit: Take GET for example for the resource ’’users’. If the url points to a specific record (which is the case when, say, an ’’id’ is appended at the end) return that record, otherwise return a list of records. Returning lists - Not many systems would like to receive hundred thousand records when they query your API! Always use lazy-loading of objects and limit the number of records that are fetched together and sent back in the response. Use ’’offset’, etc. in the query parameters to get the remaining set. (Streaming APIs are a different beast that we’ll kill in another episode) HATEOAS is your best friend - I recommend that you visit that link and read more on HATEOAS! In short what it means is that when you send your response, let’s say, for a list of users, make sure that each user node in that list has a uri pointing to that particular user. Which brings us to the next point.
Data exchange
I would highly recommend using JSON as the format of data exchange between the server and the client. JSON format is clean, easily extendable and almost every language has great JSON parsers that make life easy for you. If you are using something like MongoDb as your database, the implementation becomes a piece of cake because Mongo uses BSON and in most cases all you’ll have to do is use the request and response interchangeably to communicate between the server and client.
Authentication
There are many options. The option that you should never opt is an API without authentication!!! I would suggest you to go for OAuth (there are different versions - look for a future post on this site for which one to use or go read the rfc notes). It is the recommended way of authentication for web-services and there are tons of libraries that you can use to create your own OAuth provider.
Don’t be a snobbish web-service
Be good to the client! Do proper error handling and always return proper (documented) error messagescodes in the same format that success responses go. For example, don’t throw a 404 HTTP error code response, have an error code inside your 200 response that tells the client that the request failed, etc. Include URIs to help documentation in the error response or at the least give detailed error messages.
Good to haves
Here are a few things that are good to bundle with your API implementation. They go well with the point number 8 above:Build a test client that let’s your users experiment on a test data set. Have an API schema entry point. This should list out all entry points of the API (think of this as the top level of a perfect HATEOAS implementation) Design the APIs in such a way that even when the implementation behind the scenes changes, the API end-points remain the same (this is in fact one of the most important thing to consider in API design!)
(I’ll try to keep expanding this list, while trying to keep it short. Think of this as a ’notes-to-self’ post so I’ll come back and add links to resources and share more refined knowledge as I learn more. Do comment with your suggestions.)