API Versioning – Using Date Released

While browsing Hacker News one day, my favorite news site, I came across Stripes versioning blog post. This was not the first time I had come across the idea of using dates to version your APIs, but this time I decided to give it a try.

Some Background

I’ve commonly seen others suggest simply putting version numbers in the URL to segregate major changes. This can work, but how often are major changes made to your API?

In my experience changes are typically updates to some of the returned data, or additional parameters required for precision. These are small changes but not always backward compatible.

If this happens somewhat often, you’ll be supporting many different versions simultaneously. Not only that, you’ll need to duplicate API endpoints that haven’t changed just to be part of these new versions.

Instead of duplicating the entire API to make some small changes, there is a way of just adding changes to the single endpoint. The following is mainly a proof of concept, but with some modifications it could definitely be a solution.

Using Dates to Access API Versions

So finally, I’ll get right to it. By utilizing the flexibility of the HTTP header we can send the date which our client is able to support. This is done by adding an API-Header with a value of let’s say ‘2017-02-10’.

By sending this date in the header, you’re saying that your client is compatible with all revisions prior to and including this date. If your client will always be up to date, simply use today’s date as the value.

Routing to Specific Versions of APIs

So now that you understand the client side, I’ll explain a little how the API routes the request. Express allows you to create multiple routers with different prefixes. The goal is to generate new routes based on timestamps of when the changes were done.

There is middleware in the express server that extracts the API-Version header value and converts it to a timestamp. The middleware then uses this timestamp to reroute the request to the version compatible with the timestamp. The following image will hopefully help explain.

Example of API Date Versioning Routing

You may be thinking, what happens when you release versions that don’t include changes to each endpoint. Well, in the same middleware the routing take place, it actually loops through the endpoints to find a matching url, such as ‘fn1’. The routers are obviously sorted in ascending order to match the latest one with the requested API version. But this way, if a version was not updated in the latest release that was requested, the latest updated version will be used.

It may be easier for some just to look at the code, so I’ve put together a quick project and threw it on GitHub. Check out my date-version-api project on GitHub. Let me know what you think.

API Blueprint – Mock Server

Mock Servers from API Specifications

Last week I mentioned an API specification called API Blueprint. Turns out not only does this allow us to document our API, but also use it.

That’s right, create a functioning mock server from that same API Blueprint used to document your API. I did mention this a bit in my previous post but I thought I’d put together a quick example.

Install Drakov

sudo npm install -g drakov

I just grabbed the Polls API example from the blueprint examples.

I renamed the file to have a .apib extension. Run drakov like the following:

drakov -f PollsAPI.apib

Now you can access a mock server to test your front end code with! See the picture below for example.

api-mock-server-drakov

Drakov Tips

If you’re running the mock server on a different host and from a browser, be sure to enable  OPTIONS. To do this use the –autoOptions argument. This is because when the browser is accessing another host it will send a pre-flight OPTIONS request to see if the intended request is allowed. This bit me when creating my first NodeJS Express applications, I will always remember, vividly.

Use Notepad++ to find and replace tabs in your API Blueprint. Drakov can’t parse blueprints with tabs 🙁 .

 

Modular Node.JS Application Programming

Modular Node.JS application programming has a number of benefits. You can isolate smaller portions of the application for packaging and testing. You can create small specialized packages to use with different hardware or peripherals.

One example I’ve used this approach with is microservices. Spinning up an unknown (to the application) amount of express servers.

In the following example I will show you how to create a simple helper module to import all modules within a specified folder. These modules can basically be anything you want as long as they’re contained in their own folders. It will help if all Node.JS modules contain a common function to initialize them.

The image below is the file structure I use for modular Node.JS applications.

Modular Node.JS File Structure

Let’s See the Source for Our Modular Node.JS App!

The following code block is libraryLoader.js:

So let’s quickly pick this apart. The function we will be calling from the main script of the application starts on line 23. I’ve separated the getLibraryDirectories defined on line 13 just to keep things clean.

In our main function, line 25, is simply using Node.JS’ path module to join a file path’s starting point, path to the directory, the operating systems separating character, then the directory itself.

Next, line 26, we use this full path to obtain the names of each directory in the target folder, they are stored in an array.

Line 28 is where the magic happens. For each item in the previously mentioned array of directory names, we import that folder and pass in an object to store it’s structure. This works because if you look at the file structure I provided earlier, modules in the lib folder have an index.js file. When importing, Node.JS will try and reference an index.js file in that directory if a file is not given.

Once the loop is complete, the filled libraries object is returned to whatever had called it.

I’ll now show you a small example of one of these modules in the lib folder to show how the libraries are added to the object.

The following code block is all the source located in index,js, the file I mentioned earlier that is invoked when a directory is imported.

This is extremely simple and only created for example purposes.

The passed in libraries object during the require can be seen on line 7. Node.JS will send a reference to that object which will include a reference to functions located in the app.js. In this case init(). According to Stack Overflow this is called square bracket notation.

A matching function can be found in Module1 and you’ll see why that is important shortly.

The following code block is app.js of the root of the application. This is where the libraryLoader helper will be called.

The usage is actually quite simple.

As you can see on line 9 is where we load all the libraries or modules and store them in a single object. This object contains keys which match the directory names located in the lib folder.

The parameters are:
__dirname – The current directory to start the path
‘.’ – A single dot to tell the function the directory is within the current location
‘lib’ – The directory name we’re looking for is lib, so each module will have to be contained in a folder within lib

Line 10 is just a simple example of how to call functions in all loaded modules. In most cases I will have an init function in all modules to set up loggers and configurations.

I’ll upload the source to Github shortly. Please let me know if you have any questions or comments!

Edit: I’ve finally uploaded the source to GitHub!