restful services in grails
DESCRIPTION
Speaker: Ken Kousen G&G Special Topics Grails 2.3 added greatly enhanced REST capabilities to the framework. Now it is possible to expose RESTful endpoints directly from domain classes, or extend a RestfulController superclass, and customize rendering much more easily than before. Even the HAL specification for hypermedia is now supported. This talk will demonstrate the new RESTful features and show you how to take advantage of them in the future. Topics will range from using the new annotations, to building RESTful controllers, to customizing response renderers, to working with hypermedia, and more.TRANSCRIPT
![Page 1: Restful Services in Grails](https://reader033.vdocument.in/reader033/viewer/2022052601/559444aa1a28ab01308b47f1/html5/thumbnails/1.jpg)
© 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission.
Restful Grails
Kenneth Kousen@kenkousen
![Page 3: Restful Services in Grails](https://reader033.vdocument.in/reader033/viewer/2022052601/559444aa1a28ab01308b47f1/html5/thumbnails/3.jpg)
RESTTerm from Ph.D. thesis by Roy Fielding
Co-founder Apache HTTP Server projectPart of IETF working groups for:
URI, HTTP, HTML
Architectural Styles and the Design ofNetwork-based Software Architectures
![Page 4: Restful Services in Grails](https://reader033.vdocument.in/reader033/viewer/2022052601/559444aa1a28ab01308b47f1/html5/thumbnails/4.jpg)
REST
Representational State Transfer- Addressable resources- Uniform interface- Content negotiation- Hypermedia
![Page 5: Restful Services in Grails](https://reader033.vdocument.in/reader033/viewer/2022052601/559444aa1a28ab01308b47f1/html5/thumbnails/5.jpg)
Addressable Resources
Use URLs to access items(no verbs in URLs)
![Page 6: Restful Services in Grails](https://reader033.vdocument.in/reader033/viewer/2022052601/559444aa1a28ab01308b47f1/html5/thumbnails/6.jpg)
Uniform Interface
HTTP verbs
GET
POST
PUT
DELETE
---- HEAD
OPTIONS
PATCH
![Page 7: Restful Services in Grails](https://reader033.vdocument.in/reader033/viewer/2022052601/559444aa1a28ab01308b47f1/html5/thumbnails/7.jpg)
Safe vs Idempotent
Safe → no server side changesGET
![Page 8: Restful Services in Grails](https://reader033.vdocument.in/reader033/viewer/2022052601/559444aa1a28ab01308b47f1/html5/thumbnails/8.jpg)
Idempotent
Idempotent requests can be repeatedNo additional effects
GETPUTDELETE
![Page 9: Restful Services in Grails](https://reader033.vdocument.in/reader033/viewer/2022052601/559444aa1a28ab01308b47f1/html5/thumbnails/9.jpg)
Http Status Codes200s → good
200 OK, 201 created, 204 no content300s → moved400s → you messed up
404 not found, 409 conflict(see 418, 420 for fun)
500s → we messed up
![Page 10: Restful Services in Grails](https://reader033.vdocument.in/reader033/viewer/2022052601/559444aa1a28ab01308b47f1/html5/thumbnails/10.jpg)
RESTful service
ImplementationsGET → retrieve dataPOST → insert data
set Location header for new itemPUT → update dataDELETE → remove data
![Page 11: Restful Services in Grails](https://reader033.vdocument.in/reader033/viewer/2022052601/559444aa1a28ab01308b47f1/html5/thumbnails/11.jpg)
RESTful service
Yes, that’s a URL-driven database
![Page 12: Restful Services in Grails](https://reader033.vdocument.in/reader033/viewer/2022052601/559444aa1a28ab01308b47f1/html5/thumbnails/12.jpg)
RESTful service
Yes, that’s a URL-driven database
(Hypermedia advocates are squirming,but we’ll get there)
![Page 13: Restful Services in Grails](https://reader033.vdocument.in/reader033/viewer/2022052601/559444aa1a28ab01308b47f1/html5/thumbnails/13.jpg)
Content Negotiation
Client can request representations
Usually via MIME typein Accept header
![Page 14: Restful Services in Grails](https://reader033.vdocument.in/reader033/viewer/2022052601/559444aa1a28ab01308b47f1/html5/thumbnails/14.jpg)
Stateless Services
No state maintained in service
All interactions via self-contained requests
![Page 15: Restful Services in Grails](https://reader033.vdocument.in/reader033/viewer/2022052601/559444aa1a28ab01308b47f1/html5/thumbnails/15.jpg)
HATEOAS
HypermediaAsTheEngineOfApplicationState
An unpronounceable acronymwith the word HATE in it
![Page 16: Restful Services in Grails](https://reader033.vdocument.in/reader033/viewer/2022052601/559444aa1a28ab01308b47f1/html5/thumbnails/16.jpg)
Hypermedia
Goal is true decouplingClient asks for first URLResponse includes links
Works like the web, but programmatically
![Page 17: Restful Services in Grails](https://reader033.vdocument.in/reader033/viewer/2022052601/559444aa1a28ab01308b47f1/html5/thumbnails/17.jpg)
Grails
REST support in 2.2 and earlier
render Person as JSON
render Person.list() as JSON
![Page 18: Restful Services in Grails](https://reader033.vdocument.in/reader033/viewer/2022052601/559444aa1a28ab01308b47f1/html5/thumbnails/18.jpg)
Grails
REST support in 2.2 and earlier
request.withFormat {
xml { render p as XML }
json { render p as JSON }
html p
}
![Page 19: Restful Services in Grails](https://reader033.vdocument.in/reader033/viewer/2022052601/559444aa1a28ab01308b47f1/html5/thumbnails/19.jpg)
Grails
REST support in 2.2 and earlier
render(contentType:'application/json') {
person(first: p.firstName,
last: p.lastName)
}
![Page 20: Restful Services in Grails](https://reader033.vdocument.in/reader033/viewer/2022052601/559444aa1a28ab01308b47f1/html5/thumbnails/20.jpg)
respond
Grails 2.3+ adds respondreplies with proper Mime typeuse Accept: header or file extension
![Page 21: Restful Services in Grails](https://reader033.vdocument.in/reader033/viewer/2022052601/559444aa1a28ab01308b47f1/html5/thumbnails/21.jpg)
respond
// pick the best content type to respond withrespond Book.get(1)
// pick type from the given formatsrespond Book.get(1), [formats:['xml', 'json']]
![Page 22: Restful Services in Grails](https://reader033.vdocument.in/reader033/viewer/2022052601/559444aa1a28ab01308b47f1/html5/thumbnails/22.jpg)
@Resource
Annotation grails.rest.Resourceexposes domain class as REST resource
Works even if there is no controller (!)
![Page 23: Restful Services in Grails](https://reader033.vdocument.in/reader033/viewer/2022052601/559444aa1a28ab01308b47f1/html5/thumbnails/23.jpg)
@Resource
Can specify URI, butbetter done in UrlMappings config
![Page 24: Restful Services in Grails](https://reader033.vdocument.in/reader033/viewer/2022052601/559444aa1a28ab01308b47f1/html5/thumbnails/24.jpg)
@Resource
Default MIME types are defined inConfig.groovy
![Page 25: Restful Services in Grails](https://reader033.vdocument.in/reader033/viewer/2022052601/559444aa1a28ab01308b47f1/html5/thumbnails/25.jpg)
@Resource
Optional attributes: uri, formats
![Page 26: Restful Services in Grails](https://reader033.vdocument.in/reader033/viewer/2022052601/559444aa1a28ab01308b47f1/html5/thumbnails/26.jpg)
UrlMappings
Works best with defined mappings
"products"(resource: 'product')
![Page 27: Restful Services in Grails](https://reader033.vdocument.in/reader033/viewer/2022052601/559444aa1a28ab01308b47f1/html5/thumbnails/27.jpg)
UrlMappings
Can nest mappings
"/customers"(resource: 'customer') {
"/orders"(resource: 'order')
}
![Page 28: Restful Services in Grails](https://reader033.vdocument.in/reader033/viewer/2022052601/559444aa1a28ab01308b47f1/html5/thumbnails/28.jpg)
UrlMappings
Grails commandurl-mappings-report
![Page 29: Restful Services in Grails](https://reader033.vdocument.in/reader033/viewer/2022052601/559444aa1a28ab01308b47f1/html5/thumbnails/29.jpg)
Customize Response
Can customize existing renderersUse conf/spring/resources.groovy
Define beans using syntax:name(renderer, class)
![Page 30: Restful Services in Grails](https://reader033.vdocument.in/reader033/viewer/2022052601/559444aa1a28ab01308b47f1/html5/thumbnails/30.jpg)
Custom Renderers
Existing renderers:AtomRenderer, AtomCollectionRendererHalJsonRenderer, HalJsonCollectionRendererHalXmlRenderer, HalXmlCollectionRendererJsonRenderer, JsonCollectionRendererXmlRenderer, XmlCollectionRenderer
![Page 31: Restful Services in Grails](https://reader033.vdocument.in/reader033/viewer/2022052601/559444aa1a28ab01308b47f1/html5/thumbnails/31.jpg)
Custom Renders
Subclass AbstractRenderer<T>call super(domain) in constructorimplement render method
use a builder
![Page 32: Restful Services in Grails](https://reader033.vdocument.in/reader033/viewer/2022052601/559444aa1a28ab01308b47f1/html5/thumbnails/32.jpg)
HAL
Hypermedia Application Languagehttp://stateless.co/hal_specification.html
Spec for adding hyperlinks to JSON or XML
![Page 33: Restful Services in Grails](https://reader033.vdocument.in/reader033/viewer/2022052601/559444aa1a28ab01308b47f1/html5/thumbnails/33.jpg)
HAL
Works with MIME types:application/hal+jsonapplication/hal+xml
![Page 34: Restful Services in Grails](https://reader033.vdocument.in/reader033/viewer/2022052601/559444aa1a28ab01308b47f1/html5/thumbnails/34.jpg)
HAL
Response includes_links → links to other resources_embedded → the typical response
Other properties can be added as needed
![Page 35: Restful Services in Grails](https://reader033.vdocument.in/reader033/viewer/2022052601/559444aa1a28ab01308b47f1/html5/thumbnails/35.jpg)
HAL
Use built-in HAL renderersHalJsonRendererHalXMLRenderer
Similar for collections
![Page 36: Restful Services in Grails](https://reader033.vdocument.in/reader033/viewer/2022052601/559444aa1a28ab01308b47f1/html5/thumbnails/36.jpg)
HAL
Collection renderers can customize collectionUse collectionName property in bean def
![Page 37: Restful Services in Grails](https://reader033.vdocument.in/reader033/viewer/2022052601/559444aa1a28ab01308b47f1/html5/thumbnails/37.jpg)
HAL
Links can be added with link method def show(Order orderInstance) {
orderInstance.link rel:'customer',
href: g.link(resource:'customer',
params: [orderId: orderInstance.id])
respond orderInstance
}
![Page 38: Restful Services in Grails](https://reader033.vdocument.in/reader033/viewer/2022052601/559444aa1a28ab01308b47f1/html5/thumbnails/38.jpg)
Clients
A notes about clients:Apache HTTP Client is in JavaHttpBuilder project is a Groovy wrapper
http://groovy.codehaus.org/modules/http-builder/
Also consider Spring's RestTemplate