1.0.0 • Published 3 years ago

azure-func-middleware v1.0.0

Weekly downloads
3
License
ISC
Repository
github
Last release
3 years ago

azure-func-middleware

Build Status

A middleware cascade implementation for Azure Functions JS 2.x (inspired by Koa and Express).

Install

npm install azure-func-middleware --save

Usage

Main flow

Method use adds middleware handler to a cascade. Middleware handlers are executed in the order they are added. To go to the next middleware handler, use the next callback. Method listen composes middlewares to the Azure Function handler.

const AzureFuncMiddleware = require('azure-func-middleware');

module.exports = new AzureFuncMiddleware()
  .use(async (ctx, next) => {
    // will be called first
    // ...
    next();
  })
  .use((ctx, next) => {
    // will be called second if no error in first
    // ...
    ctx.done(null, { status: 200 });
  })
  .catch((err, ctx, next) => {
    // will be called if there is error in first or second
    // ...
    ctx.done(null, { status: 500 });
  })
  .listen();

Response

To complete the response process, use done callback of the context object

Using with the $return output binding

function.json

{
  "bindings": [
    ...
    {
    "type": "http",
    "direction": "out",
    "name": "$return"
    }
  ]
}

index.js

const AzureFuncMiddleware = require('azure-func-middleware');

module.exports = new AzureFuncMiddleware()
  .use((ctx) => {
    const response = {
      status: 200,
      body: 'OK'
    };
    ctx.done(null, response);
  })
  .listen();

Using with the named output binding

function.json

{
  "bindings": [
    ...
    {
    "type": "http",
    "direction": "out",
    "name": "res"
    }
  ]
}

index.js

const AzureFuncMiddleware = require('azure-func-middleware');

module.exports = new AzureFuncMiddleware()
  .use((ctx) => {
    ctx.res = {
      status: 200,
      body: 'OK'
    };
    ctx.done();
  })
  .listen();

Capturing errors

If an error is thrown in the middleware handler, then the nearest error middleware handler is called. Error handlers are added by the catch method.

const AzureFuncMiddleware = require('azure-func-middleware');

module.exports = new AzureFuncMiddleware()
  .use((ctx, next) => {
    throw new Error('Error!'); // or next(new Error('Error!'));
  })
  .use(async (ctx, next) => {
    // won't be called
    // ...
    next()
  })
  .catch((err, ctx, next) => {
    // will be called
    ctx.done(null, {
      status: 500,
      body: err.message // 'Error!' 
    });
  })
  .listen();

Passing data through middlewares

For passing data through middlewares you can use namespace state of the context object

const AzureFuncMiddleware = require('azure-func-middleware');

module.exports = new AzureFuncMiddleware()
  .use(async (ctx, next) => {
    ctx.state.count = 1;
    next();
  })
  .use((ctx, next) => {
    ctx.state.count += 1; // ctx.state.count === 2
    ctx.done(null, { status: 200 });
  })
  .listen();

Conditional middlewares

The method useIf adds a middleware handler that will be executed if the predicate returns true.

const AzureFuncMiddleware = require('azure-func-middleware');

module.exports = new AzureFuncMiddleware()
  .useIf(ctx => ctx.req.method === 'HEAD', (ctx, next) => {
    // will be called if HEAD request 
    // ...
  })
  .useIf(ctx => ctx.req.method === 'GET', (ctx, next) => {
    // will be called if GET request 
    // ...
  })
  .listen();

Common middlewares

Often Azure Functions use a common sequence of middlewares. You can declare this sequence and add using the method useMany.

common.js

const defineUser = (ctx, next) => { 
  //... 
};

const checkRoles = (ctx, next) => {
  //... 
};

module.exports = [
  defineUser,
  checkRoles
]

index.js

const AzureFuncMiddleware = require('azure-func-middleware');
const common = require('common');


module.exports = new AzureFuncMiddleware()
  .useMany(common)
  .use((ctx, next) => {
      // will be called after common
    })
  .listen();

Testing

The Azure Function handler returns a promise. This fact can be used for testing.

Using with the $return output binding

function.json

{
  "bindings": [
    ...
    {
    "type": "http",
    "direction": "out",
    "name": "$return"
    }
  ]
}

test.js

const funcHandler = require(...);

it('should work', async () => {
  const context = { ... };
  const expectedBody = ...;
  const { status, body } = await funcHandler(context);
  expect(status).toEqual(200);
  expect(body).toEqual(expectedBody);
});

Using with the named output binding

function.json

{
  "bindings": [
    ...
    {
    "type": "http",
    "direction": "out",
    "name": "res"
    }
  ]
}

test.js

const funcHandler = require(...);

it('should work', async () => {
  const context = { ... };
  const expectedBody = ...;
  await funcHandler(context);
  expect(context.res.status).toEqual(200);
  expect(context.res.body).toEqual(expectedBody);
});

API

Table of Contents

AzureFuncMiddleware

Parameters

  • options Object (optional, default {})
    • options.silent boolean (optional, default false)

use

Add a middleware to a cascade

Parameters

useIf

Add a middleware with condition to a cascade

Parameters

useMany

Add several middlewares to a cascade

Parameters

useManyIf

Add several middlewares to a cascade with condition

Parameters

catch

Add a middleware for error handling to a cascade

Parameters

catchIf

Add a middleware for error handling with condition to a cascade

Parameters

listen

Compose middlewares to a function handler

Returns funcHandler

funcHandler

Type: Function

Parameters

Returns Promise

middlewareHandler

Type: Function

Parameters

errMiddlewareHandler

Type: Function

Parameters

next

Type: Function

Parameters

predicate

Type: Function

Parameters

Returns boolean

1.0.0

3 years ago

0.5.3

4 years ago

0.5.2

5 years ago

0.5.1

5 years ago

0.5.0

5 years ago

0.4.1

5 years ago

0.4.0

5 years ago

0.3.1

5 years ago

0.3.0

5 years ago

0.2.3

5 years ago

0.2.2

5 years ago

0.2.1

5 years ago

0.2.0

5 years ago

0.1.1

5 years ago

0.1.0

5 years ago