We all know you should make your API backward-compatible as much as possible. But how about forward-compatible? That is, being careful to make sure your API design will be consistent with future changes that you don’t know you’ll make yet. Sounds impossible? Adam Bar over at the Bright Inventions blog gives you eight steps he’s learned in order to make it a reality.
The first step to future-proofing your RESTful API is to expose your endpoints with proper versioning from day one. Why? So you won’t need to reorganise your routing code to manage unversioned and versioned endpoints later on. At the same time, Adam advocates getting your clients to identify themselves from the beginning. So have them send their platform and locale details in the header. In this way, if the code diverges for different platforms in future, you’ll be able to manage requests according to the platform used.
The second step is to be liberal with what your API accepts. Adam says don’t expect all fields to be set correctly in requests. Use sensible defaults where the client forgot or didn’t bother to give informative answers. That means accepting null values and empty strings where possible and dealing with unknown objects, ignoring them if needs be.
Step three is key to scalable development. Only create a new API version when you really have to. You can add new stuff to the current version if it doesn’t affect existing clients. So, for example, if you’re just adding a few new fields to the existing response, there’s no need to update the API version. Clients will just ignore these new fields if they have to. Only update the version when the new changes affect your clients in a clear way.
The fourth thing adam recommends is to not return primitive values as objects. Return dictionary objects with only one field instead. In this way, if you want to return something in addition to the primitive value, you won’t need a new API version. You can just add a new field to the existing dictionary.
Step five is that when you update an object in the database in response to a client request, do not replace the object. What can happen is that the object the client sends may lack fields present in the database object. These fields get lost if you simply use swap out the currently stored object with what the client sent.
Step six, don’t mess with ids. Clients should only store and pass around ids. Don’t build structure into them that your client will then depend on, since you might want to change the db structure and then you’ll break the client’s code since he depended on your id being formed in a certain way.
Step seven is to prepare for phasing out an API version. Some old versions you can’t afford to maintain. So define a process for informing clients that you may later not support their version.
Finally, step eight is that you should try to automate as much as you can.