During last week I had been working on bringing the concept of Media Type Versioning (you can find more about it here or here) to Angular in a form of flexible and reusable $http interceptor. I had been working on project that havily relayed on microservice architecture build with help of NetflixOSS and Spring Cloud in particular. We had decided to expose the internal services (mostly REST API) through bunch of edge gateways and this is were the fun part begins. Generally we have though that it would be good idea to version our API through uri i.e: /api/v1/billings. This works preatty well, especially if you consider that you can have a proxy setup that auto discovers the services for specific version and routes the trafic towards them.
But our systems have also a single web page frontend in which we have faced some practical problem. From the whole begining whenever we were considering to consume our API we have though that having request in form of:
would be a bad idea and will not going to be so much maintainable. Having ‘hardcoded’ the API version in every possible AJAX request would require a lot of changes in cases that we would decide to release a new one. Of course a simple trick could be done to overcome that, for instance we could use only the
/api/ part of the url – without any version information and perform url rewriting either on the client side or on the server side. In fact this is exactly what we have done with one extra addition. We wanted to preserve the information of the version send by the client, but not in form of hardcoded url. This is when we have decided that for purpose of our UI interface we are going to shift from Uri based versioning towards Media Type versioning – in the same time all of the routing will be done on the server side.
As a aid for this idea I have prepared an Angular module:
A plugin that will be flexible and trasparent in the same time. As a result in entire application we don’t use any vendor specific information or versions. Just standard MIME types like:
application/json or even realy on the defaults of the $resource and $http objects. All the details of the transformation is being handled through the $http interceptor registerd by angular-vendor-media-type plugin.
What it does exactly?
It transforms the media types and by transforming I don’t mean simple subsitution. The interceptor will parse the outgoing
Content-Type headers and alter them with configured vendor information. So any additional parameters like for instance
q=0.8 will remain intact. In this way your JSON API call will be modified from
application/vnd.app.v1+json. In this approach we still need the server side part that will route that request toward the right endpoint and the exact details how this has been acomplish may deserve a seperate blog post.