Handler Options

Context

accepts

Added in 0.0.0.

Content negotiation support for the request. Provided by the accepts package. This property is lazily instantiated on access.

Example use:

myHandler.route = 'GET /foo'
function myHandler(context) {
  switch (context.accepts.type(['json', 'html'])) {
    case 'json':
      return {'hello': 'world'}
    case 'html':
      const res = Buffer.from(`<h1>hello world</h1>`)
      res[Symbol.for('headers')] = {
        'content-type': 'text/html'
      }
      return res
    default:
      // default to text/plain
      return 'hello world'
  }
}

body

Added in 0.0.0.

A promise for the parsed contents of the request body. Will either return a JavaScript object on success or throw a 422 Unprocessable Entity error when no body parser could handle the request body.

See "accepting user input" for more.

Example use:

myHandler.route = 'POST /foo'
async function myHandler(context) {
  const body = await context.body
  // do something with the body
  if (body.flub) {
    return body.blarp
  }
}

Added in 0.1.1.

A specialized Map instance allowing access to HTTP Cookie information. .cookie supports .get, .set, .delete, .has, and all other Map methods.

.cookie maps cookie names (as strings) to cookie configurations:

{ httpOnly: Boolean, # defaults to true
  expires: Date,
  maxAge: Number,
  secure: Boolean, # defaults to true in production, false in development mode
  sameSite: true,  # defaults to true
  value: String
}

This configuration information is passed to the cookie package in order to create Set-Cookie headers for outgoing responses.

The state of the cookie map is tracked; if any values are changed (or deleted), Boltzmann will automatically generate and attach a Set-Cookie header to responses.

Incoming cookies don't contain enough information to recreate fields other than .value, so those values will be synthesized with defaults.

Example use:

logout.route = 'POST /foo'
async function logout(context) {
  const { value } = context.cookie.get('sessionid') || {}
  if (value) {
    cookie.delete('sessionid')
  }
}

const uuid = require('uuid')

login.route = 'POST /login'
async function login(context) {
  const {username} = await context.body
  const id = uuid.v4()
  context.redisClient.set(id, username)

  context.cookie.set('sessionid', {
    value: username,
    maxAge: 60 // 1 minute! HOW VERY SECURE
  })
}

headers

Added in 0.0.0.

The HTTP Request Headers as a plain JavaScript object.

This forwards the Node.JS request headers object. All headers will be lower-cased and follow the concatenation rules for repeated headers listed in the linked document.

Example use:

logout.route = 'GET /'
async function logout(context) {
  return context.headers['content-type']
}

host

Added in 0.0.0.

The hostname portion of the Host request header, minus the port. Note that this is the Host header received by the Node.JS process, which may not be the same as the requested host (if, for example, your Boltzmann application is running behind a reverse proxy such as nginx.)

Example use:

host.route = 'GET /'
async function host(context) {
  return context.host // "localhost", if running locally at "localhost:5000"
}

id

Added in 0.0.0.

A unique string identifier for the request for tracing purposes. The value will be drawn from:

  1. x-honeycomb-trace
  2. x-request-id
  3. A generated ship name from Iain M Bank's Culture series (e.g.: "ROU Frank Exchange Of Views")

Example use:

const bole = require('bole')

log.route = 'GET /'
async function log(context) {
  const logger = bole(context.id)
  logger.info('wow what a request')
}

method

Added in 0.0.0.

The HTTP verb associated with the incoming request, forwarded from the underlying node request object.

Example use:

const assert = require('assert')

assertion.route = 'GET /'
async function assertion(context) {
  assert.equal(context.method, 'GET')
}

params

Added in 0.0.0.

context.params contains an object mapping URL parameter names to the resolved value for this request. Wildcard matches are available as context.params['*'].

Example use:

parameters.route = 'GET /:foo/bar/:baz'
async function parameters(context) {
  console.log(context.params) // { "foo": "something", "baz": "else" }
}

postgresClient

Added in 0.0.0. Requires the --postgres feature.

A lazily-acquired Promise for a postgres Client. Once acquired the same postgres connection will be re-used on every subsequent access from a given Context object.

When accessed from a handler responsible for unsafe HTTP methods, the connection will automatically run as part of a transaction. For more, read the "persisting data" chapter.

Example use:

postgres.route = 'GET /users/:name'
async function parameters(context) {
  const client = await context.postgresClient
  const results = await client.query("select * from users where username=$1", [context.params.name])
}

query

Added in 0.0.0.

query contains the URL search (or "query") parameters for the current request, available as a plain javascript object.

If context.url is set to a new string, context.query will be re-calculated.

Warning: Duplicated querystring keys are dropped from this object; only the last key/value pair will be available. If you need to preserve exact querystring information, use context.url.searchParams, which is a URLSearchParams object.

Example use:

queries.route = 'GET /'
async function queries(context) {
  if (context.query.foo) {
    // if you requested this handler with "/?foo=1&bar=gary&bar=busey",
    // you would get "busey" as a result
    return context.query.bar
  }
}

redisClient

Added in 0.0.0. Requires the --redis feature.

A handy-redis client attached to the context by middleware. A single client is created for the process and shared between request contexts.

Example use:

redis.route = 'GET /'
async function redis(context) {
  const [ok, then] = await context.redisClient.hmget('wow', 'ok', 'then')

  return { ok, then }
}

remote

Added in 0.0.0.

The remote IP address of the HTTP request sender. Drawn from request.socket.remoteAddress, falling back to request.remoteAddress. This value only represents the immediate connecting socket IP address, so if the application is served through a CDN or other reverse proxy (like nginx) the remote address will refer to that host instead of the originating client.

Example use:

remote.route = 'GET /'
async function remote(context) {
  console.log(context.remote) // 127.0.0.1, say
}

start

Added in 0.0.0.

A Number representing the start of the application request processing, drawn from Date.now().

Example use:

timing.route = 'GET /'
async function timing(context) {
  const ms = Date.now() - context.start
  return `routing this request took ${ms} millisecond${ms === 1 ? '' : 's'}`
}

url

Added in 0.0.0.

A URL instance populated with the host header & incoming request path information. This attribute may be set to a String in order to recalculate the url and query properties.

Example use:

uniformResourceLocation.route = 'GET /'
async function uniformResourceLocation(context) {
  console.log(context.url.pathname) // "/"

  context.url = '/foo/bar?baz=blorp'
  console.log(context.url.pathname) // "/foo/bar"
  console.log(context.query.baz) // "blorp"
}

Response Symbols

Symbol.for('headers')

Symbol.for('status')

Symbol.for('template')

Symbol.for('threw')

Response Transforms

"strings"

undefined, empty return

Node.JS Streams

JavaScript objects

Thrown errors