Skip to content

Commit 833c3b1

Browse files
authored
Merge pull request #65 from osher/patch-1
resolving controller-interface type
2 parents a44711b + 6ec101f commit 833c3b1

File tree

12 files changed

+381
-7
lines changed

12 files changed

+381
-7
lines changed

fittings/swagger_cors.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require('./cors');

fittings/swagger_router.js

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ var debug = require('debug')('swagger:swagger_router');
44
var path = require('path');
55
var assert = require('assert');
66
var SWAGGER_ROUTER_CONTROLLER = 'x-swagger-router-controller';
7+
var CONTROLLER_INTERFACE_TYPE = 'x-controller-interface';
8+
var allowedCtrlInterfaces = ["middleware", "pipe", "auto-detect"];
79
var util = require('util');
810

911
module.exports = function create(fittingDef, bagpipes) {
@@ -12,8 +14,25 @@ module.exports = function create(fittingDef, bagpipes) {
1214

1315
assert(Array.isArray(fittingDef.controllersDirs), 'controllersDirs must be an array');
1416
assert(Array.isArray(fittingDef.mockControllersDirs), 'mockControllersDirs must be an array');
17+
18+
if (!fittingDef.controllersInterface) fittingDef.controllersInterface = "middleware";
19+
assert( ~allowedCtrlInterfaces.indexOf(fittingDef.controllersInterface),
20+
'value in swagger_router config.controllersInterface - can be one of ' + allowedCtrlInterfaces + ' but got: ' + fittingDef.controllersInterface
21+
);
1522

1623
var swaggerNodeRunner = bagpipes.config.swaggerNodeRunner;
24+
swaggerNodeRunner.api.getOperations().forEach(function(operation) {
25+
var interfaceType =
26+
operation.controllerInterface =
27+
operation.definition[CONTROLLER_INTERFACE_TYPE] ||
28+
operation.pathObject.definition[CONTROLLER_INTERFACE_TYPE] ||
29+
swaggerNodeRunner.api.definition[CONTROLLER_INTERFACE_TYPE] ||
30+
fittingDef.controllersInterface;
31+
32+
assert( ~allowedCtrlInterfaces.indexOf(interfaceType),
33+
'whenever provided, value of ' + CONTROLLER_INTERFACE_TYPE + ' directive in openapi doc must be one of ' + allowedCtrlInterfaces + ' but got: ' + interfaceType);
34+
})
35+
1736
var appRoot = swaggerNodeRunner.config.swagger.appRoot;
1837
var dependencies = swaggerNodeRunner.config.swagger.dependencies
1938

@@ -62,12 +81,27 @@ module.exports = function create(fittingDef, bagpipes) {
6281

6382
if (controller) {
6483

65-
var operationId = operation.definition['operationId'] || context.request.method.toLowerCase();
84+
var operationId = operation.definition.operationId || context.request.method.toLowerCase();
85+
var ctrlType =
86+
operation.definition['x-controller-type'] ||
87+
operation.pathObject.definition['x-controller-type'] ||
88+
operation.pathObject.api.definition['x-controller-type'];
89+
6690
var controllerFunction = controller[operationId];
6791

6892
if (controllerFunction && typeof controllerFunction === 'function') {
69-
debug('running controller');
70-
return controllerFunction(context.request, context.response, cb);
93+
if (operation.controllerInterface == 'auto-detect') {
94+
operation.controllerInterface =
95+
controllerFunction.length == 3
96+
? 'middleware'
97+
: 'pipe';
98+
debug("auto-detected interface-type for operation '%s' at [%s] as '%s'", operationId, operation.pathToDefinition, operation.controllerInterface)
99+
}
100+
101+
debug('running controller, as %s', operation.controllerInterface);
102+
return operation.controllerInterface == 'pipe'
103+
? controllerFunction(context, cb)
104+
: controllerFunction(context.request, context.response, cb);
71105
}
72106

73107
var msg = util.format('Controller %s doesn\'t export handler function %s', controllerName, operationId);

lib/connect_middleware.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ function Middleware(runner) {
6666
};
6767

6868
context._finish = function finishConnect(ignore1, ignore2) { // must have arity of 2
69-
69+
debugContent("exec", context.error);
7070
if (context.error) { return next(context.error); }
7171

7272
try {
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
module.exports = {
2+
pipeInterface: pipeInterface,
3+
middlewareInterface: middlewareInterface
4+
}
5+
6+
function pipeInterface(ctx, next) {
7+
ctx.statusCode = 200;
8+
ctx.headers = {
9+
'content-type': 'application/json',
10+
'x-interface': 'pipe'
11+
};
12+
next(null, { interface: 'pipe' });
13+
}
14+
15+
function middlewareInterface(req, res, next) {
16+
res.setHeader('x-interface', 'middleware');
17+
res.json({ interface: "middleware" });
18+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
'use strict';
2+
var util = require('util');
3+
4+
module.exports = {
5+
hello: hello,
6+
hello_body: hello_body,
7+
hello_file: hello_file,
8+
get: hello,
9+
self_multiple_writes : self_multiple_writes,
10+
hello_text_body: hello_text_body
11+
};
12+
13+
function hello(ctx, next) {
14+
var req = ctx.request;
15+
var name = req.swagger.params.name.value || 'stranger';
16+
var hello = { message: util.format('Hello, %s!', name) };
17+
ctx.statusCode = 200;
18+
ctx.headers = { 'content-type' : 'application/json' };
19+
next(null, hello)
20+
}
21+
22+
function hello_body(ctx, next) {
23+
var req = ctx.request;
24+
var name = req.swagger.params.nameRequest.value.name || 'stranger';
25+
var hello = { message: util.format('Hello, %s!', name) };
26+
ctx.statusCode = 200;
27+
ctx.headers = {};
28+
next(null, hello)
29+
}
30+
31+
function hello_file(ctx, next) {
32+
var req = ctx.request;
33+
var name = req.swagger.params.name.value || 'stranger';
34+
var file = req.swagger.params.example_file.value;
35+
var hello = { message: util.format('Hello, %s!', name) };
36+
ctx.statusCode = 200;
37+
ctx.headers = {};
38+
next(null, hello)
39+
}
40+
41+
function self_multiple_writes(ctx, next) {
42+
var res = ctx.response;
43+
res.write('hello');
44+
res.write('world');
45+
res.end('yo');
46+
next();
47+
}
48+
49+
function hello_text_body(ctx, next) {
50+
var req = ctx.request;
51+
var name = req.swagger.params.name.value || 'stranger';
52+
var hello = { message: util.format('Hello, %s!', name) };
53+
ctx.statusCode = 200;
54+
ctx.headers = {};
55+
next(null, hello)
56+
}

test/assets/project/api/swagger/swagger.yaml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,45 @@ paths:
314314
content-type:
315315
type: integer
316316
schema: {}
317+
/controller_interface_auto_detected_as_pipe:
318+
x-swagger-router-controller: overrides_ctrl_interface_pipe
319+
x-controller-interface: auto-detect
320+
get:
321+
description: well, what do you know...
322+
operationId: pipeInterface
323+
responses:
324+
200:
325+
description: Whatever
326+
schema: {}
327+
/controller_interface_auto_detected_as_middleware:
328+
x-swagger-router-controller: overrides_ctrl_interface_pipe
329+
x-controller-interface: auto-detect
330+
get:
331+
description: well, what do you know...
332+
operationId: middlewareInterface
333+
responses:
334+
200:
335+
description: Whatever
336+
schema: {}
337+
/controller_interface_on_path_cascades:
338+
x-swagger-router-controller: overrides_ctrl_interface_pipe
339+
x-controller-interface: pipe
340+
get:
341+
operationId: pipeInterface
342+
responses:
343+
200:
344+
description: Whatever
345+
schema: {}
346+
/controller_interface_on_operation_cascades:
347+
x-swagger-router-controller: overrides_ctrl_interface_pipe
348+
x-controller-interface: pipe
349+
get:
350+
x-controller-interface: middleware
351+
operationId: middlewareInterface
352+
responses:
353+
200:
354+
description: Whatever
355+
schema: {}
317356
definitions:
318357
HelloWorldResponse:
319358
type: object
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# values in the swagger hash are system configuration for swagger-node
2+
swagger:
3+
4+
fittingsDirs: [ api/fittings ]
5+
defaultPipe: null
6+
swaggerControllerPipe: swagger_controllers # defines the standard processing pipe for controllers
7+
8+
# values defined in the bagpipes key are the bagpipes pipes and fittings definitions
9+
# (see https://github.com/apigee-127/bagpipes)
10+
bagpipes:
11+
12+
_router:
13+
name: swagger_router
14+
mockMode: false
15+
mockControllersDirs: [ api/mocks ]
16+
controllersDirs: [ api/controllers ]
17+
controllersInterface: auto-detect
18+
19+
_swagger_validate:
20+
name: swagger_validator
21+
validateResponse: true
22+
23+
_swagger_security:
24+
name: swagger_security
25+
securityHandlersModule: api/helpers/securityHandlers
26+
27+
# pipe for all swagger-node controllers
28+
swagger_controllers:
29+
- onError: json_error_handler
30+
- cors
31+
- swagger_params_parser
32+
- _swagger_security
33+
- _swagger_validate
34+
- express_compatibility
35+
- _router
36+
37+
# pipe to serve swagger (endpoint is in swagger.yaml)
38+
swagger_raw:
39+
name: swagger_raw
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# values in the swagger hash are system configuration for swagger-node
2+
swagger:
3+
4+
fittingsDirs: [ node_modules, api/fittings ]
5+
defaultPipe: null
6+
swaggerControllerPipe: swagger_controllers # defines the standard processing pipe for controllers
7+
8+
# values defined in the bagpipes key are the bagpipes pipes and fittings definitions
9+
# (see https://github.com/apigee-127/bagpipes)
10+
bagpipes:
11+
12+
_router:
13+
name: swagger_router
14+
mockMode: false
15+
mockControllersDirs: [ api/mocks ]
16+
controllersDirs: [ api/pipes ]
17+
controllersInterface: pipe
18+
19+
_swagger_validate:
20+
name: swagger_validator
21+
validateResponse: true
22+
23+
_swagger_security:
24+
name: swagger_security
25+
securityHandlersModule: api/helpers/securityHandlers
26+
27+
# pipe for all swagger-node controllers
28+
swagger_controllers:
29+
- onError: json_error_handler
30+
- swagger_cors
31+
- swagger_params_parser
32+
- _swagger_security
33+
- _swagger_validate
34+
- express_compatibility
35+
- _router
36+
37+
# pipe to serve swagger (endpoint is in swagger.yaml)
38+
swagger_raw:
39+
name: swagger_raw

test/fittings/swagger_raw.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ describe('swagger_raw', function() {
2020
delete(filteredSwagger.paths['/invalid_header']);
2121

2222
// hokey algorithm, but at least it's different than the one it's testing
23-
var OMIT = ['x-swagger-router-controller', 'x-swagger-pipe', 'x-hidden', 'x-private'];
23+
var OMIT = ['x-swagger-router-controller', 'x-swagger-pipe', 'x-hidden', 'x-private', 'x-controller-interface'];
2424
_.forEach(filteredSwagger.paths, function(element, name) {
2525
filteredSwagger.paths[name] = _.omit(element, OMIT);
2626
_.forEach(filteredSwagger.paths[name], function(element, subName) {

0 commit comments

Comments
 (0)