Errata

Learning Ratpack

Errata for Learning Ratpack

Submit your own errata for this product.

The errata list is a list of errors and their corrections that were found after the product was released.

The following errata were submitted by our customers and have not yet been approved or disproved by the author or editor. They solely represent the opinion of the customer.

Color Key: Serious technical mistake Minor technical mistake Language or formatting error Typo Question Note Update

Version Location Description Submitted by Date submitted
ePub Page n/a
Example 2-20

Not sure what the page numbers is because of electronic format.

The example does not add the UserAgentVersioningHandler to the registry, so the /api endpoint is unable to find the referenced class. Simply adding the following code will fix the error:

bindings {
add(new UserAgentVersioningHandler())
}

Michael Black  Apr 21, 2017 
ePub Page na
Example 2-20

The example does not add the UserAgentVersioningHandler to the registry, so the /api endpoint is unable to find the referenced class.

Simply adding the following code did NOT fix the error for me - though it seemed to have worked for Michael Black (see other errata)

bindings {
add(new UserAgentVersioningHandler())
}

INSTEAD, modifying the example as follows worked:

//get(new UserAgentVersioningHandler()) // this 'get' does not work - it should be 'all'
all(new UserAgentVersioningHandler()) // use this 'all' instead of 'get'

Anonymous  Aug 12, 2020 
1
Example 2-11. Listing 2.10

Example 2-11. Listing 2.10

fail to run

but if you change line 11:
handler {
for:
all {

everything its ok again.

Andres Usera  Feb 11, 2016 
PDF Page 13
2nd paragraph

Replace all references to Groovy enVironment Manager with Software Development Kit Manager.

Replace all references to GVM with SDKMAN.

Replace all references to gvm with sdk.

DanMcHarness  Oct 20, 2015 
PDF Page 32
Example 2-13. Listing 2.12

import ratpack.form.Form
import static ratpack.groovy.Groovy.ratpack
ratpack {
handlers {
handler {
byMethod {
get {
render "Hello World!"
}
post {
Form form = parse(Form)
render "Hello ${form.data}"
}
}
}
}
}

This does not work. I had to change 'handler' to 'all'

Mark Thomas  Mar 08, 2016 
PDF Page 33
Example 2-15. Listing 2.14

The listing does not work.

import ratpack.form.Form
import static ratpack.groovy.Groovy.ratpack
ratpack {
handlers {
prefix("api") {
handler {
byMethod {
get {
render "Hello World!"
}
post {
Form form = parse(Form)
form.get
render "Hello ${form.data}"
}
}
}
}
}
}

I get the following error:

Caught: groovy.lang.MissingMethodException: No signature of method: example14.handler() is applicable for argument types: (example14$_run_closure1$_closure2$_closure3$_closure4) values: [example14$_run_closure1$_closure2$_closure3$_closure4@5edf2821]

Mark Thomas  Mar 08, 2016 
PDF Page 33
Example 2-15. Listing 2.14

1) What's the difference between prefix('api') and path('api')?

2) The only way I could get the code to work was with:

@Grab('io.ratpack:ratpack-groovy:1.2.0')

import ratpack.form.Form
import static ratpack.groovy.Groovy.ratpack

ratpack {
handlers {
path('api') {
byMethod {
get {
render 'Hello World!'
}
post {
parse(Form).then {
render it.name
}
}
}
}
}
}

Mark Thomas  Mar 08, 2016 
PDF Page 34
Example 2-16. Listing 2.15

The only way I could get the code to work was to modify:


@Grab('io.ratpack:ratpack-groovy:1.0.0')
import ratpack.form.Form
import static ratpack.groovy.Groovy.ratpack
ratpack {
handlers {
path('api') {
byMethod {
get {
def content = 'This is my content'
byContent {
json {
render "{\"content\": \"$content\"}"
}
xml {
render "<content>$content</content>"
}
html {
render "<!DOCTYPE html><html><body>$content</body></html>"
}
plainText {
render content
}
noMatch {
render "I have no clue what you wanted from me."
}
}
}
post {
parse(Form).then {
String data = it.data
byContent {
json {
render "{\"message\": \"Received $data\"}"
}
xml {
render "<message>Received $data</message>"
}
html {
render "<!DOCTYPE html><html><body>Thank you for submitting $data</body></html>"
}
plainText {
render data
}
noMatch {
render 'I have no clue what you wanted from me.'
}
}
}
}
}
}
}
}

Mark Thomas  Mar 08, 2016 
PDF Page 40
Example 2-20. Listing 2.19

I just couldn't get this listing to work. In-the-end I rewrote it using a bespoke 'Version' header.

@Grab('io.ratpack:ratpack-groovy:1.2.0')
import ratpack.handling.Context
import ratpack.handling.Handler
import ratpack.registry.Registry
import static ratpack.groovy.Groovy.ratpack
import static ratpack.jackson.Jackson.json

class UserAgentVersioningHandler implements Handler {

private static final String ERROR_MSG = 'Unsupported Version'

enum ClientVersion {
V1('Microservice Client v1.0'),
V2('Microservice Client v2.0'),
V3('Microservice Client v3.0')

String versionString

ClientVersion(String versionString) {
this.versionString = versionString
}

static ClientVersion fromString(String versionString) {
for (val in values()) {
if (val.versionString == versionString) {
return val
}
}
null
}
}

@Override
void handle(Context context) {
def userAgent = context.request.headers.'Version' // (1)
def clientVersion = ClientVersion.fromString(userAgent)
if (!clientVersion) {
renderError(context)
} else {
println clientVersion
context.next(Registry.single(clientVersion)) // (2)
}

}

private static void renderError(Context context) {
context.response.status(400)
context.byContent { spec -> spec
.json({context.render(json([error: true, message: ERROR_MSG]))})
.html({context.render("<h1>400 Bad Request</h1><br/><div>${ERROR_MSG}</div>")})
.noMatch({context.render(ERROR_MSG)})
}
}
}

ratpack {
handlers {
prefix('api') {
all new UserAgentVersioningHandler()

all { UserAgentVersioningHandler.ClientVersion clientVersion ->
if (clientVersion == UserAgentVersioningHandler.ClientVersion.V1) {
render 'V1 Model'
} else if (clientVersion == UserAgentVersioningHandler.ClientVersion.V2) {
render 'V2 Model'
} else { // it must be V3 at this point, since the versioning
render 'V3 Model' // handler has figured out the request qualifies
}
}
}
}
}

Mark Thomas  Mar 08, 2016