azure-func-middleware
v1.0.0
Published
A middleware cascade for Azure Functions
Downloads
2
Readme
azure-func-middleware
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
use
Add a middleware to a cascade
Parameters
useIf
Add a middleware with condition to a cascade
Parameters
predicate
predicatefn
middlewareHandler
useMany
Add several middlewares to a cascade
Parameters
fns
Array<(errMiddlewareHandler | middlewareHandler)>
useManyIf
Add several middlewares to a cascade with condition
Parameters
predicate
fns
Array<(errMiddlewareHandler | middlewareHandler)>
catch
Add a middleware for error handling to a cascade
Parameters
catchIf
Add a middleware for error handling with condition to a cascade
Parameters
predicate
fn
errMiddlewareHandler
listen
Compose middlewares to a function handler
Returns funcHandler
funcHandler
Type: Function
Parameters
context
Object The context object
Returns Promise
middlewareHandler
Type: Function
Parameters
context
Object The context objectnext
next
errMiddlewareHandler
Type: Function
Parameters
error
Errorcontext
Object The context objectnext
next
next
Type: Function
Parameters
error
Error?
predicate
Type: Function
Parameters
context
Object? The context object
Returns boolean