Exegesis controllers are functions that take in a context, and produce a result to return to the client. This is one of the simplest controllers you can write:
export function myController(context) {
const name = context.params.query.name;
return { message: `Hello ${name}` };
}
This will return the object provided as a JSONdocs response. You can return a
JSON object, a string, a buffer, or a readable stream. You can also more
explicitly set the body by setting res.body
or calling res.setBody()
,
res.json()
, or res.pureJson()
:
export function myController(context) {
const name = context.params.query.name;
context.res
.status(200)
.set('content-type', 'application/json');
.setBody({message: `Hello ${name}`});
}
Controllers can be asynchronous, supporting either callbacks or Promises:
export function myAsyncController(context, callback) {
callback(null, { message: 'Hello World!' });
}
export function myPromiseController(context) {
return Promise.resolve({ message: 'Hello World!' });
}
Controllers can, of course, also return non-JSON data:
export function myController(context) {
const name = context.params.query.name;
context.res
.status(200)
.setHeader('content-type', 'text/xml')
.setBody(`<message>Hello ${name}</message>`);
}
Note, however, that response validation will not be done if the body is not a JSON object.
Controllers are defined inside modules (.js files). In order to resolve a controller, you specify both the name of the module and the name of the function to call within the module. Here's a quick example:
openapi: 3.0.3
info:
title: Example
version: 1.0.0
paths:
"/users"
x-exegesis-controller: userController
get:
operationId: getUsers
Here, we'd find a module named "userController.js", and then we'd call
getUsers(context)
within that module.
If you have a path that takes input in multiple different formats, you can
also specify the operationId
in the MediaType object, using
x-exegesis-operationId
:
openapi: 3.0.3
info:
title: Example
version: 1.0.0
paths:
"/users"
x-exegesis-controller: userController
post:
content:
application/json:
schema: {}
x-exegesis-operationId: getUsersJson
multipart/form-data:
schema: {}
x-exegesis-operationId: getUsersMultipart
You may specify x-exegesis-controller
in any of the following:
- OpenAPI Object
- Paths Object
- Path Item Object
- Operation Object
- Media Type Object within the Operation Object's
requestBody.content[string]
.
Exegesis will start from the Media Type Object specified by a given request,
walk its way upwards to find the "closest" x-exegesis-controller
, and then
do the same for x-exegesis-operationId
. This will uniquely identify which
controller module and function to call.
-
context.req
- The Nodehttp.IncomingMessage
from Node.js. -
context.res
- AExegesis Response
object. This is very similar to ahttp.ServerResponse
, and has many functions that will be familiar if you're used to express. -
context.origRes
- This is the originalhttp.ServerResponse
from Node.js. In general you should not write directly tocontext.origRes
. Exegesis will be unable to do response validation if you write directly to the origRes object. -
context.params
- This is a{query, header, path, server, cookie}
object. Each member is an object where the keys are parameter names, and values are the parsed parameters. -
context.parameterLocations
- This is a mirror of thecontext.params
object, but instead of parameter values, this has parameter locations. (server
parameters are not preset inparameterLocations
in the current release.) -
context.requestBody
- The parsed message body, if one is present. -
context.security
- This is a dictionary where keys are security schemes, and values are{user, roles, scope}
objects (as returned by the associated authenticator). For OAS3, there will only be objects here for the first matched security requirement. -
context.user
- This is a user, as returned by an authenticator. For OAS3 this will only be present if the matched security requirement had exactly one security scheme. -
context.api
- This is an object containing details about which parts of the OpenAPI document were resolved to service your request. For OAS3 this will be an object with the following fields:openApiDoc
- The OpenAPI document for your API. This is a "bundled" object, with all external $refs resolved, and only internal $refs remaining.serverObject
- The Server Object which was matched.serverPtr
- A JSON Pointer to the server object inopenApiDoc
.pathItemObject
- The Path Item Object which was matched.pathItemPath
- A JSON Pointer to the path item object.operationObject
- The matched Operation Object.operationPtr
- A JSON Pointer to the Operation Object.requestBodyMediaTypeObject
- The matched MediaType Object from the operation'srequestBody
, or null if none was matched or the Operation has no requestBody.requestBodyMediaTypePtr
- A JSON Pointer to the MediaType Object.
-
context.makeError(statusCode, message)
is a convenience function which will create a new Error object with a status. Note that this does not throw the error - your code has to do that. -
context.makeValidationError(message, location)
is a convenience function which will creates a new validation error.location
should be a parameter location fromcontext.parameterLocations
. Note that this does not throw the error - your code has to do that. -
context.route.path
is a string with the path that was matched from the API document. This is similar toreq.route.path
in Express. -
context.baseUrl
is a string with the baseUrl that was stripped off to matchcontext.route.path
. This is similar toreq.baseUrl
in Express.