Skip to content

Commit c49b65a

Browse files
bajtosraymondfeng
authored andcommitted
feat(rest): push route(verb, path, spec, fn) down to RestServer
Move the implementation of 4-arg version of "route` method from RestApplication to RestServer, simplify RestApplication's "route" to delegate the implementation to RestServer.
1 parent b6ff7b7 commit c49b65a

File tree

5 files changed

+84
-31
lines changed

5 files changed

+84
-31
lines changed

packages/rest/src/rest.application.ts

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,21 @@
33
// This file is licensed under the MIT License.
44
// License text available at https://opensource.org/licenses/MIT
55

6-
import {Application, ApplicationConfig, Server} from '@loopback/core';
7-
import {RestComponent} from './rest.component';
8-
import {SequenceHandler, SequenceFunction} from './sequence';
96
import {Binding, Constructor} from '@loopback/context';
7+
import {Application, ApplicationConfig, Server} from '@loopback/core';
8+
import {OpenApiSpec, OperationObject} from '@loopback/openapi-v3-types';
9+
import {PathParams} from 'express-serve-static-core';
10+
import {ServeStaticOptions} from 'serve-static';
1011
import {format} from 'util';
1112
import {RestBindings} from './keys';
12-
import {RestServer, HttpRequestListener, HttpServerLike} from './rest.server';
13+
import {RestComponent} from './rest.component';
14+
import {HttpRequestListener, HttpServerLike, RestServer} from './rest.server';
1315
import {
14-
RouteEntry,
1516
ControllerClass,
1617
ControllerFactory,
17-
Route,
18+
RouteEntry,
1819
} from './router/routing-table';
19-
import {OperationObject, OpenApiSpec} from '@loopback/openapi-v3-types';
20-
import {ServeStaticOptions} from 'serve-static';
21-
import {PathParams} from 'express-serve-static-core';
20+
import {SequenceFunction, SequenceHandler} from './sequence';
2221

2322
export const ERR_NO_MULTI_SERVER = format(
2423
'RestApplication does not support multiple servers!',
@@ -127,6 +126,29 @@ export class RestApplication extends Application implements HttpServerLike {
127126
methodName: string,
128127
): Binding;
129128

129+
/**
130+
* Register a new route invoking a handler function.
131+
*
132+
* ```ts
133+
* function greet(name: string) {
134+
* return `hello ${name}`;
135+
* }
136+
* app.route('get', '/', operationSpec, greet);
137+
* ```
138+
*
139+
* @param verb HTTP verb of the endpoint
140+
* @param path URL path of the endpoint
141+
* @param spec The OpenAPI spec describing the endpoint (operation)
142+
* @param handler The function to invoke with the request parameters
143+
* described in the spec.
144+
*/
145+
route(
146+
verb: string,
147+
path: string,
148+
spec: OperationObject,
149+
handler: Function,
150+
): Binding;
151+
130152
/**
131153
* Register a new route.
132154
*
@@ -172,7 +194,10 @@ export class RestApplication extends Application implements HttpServerLike {
172194
return server.route(routeOrVerb);
173195
} else if (arguments.length === 4) {
174196
return server.route(
175-
new Route(routeOrVerb, path!, spec!, controllerCtorOrHandler!),
197+
routeOrVerb,
198+
path!,
199+
spec!,
200+
controllerCtorOrHandler as Function,
176201
);
177202
} else {
178203
return server.route(

packages/rest/src/rest.server.ts

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,30 @@ export class RestServer extends Context implements Server, HttpServerLike {
520520
): Binding;
521521

522522
/**
523-
* Register a new route.
523+
* Register a new route invoking a handler function.
524+
*
525+
* ```ts
526+
* function greet(name: string) {
527+
* return `hello ${name}`;
528+
* }
529+
* app.route('get', '/', operationSpec, greet);
530+
* ```
531+
*
532+
* @param verb HTTP verb of the endpoint
533+
* @param path URL path of the endpoint
534+
* @param spec The OpenAPI spec describing the endpoint (operation)
535+
* @param handler The function to invoke with the request parameters
536+
* described in the spec.
537+
*/
538+
route(
539+
verb: string,
540+
path: string,
541+
spec: OperationObject,
542+
handler: Function,
543+
): Binding;
544+
545+
/**
546+
* Register a new generic route.
524547
*
525548
* ```ts
526549
* function greet(name: string) {
@@ -534,12 +557,12 @@ export class RestServer extends Context implements Server, HttpServerLike {
534557
*/
535558
route(route: RouteEntry): Binding;
536559

537-
route<I>(
560+
route<T>(
538561
routeOrVerb: RouteEntry | string,
539562
path?: string,
540563
spec?: OperationObject,
541-
controllerCtor?: ControllerClass<I>,
542-
controllerFactory?: ControllerFactory<I>,
564+
controllerCtorOrHandler?: ControllerClass<T> | Function,
565+
controllerFactory?: ControllerFactory<T>,
543566
methodName?: string,
544567
): Binding {
545568
if (typeof routeOrVerb === 'object') {
@@ -563,7 +586,18 @@ export class RestServer extends Context implements Server, HttpServerLike {
563586
});
564587
}
565588

566-
if (!controllerCtor) {
589+
if (arguments.length === 4) {
590+
if (!controllerCtorOrHandler) {
591+
throw new AssertionError({
592+
message: 'handler function is required for a handler-based route',
593+
});
594+
}
595+
return this.route(
596+
new Route(routeOrVerb, path, spec, controllerCtorOrHandler as Function),
597+
);
598+
}
599+
600+
if (!controllerCtorOrHandler) {
567601
throw new AssertionError({
568602
message: 'controller is required for a controller-based route',
569603
});
@@ -580,7 +614,7 @@ export class RestServer extends Context implements Server, HttpServerLike {
580614
routeOrVerb,
581615
path,
582616
spec,
583-
controllerCtor,
617+
controllerCtorOrHandler as ControllerClass<T>,
584618
controllerFactory,
585619
methodName,
586620
),

packages/rest/test/acceptance/routing/routing.acceptance.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import {
77
Request,
88
Response,
9-
Route,
109
RestBindings,
1110
RestServer,
1211
RestComponent,
@@ -408,8 +407,7 @@ describe('Routing', () => {
408407
return `hello ${name}`;
409408
}
410409

411-
const route = new Route('get', '/greet', routeSpec, greet);
412-
server.route(route);
410+
server.route('get', '/greet', routeSpec, greet);
413411

414412
const client = whenIMakeRequestTo(server);
415413
await client.get('/greet?name=world').expect(200, 'hello world');
@@ -609,8 +607,7 @@ describe('Routing', () => {
609607
return `hello ${name}`;
610608
}
611609

612-
const route = new Route('get', '/greet', routeSpec, greet);
613-
app.route(route);
610+
app.route('get', '/greet', routeSpec, greet);
614611

615612
await whenIMakeRequestTo(app)
616613
.get('/greet?name=world')

packages/rest/test/integration/rest.server.integration.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
httpsGetAsync,
1313
givenHttpServerConfig,
1414
} from '@loopback/testlab';
15-
import {Route, RestBindings, RestServer, RestComponent} from '../..';
15+
import {RestBindings, RestServer, RestComponent} from '../..';
1616
import {IncomingMessage, ServerResponse} from 'http';
1717
import * as yaml from 'js-yaml';
1818
import * as path from 'path';
@@ -238,7 +238,7 @@ describe('RestServer (integration)', () => {
238238
},
239239
},
240240
};
241-
server.route(new Route('get', '/greet', greetSpec, function greet() {}));
241+
server.route('get', '/greet', greetSpec, function greet() {});
242242

243243
const response = await createClientForHandler(server.requestHandler).get(
244244
'/openapi.json',
@@ -330,7 +330,7 @@ describe('RestServer (integration)', () => {
330330
},
331331
},
332332
};
333-
server.route(new Route('get', '/greet', greetSpec, function greet() {}));
333+
server.route('get', '/greet', greetSpec, function greet() {});
334334

335335
const response = await createClientForHandler(server.requestHandler).get(
336336
'/openapi.yaml',
@@ -372,7 +372,7 @@ paths:
372372
},
373373
},
374374
};
375-
server.route(new Route('get', '/greet', greetSpec, function greet() {}));
375+
server.route('get', '/greet', greetSpec, function greet() {});
376376

377377
const response = await createClientForHandler(server.requestHandler).get(
378378
'/explorer',

packages/rest/test/unit/rest.server/rest.server.open-api-spec.unit.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import {expect, validateApiSpec} from '@loopback/testlab';
77
import {Application} from '@loopback/core';
88
import {
99
RestServer,
10-
Route,
1110
RestComponent,
1211
createControllerFactoryForClass,
1312
} from '../../..';
@@ -51,9 +50,7 @@ describe('RestServer.getApiSpec()', () => {
5150

5251
it('binds a route via app.route(route)', () => {
5352
function greet() {}
54-
const binding = server.route(
55-
new Route('get', '/greet', {responses: {}}, greet),
56-
);
53+
const binding = server.route('get', '/greet', {responses: {}}, greet);
5754
expect(binding.key).to.eql('routes.get %2Fgreet');
5855
expect(binding.tagNames).containEql('route');
5956
});
@@ -77,7 +74,7 @@ describe('RestServer.getApiSpec()', () => {
7774

7875
it('returns routes registered via app.route(route)', () => {
7976
function greet() {}
80-
server.route(new Route('get', '/greet', {responses: {}}, greet));
77+
server.route('get', '/greet', {responses: {}}, greet);
8178

8279
const spec = server.getApiSpec();
8380
expect(spec.paths).to.eql({
@@ -195,7 +192,7 @@ describe('RestServer.getApiSpec()', () => {
195192
);
196193

197194
function greet() {}
198-
server.route(new Route('get', '/greet', {responses: {}}, greet));
195+
server.route('get', '/greet', {responses: {}}, greet);
199196

200197
const spec = server.getApiSpec();
201198
expect(spec.paths).to.eql({

0 commit comments

Comments
 (0)