1 |
|
2 | import { Application, Binding, BindingAddress, Constructor, Server } from '@loopback/core';
|
3 | import { BaseMiddlewareRegistry, ExpressRequestHandler } from '@loopback/express';
|
4 | import { HttpServer, HttpServerOptions } from '@loopback/http-server';
|
5 | import { OASEnhancerService, OpenApiSpec, OperationObject, ServerObject } from '@loopback/openapi-v3';
|
6 | import cors from 'cors';
|
7 | import express, { ErrorRequestHandler } from 'express';
|
8 | import { PathParams } from 'express-serve-static-core';
|
9 | import { IncomingMessage, ServerResponse } from 'http';
|
10 | import { ServeStaticOptions } from 'serve-static';
|
11 | import { BodyParser } from './body-parsers';
|
12 | import { HttpHandler } from './http-handler';
|
13 | import { RequestContext } from './request-context';
|
14 | import { ControllerClass, ControllerFactory, ControllerInstance, RestRouterOptions, RouteEntry, RouterSpec } from './router';
|
15 | import { SequenceFunction, SequenceHandler } from './sequence';
|
16 | import { Request, RequestBodyParserOptions, Response } from './types';
|
17 | export type HttpRequestListener = (req: IncomingMessage, res: ServerResponse) => void;
|
18 | export interface HttpServerLike {
|
19 | requestHandler: HttpRequestListener;
|
20 | }
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 |
|
42 |
|
43 |
|
44 |
|
45 |
|
46 |
|
47 |
|
48 | export declare class RestServer extends BaseMiddlewareRegistry implements Server, HttpServerLike {
|
49 | |
50 |
|
51 |
|
52 |
|
53 |
|
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 |
|
60 |
|
61 |
|
62 |
|
63 |
|
64 |
|
65 |
|
66 |
|
67 |
|
68 | protected oasEnhancerService: OASEnhancerService;
|
69 | get OASEnhancer(): OASEnhancerService;
|
70 | protected _requestHandler: HttpRequestListener;
|
71 | get requestHandler(): HttpRequestListener;
|
72 | readonly config: RestServerResolvedConfig;
|
73 | private _basePath;
|
74 | protected _httpHandler: HttpHandler;
|
75 | protected get httpHandler(): HttpHandler;
|
76 | |
77 |
|
78 |
|
79 | private _routesEventSubscription;
|
80 | protected _httpServer: HttpServer | undefined;
|
81 | protected _expressApp?: express.Application;
|
82 | get listening(): boolean;
|
83 | get httpServer(): HttpServer | undefined;
|
84 | |
85 |
|
86 |
|
87 |
|
88 |
|
89 | get url(): string | undefined;
|
90 | |
91 |
|
92 |
|
93 |
|
94 | get rootUrl(): string | undefined;
|
95 | |
96 |
|
97 |
|
98 |
|
99 |
|
100 |
|
101 |
|
102 |
|
103 |
|
104 |
|
105 | constructor(app: Application, config?: RestServerConfig);
|
106 | protected _setupOASEnhancerIfNeeded(): void;
|
107 | protected _setupRequestHandlerIfNeeded(): void;
|
108 | /**
|
109 | * Get an Express handler for unexpected errors
|
110 | */
|
111 | protected _unexpectedErrorHandler(): ErrorRequestHandler;
|
112 | /**
|
113 | * Apply express settings.
|
114 | */
|
115 | protected _applyExpressSettings(): void;
|
116 | /**
|
117 | * Mount /openapi.json, /openapi.yaml for specs and /swagger-ui, /explorer
|
118 | * to redirect to externally hosted API explorer
|
119 | */
|
120 | protected _setupOpenApiSpecEndpoints(): void;
|
121 | /**
|
122 | * Add a new non-controller endpoint hosting a form of the OpenAPI spec.
|
123 | *
|
124 | * @param path Path at which to host the copy of the OpenAPI
|
125 | * @param form Form that should be rendered from that path
|
126 | */
|
127 | addOpenApiSpecEndpoint(path: string, form: OpenApiSpecForm, router?: express.Router): void;
|
128 | protected _handleHttpRequest(request: Request, response: Response): Promise<void>;
|
129 | protected _setupHandlerIfNeeded(): void;
|
130 | /**
|
131 | * Create an instance of HttpHandler and populates it with routes
|
132 | */
|
133 | private _createHttpHandler;
|
134 | private _setupOperation;
|
135 | private _serveOpenApiSpec;
|
136 | private _redirectToSwaggerUI;
|
137 | /**
|
138 | * Register a controller class with this server.
|
139 | *
|
140 | * @param controllerCtor - The controller class
|
141 | * (constructor function).
|
142 | * @returns The newly created binding, you can use the reference to
|
143 | * further modify the binding, e.g. lock the value to prevent further
|
144 | * modifications.
|
145 | *
|
146 | * @example
|
147 | * ```ts
|
148 | * class MyController {
|
149 | * }
|
150 | * app.controller(MyController).lock();
|
151 | * ```
|
152 | *
|
153 | */
|
154 | controller(controllerCtor: ControllerClass<ControllerInstance>): Binding;
|
155 | /**
|
156 | * Register a new Controller-based route.
|
157 | *
|
158 | * @example
|
159 | * ```ts
|
160 | * class MyController {
|
161 | * greet(name: string) {
|
162 | * return `hello ${name}`;
|
163 | * }
|
164 | * }
|
165 | * app.route('get', '/greet', operationSpec, MyController, 'greet');
|
166 | * ```
|
167 | *
|
168 | * @param verb - HTTP verb of the endpoint
|
169 | * @param path - URL path of the endpoint
|
170 | * @param spec - The OpenAPI spec describing the endpoint (operation)
|
171 | * @param controllerCtor - Controller constructor
|
172 | * @param controllerFactory - A factory function to create controller instance
|
173 | * @param methodName - The name of the controller method
|
174 | */
|
175 | route<I extends object>(verb: string, path: string, spec: OperationObject, controllerCtor: ControllerClass<I>, controllerFactory: ControllerFactory<I>, methodName: string): Binding;
|
176 | /**
|
177 | * Register a new route invoking a handler function.
|
178 | *
|
179 | * @example
|
180 | * ```ts
|
181 | * function greet(name: string) {
|
182 | * return `hello ${name}`;
|
183 | * }
|
184 | * app.route('get', '/', operationSpec, greet);
|
185 | * ```
|
186 | *
|
187 | * @param verb - HTTP verb of the endpoint
|
188 | * @param path - URL path of the endpoint
|
189 | * @param spec - The OpenAPI spec describing the endpoint (operation)
|
190 | * @param handler - The function to invoke with the request parameters
|
191 | * described in the spec.
|
192 | */
|
193 | route(verb: string, path: string, spec: OperationObject, handler: Function): Binding;
|
194 | /**
|
195 | * Register a new generic route.
|
196 | *
|
197 | * @example
|
198 | * ```ts
|
199 | * function greet(name: string) {
|
200 | * return `hello ${name}`;
|
201 | * }
|
202 | * const route = new Route('get', '/', operationSpec, greet);
|
203 | * app.route(route);
|
204 | * ```
|
205 | *
|
206 | * @param route - The route to add.
|
207 | */
|
208 | route(route: RouteEntry): Binding;
|
209 | private bindRoute;
|
210 | /**
|
211 | * Register a route redirecting callers to a different URL.
|
212 | *
|
213 | * @example
|
214 | * ```ts
|
215 | * server.redirect('/explorer', '/explorer/');
|
216 | * ```
|
217 | *
|
218 | * @param fromPath - URL path of the redirect endpoint
|
219 | * @param toPathOrUrl - Location (URL path or full URL) where to redirect to.
|
220 | * If your server is configured with a custom `basePath`, then the base path
|
221 | * is prepended to the target location.
|
222 | * @param statusCode - HTTP status code to respond with,
|
223 | * defaults to 303 (See Other).
|
224 | */
|
225 | redirect(fromPath: string, toPathOrUrl: string, statusCode?: number): Binding;
|
226 | private _externalRoutes;
|
227 | /**
|
228 | * Mount static assets to the REST server.
|
229 | * See https://expressjs.com/en/4x/api.html#express.static
|
230 | * @param path - The path(s) to serve the asset.
|
231 | * See examples at https://expressjs.com/en/4x/api.html#path-examples
|
232 | * @param rootDir - The root directory from which to serve static assets
|
233 | * @param options - Options for serve-static
|
234 | */
|
235 | static(path: PathParams, rootDir: string, options?: ServeStaticOptions): void;
|
236 | /**
|
237 | * Set the OpenAPI specification that defines the REST API schema for this
|
238 | * server. All routes, parameter definitions and return types will be defined
|
239 | * in this way.
|
240 | *
|
241 | * Note that this will override any routes defined via decorators at the
|
242 | * controller level (this function takes precedent).
|
243 | *
|
244 | * @param spec - The OpenAPI specification, as an object.
|
245 | * @returns Binding for the spec
|
246 | *
|
247 | */
|
248 | api(spec: OpenApiSpec): Binding;
|
249 | /**
|
250 | * Get the OpenAPI specification describing the REST API provided by
|
251 | * this application.
|
252 | *
|
253 | * This method merges operations (HTTP endpoints) from the following sources:
|
254 | * - `app.api(spec)`
|
255 | * - `app.controller(MyController)`
|
256 | * - `app.route(route)`
|
257 | * - `app.route('get', '/greet', operationSpec, MyController, 'greet')`
|
258 | *
|
259 | * If the optional `requestContext` is provided, then the `servers` list
|
260 | * in the returned spec will be updated to work in that context.
|
261 | * Specifically:
|
262 | * 1. if `config.openApi.setServersFromRequest` is enabled, the servers
|
263 | * list will be replaced with the context base url
|
264 | * 2. Any `servers` entries with a path of `/` will have that path
|
265 | * replaced with `requestContext.basePath`
|
266 | *
|
267 | * @param requestContext - Optional context to update the `servers` list
|
268 | * in the returned spec
|
269 | */
|
270 | getApiSpec(requestContext?: RequestContext): Promise<OpenApiSpec>;
|
271 | /**
|
272 | * Update or rebuild OpenAPI Spec object to be appropriate for the context of
|
273 | * a specific request for the spec, leveraging both app config and request
|
274 | * path information.
|
275 | *
|
276 | * @param spec base spec object from which to start
|
277 | * @param requestContext request to use to infer path information
|
278 | * @returns Updated or rebuilt spec object to use in the context of the request
|
279 | */
|
280 | private updateSpecFromRequest;
|
281 | /**
|
282 | * Configure a custom sequence class for handling incoming requests.
|
283 | *
|
284 | * @example
|
285 | * ```ts
|
286 | * class MySequence implements SequenceHandler {
|
287 | * constructor(
|
288 | * @inject('send) public send: Send)) {
|
289 | * }
|
290 | *
|
291 | * public async handle({response}: RequestContext) {
|
292 | * send(response, 'hello world');
|
293 | * }
|
294 | * }
|
295 | * ```
|
296 | *
|
297 | * @param sequenceClass - The sequence class to invoke for each incoming request.
|
298 | */
|
299 | sequence(sequenceClass: Constructor<SequenceHandler>): Binding<SequenceHandler>;
|
300 | /**
|
301 | * Configure a custom sequence function for handling incoming requests.
|
302 | *
|
303 | * @example
|
304 | * ```ts
|
305 | * app.handler(({request, response}, sequence) => {
|
306 | * sequence.send(response, 'hello world');
|
307 | * });
|
308 | * ```
|
309 | *
|
310 | * @param handlerFn - The handler to invoke for each incoming request.
|
311 | */
|
312 | handler(handlerFn: SequenceFunction): void;
|
313 | /**
|
314 | * Bind a body parser to the server context
|
315 | * @param parserClass - Body parser class
|
316 | * @param address - Optional binding address
|
317 | */
|
318 | bodyParser(bodyParserClass: Constructor<BodyParser>, address?: BindingAddress<BodyParser>): Binding<BodyParser>;
|
319 | /**
|
320 | * Configure the `basePath` for the rest server
|
321 | * @param path - Base path
|
322 | */
|
323 | basePath(path?: string): void;
|
324 | /**
|
325 | * Start this REST API's HTTP/HTTPS server.
|
326 | */
|
327 | start(): Promise<void>;
|
328 | /**
|
329 | * Stop this REST API's HTTP/HTTPS server.
|
330 | */
|
331 | stop(): Promise<void>;
|
332 | /**
|
333 | * Mount an Express router to expose additional REST endpoints handled
|
334 | * via legacy Express-based stack.
|
335 | *
|
336 | * @param basePath - Path where to mount the router at, e.g. `/` or `/api`.
|
337 | * @param router - The Express router to handle the requests.
|
338 | * @param spec - A partial OpenAPI spec describing endpoints provided by the
|
339 | * router. LoopBack will prepend `basePath` to all endpoints automatically.
|
340 | * This argument is optional. You can leave it out if you don't want to
|
341 | * document the routes.
|
342 | */
|
343 | mountExpressRouter(basePath: string, router: ExpressRequestHandler, spec?: RouterSpec): void;
|
344 | /**
|
345 | * Export the OpenAPI spec to the given json or yaml file
|
346 | * @param outFile - File name for the spec. The extension of the file
|
347 | * determines the format of the file.
|
348 | * - `yaml` or `yml`: YAML
|
349 | * - `json` or other: JSON
|
350 | * If the outFile is not provided or its value is `''` or `'-'`, the spec is
|
351 | * written to the console using the `log` function.
|
352 | * @param log - Log function, default to `console.log`
|
353 | */
|
354 | exportOpenApiSpec(outFile?: string, log?: (message?: any, ...optionalParams: any[]) => void): Promise<void>;
|
355 | }
|
356 | /**
|
357 | * Create a binding for the given body parser class
|
358 | * @param parserClass - Body parser class
|
359 | * @param key - Optional binding address
|
360 | */
|
361 | export declare function createBodyParserBinding(parserClass: Constructor<BodyParser>, key?: BindingAddress<BodyParser>): Binding<BodyParser>;
|
362 | /**
|
363 | * The form of OpenAPI specs to be served
|
364 | */
|
365 | export interface OpenApiSpecForm {
|
366 | version?: string;
|
367 | format?: string;
|
368 | }
|
369 | /**
|
370 | * Options to customize how OpenAPI specs are served
|
371 | */
|
372 | export interface OpenApiSpecOptions {
|
373 | /**
|
374 | * Mapping of urls to spec forms, by default:
|
375 | * <br>
|
376 | * {
|
377 | * <br>
|
378 | * '/openapi.json': {version: '3.0.0', format: 'json'},
|
379 | * <br>
|
380 | * '/openapi.yaml': {version: '3.0.0', format: 'yaml'},
|
381 | * <br>
|
382 | * }
|
383 | *
|
384 | */
|
385 | endpointMapping?: {
|
386 | [key: string]: OpenApiSpecForm;
|
387 | };
|
388 | /**
|
389 | * A flag to force `servers` to be set from the http request for the OpenAPI
|
390 | * spec
|
391 | */
|
392 | setServersFromRequest?: boolean;
|
393 | /**
|
394 | * Configure servers for OpenAPI spec
|
395 | */
|
396 | servers?: ServerObject[];
|
397 | /**
|
398 | * Set this flag to disable the endpoint for OpenAPI spec
|
399 | */
|
400 | disabled?: true;
|
401 | /**
|
402 | * Set this flag to `false` to disable OAS schema consolidation. If not set,
|
403 | * the value defaults to `true`.
|
404 | */
|
405 | consolidate?: boolean;
|
406 | }
|
407 | export interface ApiExplorerOptions {
|
408 | /**
|
409 | * URL for the hosted API explorer UI
|
410 | * default to https://loopback.io/api-explorer
|
411 | */
|
412 | url?: string;
|
413 | /**
|
414 | * URL for the API explorer served over `http` protocol to deal with mixed
|
415 | * content security imposed by browsers as the spec is exposed over `http` by
|
416 | * default.
|
417 | * See https://github.com/loopbackio/loopback-next/issues/1603
|
418 | */
|
419 | httpUrl?: string;
|
420 | /**
|
421 | * Set this flag to disable the built-in redirect to externally
|
422 | * hosted API Explorer UI.
|
423 | */
|
424 | disabled?: true;
|
425 | }
|
426 | /**
|
427 | * RestServer options
|
428 | */
|
429 | export type RestServerOptions = Partial<RestServerResolvedOptions>;
|
430 | export interface RestServerResolvedOptions {
|
431 | port: number;
|
432 | path?: string;
|
433 | /**
|
434 | * Base path for API/static routes
|
435 | */
|
436 | basePath?: string;
|
437 | cors: cors.CorsOptions;
|
438 | openApiSpec: OpenApiSpecOptions;
|
439 | apiExplorer: ApiExplorerOptions;
|
440 | requestBodyParser?: RequestBodyParserOptions;
|
441 | sequence?: Constructor<SequenceHandler>;
|
442 | expressSettings: {
|
443 | [name: string]: any;
|
444 | };
|
445 | router: RestRouterOptions;
|
446 | /**
|
447 | * Set this flag to `false` to not listen on connections when the REST server
|
448 | * is started. It's useful to mount a LoopBack REST server as a route to the
|
449 | * facade Express application. If not set, the value is default to `true`.
|
450 | */
|
451 | listenOnStart?: boolean;
|
452 | }
|
453 | /**
|
454 | * Valid configuration for the RestServer constructor.
|
455 | */
|
456 | export type RestServerConfig = RestServerOptions & HttpServerOptions;
|
457 | export type RestServerResolvedConfig = RestServerResolvedOptions & HttpServerOptions;
|
458 |
|
\ | No newline at end of file |