-
Notifications
You must be signed in to change notification settings - Fork 10
Use custom filter to enforce API versions
srfrog edited this page Aug 9, 2014
·
3 revisions
Suppose you need to enforce an API version for a resource or a specific route.
The client requests the API version via the Accept header:
~$ curl -i -X GET -H 'Accept: application/vnd.relax+json;version=1.1' https://api.company.com
Go-Relax will create a request info variable "content.version" with value of "1.1".
Now, you have two ways to enforce versions.
- Enforce within your application:
const API_VERSION "2.0"
func (r *MyResource) Read(ctx *relax.Context) {
version := ctx.Info.Get("content.version")
if version != API_VERSION && version != "current" {
ctx.Error(400, "Invalid API version")
}
ctx.Respond("OK!")
}
This works fine, but leads to writing a lot of redundant if/else code.
- Use a custom filter:
type APIVersionFilter struct {
MinVersion float64
}
func (self *APIVersionFilter) Run(next relax.HandlerFunc) relax.HandlerFunc {
if self.MinVersion == 0 {
self.MinVersion = 1.5
}
return func(ctx *relax.Context) {
if ctx.Info.Get("content.version") != "current" && ctx.Info.GetFloat("content.version") < self.MinVersion {
ctx.Error(400, "API version requested is no longer supported.")
return
}
// requested version is supported
next(ctx)
}
}
You can use the custom filter everywhere as needed:
apiver := &APIVersionFilter{MinVersion: 1.2}
myservice := relax.NewService("/api")
// for the whole service:
myservice.Use(apiver)
// or just for resource(s)
res1 := myservice.Resource(tickets, apiver)
// or just for route(s)
res1.GET("{uint:ticketid}/something", tickets.Something, apiver)
res1.PUT("work/{uint:ticketid}", tickets.Hardwork, apiver)
// super-alpha-beta API features, require version=10
apiver.MinVersion = 10.0
res1.POST("another", tickets.Another, apiver)