Kurro Lopez · Oct 30, 2019

API RESTful Version


We need to create a versioning of an existing API, so we going to set a default version (so far) for current connections to version 1

My first attempt is:

XData UrlMap [ XMLNamespace = "" ]
    <Route Url="(?i)/check" Method="GET" Call="CheckApi"/>
    <Route Url="(?i)/getcustomer" Method="POST" Call="GetCustomerDefault"/>
    <Route Url="(?i)/revoke" Method="DELETE" Call="RevokeDefault"/>
    <Route Url="(?i)/:version/getcustomer" Method="POST" Call="GetCustomer"/>
    <Route Url="(?i)/:version/revoke" Method="DELETE" Call="Revoke"/>
/// Get customer info (API version default)
ClassMethod GetCustomerDefault() As %Status
    quit ..GetCustomer(..#DEFAULTVERSION)
ClassMethod GetCustomer(pVersion As %IntegerAs %Status
    // This is the code for all version. Get the Id and pass into the message
    quit $$$OK


Also, I have a parameter called DEFAULTVERSION with value 1

By this way, the newer calls will have the version number and response according the version of API

The URL will be:

I'm checking if the version is less than a CURRENTVERSION, the call is fine

According to a new especification, the URL will be "api/v2/getCustomer", before it was an integer, and now will be a string.


How can I check if this parameter is well formed (v and number), then I can evaluate if the number is an valid API version?


We can change our versioning, so any suggest will be welcome

0 272
Discussion (5)3
Log in or sign up to continue

I would do something like this.

if pVersion?1"v"1n.n {

     // Parameter is well formed vnnn

} else {

     // Parameter is not well formed


It's just I need... By this way, I have the version number

Many thanks

Good approach, thanks for your answer.

The methods will be exactly the same as before. The changes in version is a slight change in BP, so I need which version is calling. If I user the version number as parameter, I can add into a message and calls to BP with the version and not replay all methods for each version.

I'll be in mind for future versions.


Approach 1

I would be tempted to have your Dispatch class have a forwarding rule for the API version eg v1 or v2 and this will help ensure a clear hierarchical separation both in the URL and in the class definitions between versions. You might also be interested in the %request.URL property for checking relative paths. An example based on your route map might look like 

<Map Prefix="/v1/customer" Forward="MyApp.APIVersion1.Customer" />
<Map Prefix="/v2/customer" Forward="MyApp.
APIVersion2.Customer" />

And your class MyApp.APIVersion1.Customer might look like

        <Route Url="/getcustomer" Method="Post" Call="GetCustomer" />

Personally, I like the classmethod names to reflect the HTTP Method so if I see a GetCustomer method I know that's a HTTP Get method but this is based on personal preference and convention rather than a rule.

Approach 2

The alternative approach is to have everything in the same class but over time this may cause your classes to be rather bloated and unwieldy

<Map Prefix="/v1/customer" Method="Post"  Call="GetCustomerV1" />
<Map Prefix="/v2/customer" Method="Post"  Call="GetCustomerV2" />

Other Thoughts

I do not know if there's a specific function that can be called prior the classmethod in the route map that can validate or invalidate routes. Perhaps the OnPreHTTP method could be used? I noted that some of your methods had the word "default" in them. You can define default route as "/" in your route map.