On and off from past couple of years I have been building out Rest API’s using Java and on some other occasions using .NET. I often come across debates as how to build the API’s and what features or functionality we need to expose with through the API. I have seen folks building API which exposes the entire dataset from the table something like (select * from some table) or something like this (select * from some table limit 0 20) or add some where clause and expose data based on some parameter. If we are using some framework like spring or ORM, then it’s just matter of couple of lines of code and we expose everything or want ever we want it to expose.
However in spite of having best frameworks out there or best tool sets, I see lot of team struggling to build out the API which does not do what they are supposed to do, they add all kinds of extra layers around API like API gateway wrappers , Circuit breakers etc. . to their lean business requirement and get lost in technical ocean, here by lean I mean any API which has less than 10 clients or consumers or are those API’s which are called couple of times in a day. I know I had a built out the API for some of small business with bare minimum working functionality with lean requirements. All I did was build out the API and then make them test it. Here is what I do and suggest for building out API’s
- URL’s should be restful. They should provide some information about the resources which we are trying to access or add or modify. They should be easy to read and looking at it should tell us the purpose of URL. Keep it short and Simple. I know earlier days I had quite a bit of trouble getting pretty URL’s. Now whenever I start building out the API URL’s, I ensure that it looks good and meaningful. Just ask yourself can I make URL easy for Search Engines to find or index the page or Can a third person remember the entire URL without making an effort ? Now a days most frameworks abstracts away URL path segments making it quite a breeze to make URL changes without breaking the code.
- Use HTTP verbs to doing CRUD Action. If any of the API’s I build do CRUD actions, then I logically group URL’s around HTTP verbs which conveys the API intent. Post to create new resource, Get to Fetch data, Put to Update and Delete for deleting resource or marking resource as logically inactive.
- If the URL has to implement many actions on the server side, then ensure that URL contains logical description of the action. Something like “/serverhost/resource/somecomplexmultistepactiononserver”.
- Use SSL wherever possible. Let’s Encrypt provides free SSL Certificates and there is nothing harm in using them. They are good certificates and I have received good feedback about them.
- Use API Versioning often to ensure that changes are tracked and communicated well. I have used limited versioning capability provided by frameworks. I just append to existing URL version numbers so as to indicate the latest one or still better is to just expose version information via cookies or headers by adding a single line of code.
- Think of Pagination or providing a way to page the results. It’s generally bad idea to blind fetch all data. API’s should and must support pagination while interfacing with plural datasets.
- Documenting the API’s and providing the client code as how to consume the API’s in the optimal way. Something like good, very good and very bad way of consuming the API’s.
- Sometimes it’s good to add extra code which will measure the API’s usage. Something like whenever API is called, increment a counter in some table etc. rather than using full rate limiting framework.
- Use logging wisely. Provide a switch which can be used to enable to provide all types of information for debugging purpose.
- Proper Error handling. Provide just enough information with reference number to track for user in case something bad happens.
- Most importantly, expose data what is required and not the entire object or all the data which tables contains. Still better provide a parameter to filter the results in the URL either using query params or path parameter.
- Embed nonfunctional requirement during initial phases of design and coding, start with just enough bare minimum NFR’s something like API needs to support more than 2 consumers at any time, need to do around at the minimum 6 calls per minute. Thinking this way will enable you to write concurrent and performant code.
- Limit the length of response data. Too length response often leads to all kinds of issues, so it helps to restrict the size of response.
- Use caching wisely unless we need real time data.
- As far as possible build stateless API’s. Stateful services requires different kind of principles and patterns.
- API’s should be simple to manage, debug or maintain. It should not take more than 10 ~ 20 minutes to figure root cause of issue in case of triages.
- Find the way to identify/monitor/report/prevent abuse of your API’s.
- Have a mechanism or filter which will identify return type for view and respond accordingly with appropriate response data format.
So start by building out with pieces which serves P1 requirements, and roll it out and then incrementally add other wrappers or features to it rather than using all big bang approach to design or coding.
Comments are closed here.