### Clone the Exegesis Typescript Example Repository Source: https://github.com/exegesis-js/exegesis/blob/master/samples/typescript-example/README.md Clone the repository to your local machine to get started with the Typescript API example. ```bash git clone https://github.com/Ryan-Gordon/exegesis-typescript-example.git ``` -------------------------------- ### Create Project and Install Dependencies Source: https://github.com/exegesis-js/exegesis/blob/master/docs/Tutorial.md Sets up the project directory, initializes npm, and installs necessary packages like express and exegesis-express. ```sh mkdir exegesis-tutorial cd exegesis-tutorial mkdir controllers npm init -y npm install express exegesis-express ``` -------------------------------- ### Start Exegesis Server Source: https://github.com/exegesis-js/exegesis/blob/master/docs/Tutorial.md Command to start the Exegesis server. This is typically run from the project's root directory. ```sh node index.js ``` -------------------------------- ### Defining the '/greet' Path and GET Operation Source: https://github.com/exegesis-js/exegesis/blob/master/docs/Tutorial.md This snippet shows how to define a '/greet' path with a GET operation in an OpenAPI document. It includes the summary, operationId, and an Exegesis-specific controller extension. ```yaml paths: '/greet': get: summary: Greets the user operationId: getGreeting x-exegesis-controller: greetController ``` -------------------------------- ### OpenAPI Document with a '/greet' Path Source: https://github.com/exegesis-js/exegesis/blob/master/docs/Tutorial.md This OpenAPI 3.0.3 document defines a '/greet' path with a GET operation. It includes parameters, operationId, an Exegesis controller extension, and response definitions. ```yaml openapi: 3.0.3 info: title: My API version: 1.0.0 paths: '/greet': get: summary: Greets the user operationId: getGreeting x-exegesis-controller: greetController parameters: - description: The name of the user to greet. name: name in: query required: true schema: type: string responses: 200: description: A greeting for the user. content: application/json: schema: type: object required: - message properties: message: type: string default: description: Unexpected error. content: application/json: schema: type: object required: - message properties: message: type: string ``` -------------------------------- ### Basic Auth Authenticator with Passport.js Source: https://github.com/exegesis-js/exegesis/blob/master/docs/OAS3 Security.md Integrate Basic Authentication using Passport.js. This example shows how to configure Passport with a Basic Strategy and then use it with Exegesis. ```javascript import exegesisPassport from 'exegesis-passport'; import passport from 'passport'; import { BasicStrategy } from 'passport-http'; import bcrypt from 'bcrypt'; // Note the name of the auth scheme here should match the name of the security // role. passport.use('basicAuth', new BasicStrategy( function(name, password, done) { db.User.find({name}, (err, user) => { if (err) {return done(err);} bcrypt.compare(password, user.password, (err, matched) => { if (err) {return done(err);} return done(null, matched ? user : false); } }); } )); const basicAuthAuthenticator = passportSecurity('basicAuth'); ``` -------------------------------- ### Exegesis Plugin Structure and Lifecycle Source: https://github.com/exegesis-js/exegesis/blob/master/docs/Exegesis Plugins.md This example demonstrates the basic structure of an Exegesis plugin module. It includes the default export function that returns plugin configuration and the `makeExegesisPlugin` function, which defines the plugin's behavior across different request lifecycle phases. It also shows how to validate the OpenAPI document version and return an `ExegesisPluginInstance` with various lifecycle hooks. ```javascript import * as semver from 'semver'; function makeExegesisPlugin({apiDoc}) { // Verify the apiDoc is an OpenAPI 3.x.x document, because this plugin // doesn't know how to handle anything else. if (!apiDoc.openapi) { throw new Error("OpenAPI definition is missing 'openapi' field"); } if (!semver.satisfies(apiDoc.openapi, '>=3.0.0 <4.0.0')) { throw new Error(`OpenAPI version ${apiDoc.openapi} not supported`); } // Can make modifications to apiDoc at this point, such as adding new // routes, or modifying documentation - whatever you want to do. Just // keep in mind that other plugins might make changes, also, either before // or after this. If you need the "final" apiDoc, see `preCompile`. // Return an ExegesisPluginInstance. return { // Called exactly once, before Exegesis "compiles" the API document. // Plugins must not modify apiDoc here. preCompile({apiDoc, options}) { } // Called before routing. Note that the context hasn't been created yet, // so you just get a raw `req` and `res` object here. preRouting({req, res}) { } // Called immediately after the routing phase. Note that this is // called before Exegesis verifies routing was valid - the // `pluginContext.api` object will have information about the // matched route, but will this information may be incomplete. // For example, for OAS3 we may have matched a route, but not // matched an operation within the route. Or we may have matched // an operation but that operation may have no controller defined. // (If we failed to match a route at all, this will not be called.) // // If your API added a route to the API document, this function is a // good place to write a reply. // // Note that calling `pluginContext.getParams()` or `pluginContext.getRequestBody()` // will throw here if routing was not successful. postRouting(pluginContext) { } // Called for each request, after security phase and before input // is parsed and the controller is run. This is a good place to // do extra security checks. The `exegesis-plugin-roles` plugin, // for example, generates a 403 response here if the authenticated // user has insufficient privliedges to access this path. // // Note that this function will not be called if a previous plugin // has already written a response. postSecurity(pluginContext) { } // Called immediately after the controller has been run, but before // any response validation. This is a good place to do custom // response validation. If you have to deal with something weird // like XML, this is where you'd handle it. // // This function can modify the contents of the response. postController(context) { } // Called after the response validation step. This is the last step before // the response is converted to JSON and written to the output. postResponseValidation(context) { } }; } export default function plugin(options) { return { info: { // This should match the name of your npm package. name: 'exegesis-plugin-example' }, makeExegesisPlugin }; } ``` -------------------------------- ### Specify Controller for a GET Operation Source: https://github.com/exegesis-js/exegesis/blob/master/docs/Exegesis Controllers.md Use 'x-exegesis-controller' to link an OpenAPI path to a controller module. Exegesis will look for 'userController.js' and call the 'getUsers' function. ```yaml openapi: 3.0.3 info: title: Example version: 1.0.0 paths: "/users" x-exegesis-controller: userController get: operationId: getUsers ``` -------------------------------- ### Example Session Authenticator Source: https://github.com/exegesis-js/exegesis/blob/master/docs/OAS3 Security.md A sample authenticator function that checks for a 'session' key in the request headers. It demonstrates returning different types of results based on the session key's validity. ```javascript async function sessionAuthenticator(pluginContext, info) { const session = pluginContext.req.headers.session; if (!session) { return { type: 'missing', statusCode: 401, message: 'Session key required' }; } else if (session === 'secret') { return { type: 'success', user: { name: 'jwalton', roles: ['read', 'write'] } }; } else { // Session was supplied, but it's invalid. return { type: 'invalid', statusCode: 401, message: 'Invalid session key' }; } } ``` -------------------------------- ### OpenAPI 3 Operation Security Requirements Source: https://github.com/exegesis-js/exegesis/blob/master/docs/OAS3 Security.md Specifies security requirements for a GET operation on '/kittens', allowing either basicAuth or OAuth2 with a 'readOnly' scope. ```yaml paths: '/kittens': get: description: Get a list of kittens security: - basicAuth: [] - oauth: ['readOnly'] ``` -------------------------------- ### Create Exegesis Server with Express Source: https://github.com/exegesis-js/exegesis/blob/master/docs/Tutorial.md This snippet demonstrates the boilerplate code required to set up an Exegesis server using Express. It includes setting up Exegesis middleware, defining routes, and basic error handling. ```javascript const express = require('express'); const exegesisExpress = require('exegesis-express'); const http = require('http'); const path = require('path'); async function createServer() { // See https://github.com/exegesis-js/exegesis/blob/master/docs/Options.md const options = { controllers: path.resolve(__dirname, 'controllers'), allowMissingControllers: false, }; // This creates an exegesis middleware, which can be used with express, // connect, or even just by itself. const exegesisMiddleware = await exegesisExpress.middleware( path.resolve(__dirname, './openapi.yaml'), options ); const app = express(); // If you have any body parsers, this should go before them. app.use(exegesisMiddleware); // Return a 404 app.use((req, res) => { res.status(404).json({ message: `Not found` }); }); // Handle any unexpected errors app.use((err, req, res, next) => { res.status(500).json({ message: `Internal error: ${err.message}` }); }); const server = http.createServer(app); return server; } createServer() .then(server => { server.listen(3000); console.log('Listening on port 3000'); console.log('Try visiting http://localhost:3000/greet?name=Jason'); }) .catch(err => { console.error(err.stack); process.exit(1); }); ``` -------------------------------- ### Exegesis Server Options Source: https://github.com/exegesis-js/exegesis/blob/master/docs/Tutorial.md Configuration options for Exegesis, specifying the directory for controller implementations and whether to allow missing controllers. ```javascript const options = { controllers: path.resolve(__dirname, 'controllers'), allowMissingControllers: false, }; ``` -------------------------------- ### Compile and Run Exegesis API Source: https://github.com/exegesis-js/exegesis/blob/master/README.md This snippet demonstrates how to compile an OpenAPI specification and use the generated middleware to create an HTTP server. It handles API compilation with options and basic request routing, including error handling for 404s and internal errors. ```javascript import * as path from 'path'; import * as http from 'http'; import * as exegesis from 'exegesis'; // See https://github.com/exegesis-js/exegesis/blob/master/docs/Options.md const options = { controllers: path.resolve(__dirname, './src/controllers'), }; // `compileApi()` can either be used with a callback, or if none is provided, // will return a Promise. exegesis.compileApi( path.resolve(__dirname, './openapi/openapi.yaml'), options, (err, middleware) => { if (err) { console.error('Error creating middleware', err.stack); process.exit(1); } const server = http.createServer((req, res) => middleware(req, res, (err) => { if (err) { res.writeHead(err.status || 500); res.end(`Internal error: ${err.message}`); } else { res.writeHead(404); res.end(); } }) ); server.listen(3000); } ); ``` -------------------------------- ### Defining a Query Parameter for '/greet' Source: https://github.com/exegesis-js/exegesis/blob/master/docs/Tutorial.md This snippet illustrates how to define a required string query parameter named 'name' for an OpenAPI operation. Exegesis will validate its presence and type. ```yaml parameters: - description: The name of the user to greet. name: name in: query required: true schema: type: string ``` -------------------------------- ### Exegesis Options with Session Authenticator Source: https://github.com/exegesis-js/exegesis/blob/master/docs/OAS3 Security.md Configuration object for Exegesis, specifying the controllers directory and mapping the 'sessionKey' security scheme to the custom sessionAuthenticator function. ```javascript const options: exegesis.ExegesisOptions = { controllers: path.resolve(__dirname, './controllers'), authenticators: { sessionKey: sessionAuthenticator, }, }; ``` -------------------------------- ### Configure Controller Loading Path and Pattern Source: https://github.com/exegesis-js/exegesis/blob/master/docs/Options.md Specify the directory containing controller modules and a glob pattern to filter which files are loaded. This is useful for organizing controller logic and ensuring only relevant files are processed. ```javascript import * as path from 'path'; const options = { controllers: path.resolve(__dirname, 'controllers'), controllersPattern: '**/*.@(ts|js)', }; ``` -------------------------------- ### OpenAPI 3.x.x Document Hierarchy Source: https://github.com/exegesis-js/exegesis/blob/master/src/oas3/README.md Illustrates the nested structure of an OpenAPI 3.x.x document, from the root 'OpenApi' object down to 'Operation' details like Parameters, Request Media Types, and Responses. ```text OpenApi +- Servers +- Paths +- Path[] +- Operation +- Parameter +- RequestMediaType +- Responses +- Response ``` -------------------------------- ### Basic Greeting Controller Source: https://github.com/exegesis-js/exegesis/blob/master/docs/Tutorial.md This JavaScript controller function implements the 'getGreeting' operation. It accesses the 'name' query parameter from the context and returns a JSON object with a greeting message. Ensure the function name matches the operationId in your OpenAPI document. ```javascript // This function has the same name as an operationId in the OpenAPI document. exports.getGreeting = function getGreeting(context) { const name = context.params.query.name; return { message: `Hello ${name}` }; }; ``` -------------------------------- ### Defining a 200 Response for '/greet' Source: https://github.com/exegesis-js/exegesis/blob/master/docs/Tutorial.md This snippet shows how to define a successful 200 response for an OpenAPI operation. It specifies that the response content will be JSON with a 'message' property. ```yaml 200: description: A greeting for the user. content: application/json: schema: type: object required: - message properties: message: type: string ``` -------------------------------- ### Minimal OpenAPI 3.0.3 Document Source: https://github.com/exegesis-js/exegesis/blob/master/docs/Tutorial.md This is the simplest valid OpenAPI 3.0.3 document. It includes the required fields but defines no API paths. ```yaml openapi: 3.0.3 info: title: My API version: 1.0.0 paths: ``` -------------------------------- ### compileApi Source: https://github.com/exegesis-js/exegesis/blob/master/README.md Compiles an OpenAPI document into a connect-style middleware function. This middleware handles API requests based on the provided OpenAPI specification and options. ```APIDOC ## compileApi(openApiDoc, options[, done]) ### Description This function takes an API document and a set of options, and returns a connect-style middleware function which will execute the API. ### Parameters #### Path Parameters - **openApiDoc** (string | object) - Required - Path to the OpenAPI document or the document object itself. - **options** (object) - Required - Configuration options for Exegesis, including controllers, authenticators, and validation callbacks. - **done** (function) - Optional - Callback function to be executed upon completion. ``` -------------------------------- ### Specify OperationId per MediaType Source: https://github.com/exegesis-js/exegesis/blob/master/docs/Exegesis Controllers.md When a path accepts multiple media types, use 'x-exegesis-operationId' within the MediaType object to specify a different controller function for each. This allows for distinct logic based on the request's content type. ```yaml 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 ``` -------------------------------- ### Asynchronous Controller with Promise Source: https://github.com/exegesis-js/exegesis/blob/master/docs/Exegesis Controllers.md An asynchronous controller that returns a Promise. The Promise should resolve with the result. ```javascript export function myPromiseController(context) { return Promise.resolve({ message: 'Hello World!' }); } ``` -------------------------------- ### Exegesis Parser Object for Request Parsing Source: https://github.com/exegesis-js/exegesis/blob/master/docs/Options.md Implement parseReq for asynchronous parsing of HTTP request bodies, allowing integration with existing body-parsing middleware. ```javascript { /** * Async function which parses an incoming HTTP request. This is essentially * here so you can use express/connect body parsers. * * @param {http.IncomingMessage} req - The request to read. This function * should add `req.body` after parsing the body. If `req.body` is already * present, this function can ignore the body and just call `next()`. * @param {http.ServerResponse} res - The response object. Well behaved * body parsers should *not* write anything to the response or modify it * in any way. * @param next - Callback to call when complete. If no value is returned * via the callback then `req.body` will be used as the body. */ parseReq(req, res, next) {...} } ``` -------------------------------- ### Exegesis Parameters Object Structure Source: https://github.com/exegesis-js/exegesis/blob/master/docs/OAS3 Parameter Parsing.md This object represents the expected structure for parameters within the Exegesis context. It organizes parameters by their 'in' location (path, query, header, cookie) and then by parameter name. ```js parameters = { path: { id: '5acc0981eaad142f3a754c77', }, query: { min: 6, users: ['tom', 'dick', 'harry'], deepObject: { a: 7, b: [2, 4] }, }, header: {}, cookie: {}, }; ``` -------------------------------- ### Basic Auth Authenticator Source: https://github.com/exegesis-js/exegesis/blob/master/docs/OAS3 Security.md Implement a custom authenticator for Basic Authentication. This function handles parsing credentials, validating against a database, and returning the authentication result. ```javascript import basicAuth from 'basic-auth'; import bcrypt from 'bcrypt'; // Note that authenticators can either return a Promise, or take a callback. async function basicAuthSecurity(pluginContext, info) { const credentials = basicAuth(pluginContext.req); if (!credentials) { // The request failed to provide a basic auth header. return { type: 'missing', challenge: info.scheme }; } const { name, pass } = credentials; const user = await db.User.find({ name }); if (!user) { return { type: 'invalid', challenge: info.scheme, message: `User ${name} not found`, }; } if (!(await bcrypt.compare(pass, user.password))) { return { type: 'invalid', challenge: info.scheme, message: `Invalid password for ${name}`, }; } return { type: 'success', user, roles: user.roles, // e.g. `['admin']`, or `[]` if this user has no roles. scopes: [], // Ignored in this case, but if `basicAuth` was an OAuth // security scheme, we'd fill this with `['readOnly', 'readWrite']` // or similar. }; } ``` -------------------------------- ### Basic JSON Controller Source: https://github.com/exegesis-js/exegesis/blob/master/docs/Exegesis Controllers.md A simple controller that returns a JSON object. The response is automatically stringified and set as the JSON body. ```javascript export function myController(context) { const name = context.params.query.name; return { message: `Hello ${name}` }; } ``` -------------------------------- ### OpenAPI 3 Combined Security OR and AND Scenario Source: https://github.com/exegesis-js/exegesis/blob/master/docs/OAS3 Security.md Defines a complex security requirement where (A AND B) OR (C AND D) must be satisfied. ```yaml security: # (A AND B) OR (C AND D) - A B - C D ``` -------------------------------- ### compileRunner Source: https://github.com/exegesis-js/exegesis/blob/master/README.md Compiles an OpenAPI document into a runner function. The runner function processes incoming Node.js HTTP requests and responses, returning an HttpResult object. ```APIDOC ## compileRunner(openApiDoc, options[, done]) ### Description This function is similar to `compileApi`; it takes an API document and a set of options, and returns a "runner". The runner is a `function runner(req, res)`, which takes in a standard node HTTP request and response. It will not modify the response, however. Instead it returns (either via callback or Promise) and `HttpResult` object. This is a `{headers, status, body}` object, where `body` is a readable stream, read to be piped to the response. ### Parameters #### Path Parameters - **openApiDoc** (string | object) - Required - Path to the OpenAPI document or the document object itself. - **options** (object) - Required - Configuration options for Exegesis. - **done** (function) - Optional - Callback function to be executed upon completion. ``` -------------------------------- ### Asynchronous Controller with Callback Source: https://github.com/exegesis-js/exegesis/blob/master/docs/Exegesis Controllers.md An asynchronous controller using a callback to return the result. The first argument to the callback is for errors, and the second is the result. ```javascript export function myAsyncController(context, callback) { callback(null, { message: 'Hello World!' }); } ``` -------------------------------- ### OpenAPI 3 Security AND Scenario Source: https://github.com/exegesis-js/exegesis/blob/master/docs/OAS3 Security.md Defines a security requirement where both 'A' and 'B' must be satisfied. ```yaml security: # A AND B - A B ``` -------------------------------- ### OpenAPI 3 Security OR Scenario Source: https://github.com/exegesis-js/exegesis/blob/master/docs/OAS3 Security.md Defines a security requirement where either 'A' or 'B' must be satisfied. ```yaml security: # A OR B - A - B ``` -------------------------------- ### Ignoring Servers in OpenAPI Source: https://github.com/exegesis-js/exegesis/blob/master/docs/Options.md Configure Exegesis to ignore the 'servers' section in your OpenAPI document. This allows routing to be based solely on the defined paths, bypassing server URL prefixes. ```yaml servers: - url: '/api/v2' ``` -------------------------------- ### Exegesis Parser Object for String Parsing Source: https://github.com/exegesis-js/exegesis/blob/master/docs/Options.md Implement parseString for synchronous parsing of string values, typically used for parameter parsing. ```javascript { /** * Synchronous function which parses a string. A BodyParser must implement * this function to be used for parameter parsing. * * @param {string} encoded - The encoded value to parse. * @returns - The decoded value. */ parseString(encoded) {...} } ``` -------------------------------- ### Authenticator Function Signatures Source: https://github.com/exegesis-js/exegesis/blob/master/docs/OAS3 Security.md Defines the two types of authenticator functions supported by Exegesis: one using Promises and another using callbacks. ```javascript async function promiseAuthenticator(pluginContext, info) {...} function callbackAuthenticator(pluginContext, info, done) {...} ``` -------------------------------- ### YAML for Exploded Query Parameter Source: https://github.com/exegesis-js/exegesis/blob/master/docs/OAS3 Parameter Parsing.md This YAML configuration defines a query parameter named 'myParam' with the 'form' style and 'explode' option set to true. This configuration results in the query string being expanded as '?a=foo&b=bar'. ```yaml parameter: name: 'myParam' in: query style: form explode: true schema: type: object properties: a: { type: string } b: { type: string } ``` -------------------------------- ### Custom HTTP Error Handling Source: https://github.com/exegesis-js/exegesis/blob/master/docs/Options.md Set 'autoHandleHttpErrors' to false to manually handle Exegesis HttpErrors, or provide a custom handler function. This allows for tailored error responses. ```javascript const options = { autoHandleHttpErrors: (err, { req }) => { // Custom error handling logic here return exegesis.HttpResult.fromError(err); } }; ``` -------------------------------- ### OpenAPI 3 Security Schemes Definition Source: https://github.com/exegesis-js/exegesis/blob/master/docs/OAS3 Security.md Defines basic authentication and OAuth2 security schemes for an API. ```yaml securitySchemes: basicAuth: description: A request with a username and password type: http scheme: basic oauth: description: A request with an oauth token. type: oauth2 flows: authorizationCode: authorizationUrl: https://api.exegesis.io/oauth/authorize tokenUrl: https://api.exegesis.io/oauth/token scopes: readOnly: "Read only scope." readWrite: "Read/write scope." ``` -------------------------------- ### Parameter Parser Function Signature Source: https://github.com/exegesis-js/exegesis/blob/master/src/oas3/parameterParsers/README.md The standard signature for a parameter parser function in Exegesis. It accepts the parameter name, raw values, and the querystring. ```javascript function(name, rawValues, querystring) ``` -------------------------------- ### Controller Returning Non-JSON Data Source: https://github.com/exegesis-js/exegesis/blob/master/docs/Exegesis Controllers.md Controller setting a non-JSON content type and body, such as XML. Note that response validation is skipped for non-JSON bodies. ```javascript export function myController(context) { const name = context.params.query.name; context.res .status(200) .setHeader('content-type', 'text/xml') .setBody(`Hello ${name}`); } ``` -------------------------------- ### Custom OpenAPI Formats Source: https://github.com/exegesis-js/exegesis/blob/master/docs/Options.md Provide validation functions or regular expressions for custom formats defined in your OpenAPI specification. This ensures data adheres to specific schemas beyond standard types. ```javascript const customFormats = { 'non-empty-string': { validate: (str) => str.length > 0, type: 'string' }, 'positive-integer': /^[1-9]\d*$/ }; ``` -------------------------------- ### writeHttpResult Source: https://github.com/exegesis-js/exegesis/blob/master/README.md A convenience function to write an HttpResult object to a Node.js HTTP response. ```APIDOC ## writeHttpResult(httpResult, res[, done]) ### Description A convenience function for writing an `HttpResult` from a runner out to the response. ### Parameters #### Path Parameters - **httpResult** (object) - Required - The HttpResult object to write. - **res** (object) - Required - The Node.js HTTP response object. - **done** (function) - Optional - Callback function to be executed upon completion. ``` -------------------------------- ### Explicitly Setting JSON Response Body Source: https://github.com/exegesis-js/exegesis/blob/master/docs/Exegesis Controllers.md Controller explicitly setting the status, content type, and body for a JSON response. ```javascript export function myController(context) { const name = context.params.query.name; context.res .status(200) .set('content-type', 'application/json'); .setBody({message: `Hello ${name}`}); } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.