Versioning API Responses with Self Descriptive Messages

There was a comment posted on the HTTPAPIs slack earlier around versioning in HTTP APIs:

about the versioning thing, if my api returns like in json format something like <code>{ "name" : "Bart" }</code> my client see this and can read the name field. But, what if tomorrow I change the field "name" to "title". My client will be broken..

Now common wisdom dictates "don't break backward compatibility" - i.e. just return both name and title in your API response. Clients written when the field was called name will use name, and new ones will use title. Then, when the old clients have updated, you can remove name.

This is great if you have control over the clients, and have some strategy in place for keeping track of what 'version' the clients accessing your API are on, and some way of forcing them to update their code to a newer version. If not, you have to keep serving both name and title forever, and as you make more and more changes, your API responses (and your codebase) will get bigger and bigger.

There are other ways to tackle this. Here's one possible approach, where by building a few smarts into the client, and using self-descriptive messages, you can make your clients automatically adapt to changes.

So we've got

GET /someuri  
{ 
    "_context" : "/vocab_v1", 
    "name": "Bart" }
}

where the _context is a url containing definitions of the terms elsewhere in the document e.g.

GET /vocab_v1  
[ 
    {"id" : "name", "meaning" : "a human readable label for the item" } 
]

Then, when you want to change the name term

GET /someuri  
{ 
    "_context" : "/vocab_v2", 
    "title": "Bart" }
}


GET /vocab_v2  
[ 
    {
        "id" : "title", "meaning" : "an official human readable name for the the item", 
        "synonyms" : [ { vocab : "/vocab_v1", id: "name" ]
    } 
]

So your client, upon encountering a term it doesn't understand can access the vocab and see that the new term is a synonym for the old one.

An even smarter client could work without the synonym field, either by looking up an external, reusable "thesaurus service" and finding a match*.

An even smarter still client could work by using some ML techniques to determine the equivalency between name and title.

Both those two approaches are generic approaches and once written in a client library, can be reused.

Now you might find it tricky to guarantee that the developer codes the client to take these dynamic changes into account. How you do that is another story...

*each synonym could even have a quality value which the client can use to decide whether to accept the synonym