Wrappers around stuff you would otherwise do with express but with reflection
capabilities used for openapi specification generation and built-in request
format validation.
The req and res objects aren't provided to the passed in handler
functions, if you're doing something more complicated just use the router
directly for now.
Nested routing not supported yet, but should probably be added since api.ts
is getting long (or we could separate the functions from the route
defintions).
// add route (/api/double) addGetRoute( globalContext, router, '/double', // Zod schemas for each part of the request & response, defaults=emptyFormat // since query params end up as strings, z.coerce.number() is needed not z.number() { ...emptyFormat, query:z.object({ x:z.coerce.number() }), resBody:z.number() }, // handling logic goes here, first arg is ignored b/c it is the path params (_, { x }) => { // x is already a number as opposed to any/unknown makeSuccessResponse(x * 2); }, // documentation goes here { name:'double a number', description:'f: R -> R, x |-> 2x'} );
z.tuple isn't handled well by swagger_parser, prefer objects instead.
If a Zod schema is reused / important enough to get its own variable, make
sure to at the very least add .meta({ id: 'unique name' }) to it so that
API/docs consumers can also take advantage of this. Other schemas can also
have this even if they are not variables. Note that id must be unique, and
accidentally setting name instead won't have the intended outcome.
Be Careful With Zod Transformations
The OpenAPI spec will be populated with the output formats of the schemas you
define routes with. This makes coerce work well with path/query formats but
might be problematic with client generation if using transformations to
non-primative types. Only use coerce, pipe, and transform with the parts of
the request, not the response (the resBody schema is never used to validate,
only to get a type).
Getting OpenAPI Specs
Look into setting the environment variables DOCUMENTED (to anything
truthy), DOCUMENTED_OUTPUT_FILE (or it will log to the console), and
DOCUMENTED_EXIT_ON_OUTPUT. Also look at globalContext,
docsFor, and outputDocsFor.
Wrappers around stuff you would otherwise do with express but with reflection capabilities used for openapi specification generation and built-in request format validation.
The
reqandresobjects aren't provided to the passed in handler functions, if you're doing something more complicated just use the router directly for now.Nested routing not supported yet, but should probably be added since api.ts is getting long (or we could separate the functions from the route defintions).
Extra functionality can be added as needed.
Getting Started
Defining Routes
Make sure you know how to use Zod, then look into addRouter, addGetRoute, and addPostRoute. It would also be useful to take a look at HandlerReturn + remember the existence of emptyFormat and globalContext.
z.tupleisn't handled well by swagger_parser, prefer objects instead.If a Zod schema is reused / important enough to get its own variable, make sure to at the very least add
.meta({ id: 'unique name' })to it so that API/docs consumers can also take advantage of this. Other schemas can also have this even if they are not variables. Note that id must be unique, and accidentally settingnameinstead won't have the intended outcome.Be Careful With Zod Transformations
The OpenAPI spec will be populated with the output formats of the schemas you define routes with. This makes coerce work well with path/query formats but might be problematic with client generation if using transformations to non-primative types. Only use coerce, pipe, and transform with the parts of the request, not the response (the resBody schema is never used to validate, only to get a type).
Getting OpenAPI Specs
Look into setting the environment variables
DOCUMENTED(to anything truthy),DOCUMENTED_OUTPUT_FILE(or it will log to the console), andDOCUMENTED_EXIT_ON_OUTPUT. Also look at globalContext, docsFor, and outputDocsFor.