* Create an instance of HttpHandler and populates it with routes
()
| 421 | * Create an instance of HttpHandler and populates it with routes |
| 422 | */ |
| 423 | private _createHttpHandler() { |
| 424 | /** |
| 425 | * Check if there is custom router in the context |
| 426 | */ |
| 427 | const router = this.getSync(RestBindings.ROUTER, {optional: true}); |
| 428 | const routingTable = new RoutingTable(router, this._externalRoutes); |
| 429 | |
| 430 | this._httpHandler = new HttpHandler(this, this.config, routingTable); |
| 431 | |
| 432 | // Remove controller routes |
| 433 | for (const b of this.findByTag(RestTags.CONTROLLER_ROUTE)) { |
| 434 | this.unbind(b.key); |
| 435 | } |
| 436 | |
| 437 | for (const b of this.find(`${CoreBindings.CONTROLLERS}.*`)) { |
| 438 | const controllerName = b.key.replace(/^controllers\./, ''); |
| 439 | const ctor = b.valueConstructor; |
| 440 | if (!ctor) { |
| 441 | throw new Error( |
| 442 | `The controller ${controllerName} was not bound via .toClass()`, |
| 443 | ); |
| 444 | } |
| 445 | const apiSpec = getControllerSpec(ctor); |
| 446 | if (!apiSpec) { |
| 447 | // controller methods are specified through app.api() spec |
| 448 | debug('Skipping controller %s - no API spec provided', controllerName); |
| 449 | continue; |
| 450 | } |
| 451 | |
| 452 | debug('Registering controller %s', controllerName); |
| 453 | if (apiSpec.components) { |
| 454 | this._httpHandler.registerApiComponents(apiSpec.components); |
| 455 | } |
| 456 | const controllerFactory = createControllerFactoryForBinding<object>( |
| 457 | b.key, |
| 458 | ); |
| 459 | const routes = createRoutesForController( |
| 460 | apiSpec, |
| 461 | ctor, |
| 462 | controllerFactory, |
| 463 | ); |
| 464 | for (const route of routes) { |
| 465 | const binding = this.bindRoute(route); |
| 466 | binding |
| 467 | .tag(RestTags.CONTROLLER_ROUTE) |
| 468 | .tag({[RestTags.CONTROLLER_BINDING]: b.key}); |
| 469 | } |
| 470 | } |
| 471 | |
| 472 | for (const b of this.findByTag(RestTags.REST_ROUTE)) { |
| 473 | // TODO(bajtos) should we support routes defined asynchronously? |
| 474 | const route = this.getSync<RouteEntry>(b.key); |
| 475 | this._httpHandler.registerRoute(route); |
| 476 | } |
| 477 | |
| 478 | // TODO(bajtos) should we support API spec defined asynchronously? |
| 479 | const spec: OpenApiSpec = this.getSync(RestBindings.API_SPEC); |
| 480 | if (spec.components) { |
no test coverage detected