Rest API Versioning support

Hi Team,
I need to implement the API versioning. we thought of using accept media type to differentiate api versions.
I am using mux gorilla router. how can i send dynamically incoming request to appropriate handler based on media type version?

Thanks in advance!

Gorilla Mux can match on HTTP headers:

r := mux.NewRouter()
// ...
r.Headers("X-Requested-With", "XMLHttpRequest")

So you could match on the Accept header which contains the versioned MIME type.

1 Like

Alternatively you could use multiple routers (one for reaching API version) and write a single http handler that determines version and picks the correct router to use. Both sound like good options depending on your use case.

@lutzhorn In my case i have two versions and based on that i want to dynamically route to handler function.

Also, i tried giving two values for same header accept. at run time it take the last value and rejects the first assigned value.

Is it still possible with one router or i need to create 2 routers and based on version call the appropriate handler like @joncalhoun mentioned.

You do not NEED to create 2 routers. Check out the docs and the Headers() method that @lutzhorn mentioned and you should see how it all works. I simply meant that it might be easier to design that way if you were dealing with many versions.

Why do you do that? A HTTP client must not specify the Accept header more than once for a HTTP request. It can specifiy multiple accepted content types:

// Multiple types, weighted with the quality value syntax:
Accept: text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8

See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept for more.

@lutzhorn i got your point that we can specify multiple values at once. i tried giving the value to the route 2 ways mentioned below:

router.Methods(route.Method).Path(route.Pattern).Name(route.Name).Handler(handler).Headers(
headerAccept, “application/test-0.1+json application/test-0.2+json”)

or,
router.Methods(route.Method).Path(route.Pattern).Name(route.Name).Handler(handler).Headers(
headerAccept, “application/test-0.1+json, application/test-0.2+json”)

It failed each time.

Headers do match the header pair value for each incoming request and accept/reject accordingly but there is no way to pass the request to appropriate handler func.

I am thinking to check the version in the handler method and pass the request to different version handler from there. though it is very ugly way.

Aas far as I understand Mux, r.Headers must specify one header value to match. See https://github.com/gorilla/mux/blob/master/route.go#L206 for an example.

If you want to match many header values, you should try r.HeadersRegexp. See https://github.com/gorilla/mux/blob/master/route.go#L231.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.