Middleware
Every query and mutation specified in queries.js and mutations.js can have optional middleware.
Chain
Middleware supports before and after hooks. The before hooks fire before the root query/mutation resolve method is called, and after hooks fire afterwards
// middleware.js
import { createMiddleware } from 'micrograph';
import bcrypt from 'bcrypt';
const middleware = createMiddleware();
// fires before all queries and mutations
middleware.before('*', (args, ctx, next) => {
  ctx.startTime = Date.now();
  next();
});
// fires after all queries and mutations
middleware.after('*', (args, ctx, next) => {
  ctx.duration = Date.now() - ctx.startTime;
  next();
});
// fires before the createBlog and createUser mutations
middleware.before('create*', (args, ctx, next) => {
  if (!ctx.request.headers.authorization) {
    throw new Error('Unauthorized');
  }
  next();
});
// only fires before the createuUer mutation
middleware.before('createUser', (args, ctx, next) => {
  bcrypt.hash(args.input.password, 10, (err, hash) => {
    if (err) throw err;
    // override password with hash
    args.input.password = hash;
    next();
  });
});
export default middleware;
Middleware propagation
Middleware propagates by invoking next (the third argument) or by returning a Promise:
middleware.before('*', (args, ctx, next) => {
  // do something
  next();
});
or
middleware.before('*', (args, ctx) => {
  return somePromise.then(someOtherPromise);
});
There are a few gotcha, such as avoiding next inside a Promise. Refer to the create middleware docs.
Error handling
You can break out of a middleware chain (including inside of a resolve method) by either throwing an error or returning a rejected promise.
middleware.before('createUser', (args, ctx, next) => {
  // throwing an error will break out of the middleware chain
  throw new Error('Oh no!');
});
or
middleware.before('createUser', (args, ctx) => {
  return new Promise((resolve, reject) => {
    reject(new Error('Oh no!'));
  });
});
Refer to the api reference for more information on chaining middleware and handling errors.