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, and stops with the first value it finds:

  1. x-controller-interface attribute on the operation
  2. x-controller-interface attribute on the path
  3. x-controller-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 - 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?). In any case, if the value is not any of the above - an error is passed in server load-time and the sever startup is halted.

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 are implemented by the same controller (point 2),
  • and final word - a cascading value for a specific method of a specific operation (point 1).