Skip to content

Handling Requests

Chris Kent edited this page May 29, 2019 · 23 revisions

There are two distinct parts to the definition of an endpoint.

The first part defines the route, for example get("/foo"). This defines an endpoint at the path /foo that responds to GET requests.

The second part is the code that gets executed when a request is received. This is the block passed to the get function:

get("/foo") { req ->
    // Code in here is executed when a request is received for the endpoint
}

This code block is referred to as the "handler". A handler block has a single parameter, normally called req. This is a Request object and it contains the data provided by the caller that made the HTTP request. It contains:

  • Request Headers
  • Path parameters
  • Query string parameters
  • The request body (for POST and PUT requests)

Request Parameters

A request contains three types of parameters - headers, path parameters and query string parameters. These are all instances of the Params class which is a wrapper around a Map<String, String> that provides some convenience functions.

Parameters can be looked up using the normal map lookup syntax:

val contentType = req.headers["Content-Type"]

This lookup is case-insensitive in accordance with the HTTP spec. If a parameter is not found with the specified name then an IllegalArgumentException is thrown. This is automatically translated to a response with a status of 400 (bad request).

If a parameter is optional it can be looked up using the Params.optional function:

val contentType = req.headers.optional("Content-Type")

If there is no parameter found with the specified then null is returned.

Request Headers

Request headers are available via the property Request.headers.

Path Parameters

Route definitions can include variable segments - sections of the route that match any value and whose value is available to the handler. These are available via the property Request.pathParams. For example, consider the route:

/customers/{customerId}/orders/{orderId}

This contains two variable segments, customerId and orderId. The path parameters in any request matching the route will contain values for the variables customerId and orderId. For example, if a request is made to the path

/customers/123/order/789

the path parameters can be obtained like this:

get("/customers/{customerId}/orders/{orderId}") { req ->
    val cId = req.pathParams["customerId"] // cId will be 123
    val oId = req.pathParams["orderId"]    // oId will be 789
    ...
}

Query String Parameters

GET requests can contain query string parameters - name / value pairs appended to the request path. These are available via the property Request.queryParams. The path

/foo?bar=123&baz=789

contains two query string parameters, bar and baz.

get("/foo") { req ->
    val bar = req.queryParams["bar"] // bar will be 123
    val baz = req.queryParams["baz"] // baz will be 789
    ...
}

Request Body

Requests with a method of POST or PUT normally contain a body containing data, for example a JSON object or an image. This is available via the property Request.body. The type of Request.body is Any?, i.e. it can be any type and may be null. In practice, it will be:

  • null - if the request did not include a body
  • String - if the request included a body that is not binary data
  • ByteArray - if the request included a body containing binary data
  • Something else - if a filter has decoded the body into an object

Binary MIME Types

If you want to pass binary data to your endpoints in you must tell API Gateway which MIME types should be treated as binary. This is done using the binaryMimeTypes property of API definition.

Clone this wiki locally