Restful Services in Grails
description
Transcript of Restful Services in Grails
© 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission.
Restful Grails
Kenneth Kousen@kenkousen
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
REST
Representational State Transfer- Addressable resources- Uniform interface- Content negotiation- Hypermedia
Addressable Resources
Use URLs to access items(no verbs in URLs)
Uniform Interface
HTTP verbs
GET
POST
PUT
DELETE
---- HEAD
OPTIONS
PATCH
Safe vs Idempotent
Safe → no server side changesGET
Idempotent
Idempotent requests can be repeatedNo additional effects
GETPUTDELETE
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
RESTful service
ImplementationsGET → retrieve dataPOST → insert data
set Location header for new itemPUT → update dataDELETE → remove data
RESTful service
Yes, that’s a URL-driven database
RESTful service
Yes, that’s a URL-driven database
(Hypermedia advocates are squirming,but we’ll get there)
Content Negotiation
Client can request representations
Usually via MIME typein Accept header
Stateless Services
No state maintained in service
All interactions via self-contained requests
HATEOAS
HypermediaAsTheEngineOfApplicationState
An unpronounceable acronymwith the word HATE in it
Hypermedia
Goal is true decouplingClient asks for first URLResponse includes links
Works like the web, but programmatically
Grails
REST support in 2.2 and earlier
render Person as JSON
render Person.list() as JSON
Grails
REST support in 2.2 and earlier
request.withFormat {
xml { render p as XML }
json { render p as JSON }
html p
}
Grails
REST support in 2.2 and earlier
render(contentType:'application/json') {
person(first: p.firstName,
last: p.lastName)
}
respond
Grails 2.3+ adds respondreplies with proper Mime typeuse Accept: header or file extension
respond
// pick the best content type to respond withrespond Book.get(1)
// pick type from the given formatsrespond Book.get(1), [formats:['xml', 'json']]
@Resource
Annotation grails.rest.Resourceexposes domain class as REST resource
Works even if there is no controller (!)
@Resource
Can specify URI, butbetter done in UrlMappings config
@Resource
Default MIME types are defined inConfig.groovy
@Resource
Optional attributes: uri, formats
UrlMappings
Works best with defined mappings
"products"(resource: 'product')
UrlMappings
Can nest mappings
"/customers"(resource: 'customer') {
"/orders"(resource: 'order')
}
UrlMappings
Grails commandurl-mappings-report
Customize Response
Can customize existing renderersUse conf/spring/resources.groovy
Define beans using syntax:name(renderer, class)
Custom Renderers
Existing renderers:AtomRenderer, AtomCollectionRendererHalJsonRenderer, HalJsonCollectionRendererHalXmlRenderer, HalXmlCollectionRendererJsonRenderer, JsonCollectionRendererXmlRenderer, XmlCollectionRenderer
Custom Renders
Subclass AbstractRenderer<T>call super(domain) in constructorimplement render method
use a builder
HAL
Hypermedia Application Languagehttp://stateless.co/hal_specification.html
Spec for adding hyperlinks to JSON or XML
HAL
Works with MIME types:application/hal+jsonapplication/hal+xml
HAL
Response includes_links → links to other resources_embedded → the typical response
Other properties can be added as needed
HAL
Use built-in HAL renderersHalJsonRendererHalXMLRenderer
Similar for collections
HAL
Collection renderers can customize collectionUse collectionName property in bean def
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
}
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