Skip to content

Controllers Interface

osher edited this page Nov 29, 2016 · 9 revisions

A user can chose one of two styles for the interface of web-operation methods:

  • middleware interface
  • pipe interface

Middleware Interface

This is the interface the project initially launched with. It is the default interface for same reason.

With this style, user controllers should look like this:

module.exports = {
  myOperation
}

function myOperation(req, res, next) {
    const params = req.swagger.params;
    const poperations = req.swagger.operation;
    
    //do your logic here
    
    res.setHeader("x-foo", "bar" );
    next(null, { message: "Hello World" })
}

Pipe Interface

This alternative to the middleware interface comes to increase reuse and testability. It persues the following goals (not all of which are fully accomplished, but are under work):

  • let the ctx be a basis for dependency injection
  • isolate the handlers from web-context, letting you reuse the same code in CLI or message-queue consumer, and - of course - test context

As of the time of writing this page, only the first step was taken: isolate from ctx.response. Better isolation from ctx.request is still in design/progress.

With this style, user controllers should look like this:

module.exports = {
  myOperation
}

function myOperation(ctx, next) {
    const params      = ctx.request.swagger.params;   //swagger will be available on the ctx in the future
    const poperations = ctx.request.swagger.operation;//swagger will be available on the ctx in the future
    
    //do your logic here
    
    ctx.headers["x-foo"] = "bar";
    next(null, { message: "Hello World" })
}

Automatic Detection

Automatic detection should be activated deliberately (the default is middleware). When automatic detection is applied - operation methods with arity of 3 will be invoked as ctrl.operation(req,res,next), and operation methods with arity of 2 will be invoked as ctrl.operation(ctx,next).

How swagger-node-runner knows what interface to work with?

It looks on the following places:

  1. x-controllers-interface attribute on the operation
  2. x-controllers-interface attribute on the path
  3. x-controllers-interface attribute on the open-api root
  4. fittingDef.controllersInterface attribute in fitting-definition of the swagger_router fitting
  5. Defaults to middleware

The values that are acceptable in all of these places are:

  • pipe - for Pipe Interface
  • middleware - for Middleware Interface
  • auto-detect - for Automatic Detection of Interface Type

All this resolving happens only once, during server load-time. If the value is not legal - an error is passed and the sever startup is halted - with the exception of auto-detect, where final detection is done lazily just before invocation. (we could actually move it to load time too... PR anybody?)

This means you can have

  • a default for your entire server (point 3, 4 or 5),
  • a cascading default for all operations in a given path - traditionally but not necessarily implemented by the same controller (point 2),
  • and final word - a cascading value for a specific method of a specific operation (point 1).
Clone this wiki locally