10.1.4 Versioning REST resources - Reference Documentation
Authors: Graeme Rocher, Peter Ledbrook, Marc Palmer, Jeff Brown, Luke Daley, Burt Beckwith, Lari Hotari
Version: 3.1.3
10.1.4 Versioning REST resources
A common requirement with a REST API is to expose different versions at the same time. There are a few ways this can be achieved in Grails.Versioning using the URI
A common approach is to use the URI to version APIs (although this approach is discouraged in favour of Hypermedia). For example, you can define the following URL mappings:"/books/v1"(resources:"book", namespace:'v1') "/books/v2"(resources:"book", namespace:'v2')
package myapp.v1class BookController { static namespace = 'v1' }package myapp.v2class BookController { static namespace = 'v2' }
Versioning with the Accept-Version header
As an alternative Grails supports the passing of anAccept-Version
header from clients. For example you can define the following URL mappings:"/books"(version:'1.0', resources:"book", namespace:'v1') "/books"(version:'2.0', resources:"book", namespace:'v2')
Accept-Version
header:$ curl -i -H "Accept-Version: 1.0" -X GET http://localhost:8080/books
Versioning using Hypermedia / Mime Types
Another approach to versioning is to use Mime Type definitions to declare the version of your custom media types (see the section on "Hypermedia as the Engine of Application State" for more information about Hypermedia concepts). For example, inapplication.groovy
you can declare a custom Mime Type for your resource that includes a version parameter (the 'v' parameter):grails.mime.types = [ all: '*/*', book: "application/vnd.books.org.book+json;v=1.0", bookv2: "application/vnd.books.org.book+json;v=2.0", … }
It is critical that place your new mime types after the 'all' Mime Type because if the Content Type of the request cannot be established then the first entry in the map is used for the response. If you have your new Mime Type at the top then Grails will always try and send back your new Mime Type if the requested Mime Type cannot be established.Then override the renderer (see the section on "Customizing Response Rendering" for more information on custom renderers) to send back the custom Mime Type in
grails-app/conf/spring/resourses.groovy
:import grails.rest.render.json.* import grails.web.mime.*beans = { bookRendererV1(JsonRenderer, myapp.v1.Book, new MimeType("application/vnd.books.org.book+json", [v:"1.0"])) bookRendererV2(JsonRenderer, myapp.v2.Book, new MimeType("application/vnd.books.org.book+json", [v:"2.0"])) }
class BookController extends RestfulController { static responseFormats = ['json', 'xml', 'book', 'bookv2'] // … }
Accept
header you can specify which version you need using the Mime Type:$ curl -i -H "Accept: application/vnd.books.org.book+json;v=1.0" -X GET http://localhost:8080/books