Немедленно ответьте на запрос Коа, продолжайте цепочку промежуточного программного обеспечения - PullRequest
0 голосов
/ 11 марта 2020

Я пишу промежуточное ПО для конечных точек API в моем приложении, которое отвечает на веб-хуки из других приложений, и я относительно новичок в Koa, поэтому не совсем знаком с его шаблонами.

Я хотел бы структурировать свой промежуточное программное обеспечение выглядит следующим образом:

exports.updateReceived = async (ctx, next) => {
  // Respond to server issuing the webhook
  ctx.res.body = "ok";
  ctx.res.statusCode = 200;

  // Grab what we need from the request
  const { headers, state, request } = ctx;
  const { body } = request;

  // Do some async work
  const { example } = await doSomeAsyncWork(ctx);

  // Prepare a database query
  const query = { aValue: anId };

  // Run the DB query
  const result = await Thing.findOne(query);

  // Add data to the request
  state.thing = result;

  // Move on...
  return next();
};

Однако, похоже, это не работает, так как ошибка в любом из моих асин c методов может привести к ошибке маршрута.

Мой цель состоит в том, чтобы эта конечная точка всегда отвечала «да, хорошо» (немедленно), что означает, что приложение должно обрабатывать любые состояния ошибок.

Я достаточно хорошо это исследовал и натолкнулся на этот паттерн :

app.use(async ctx => {
  db.fetch() // Assuming a Promise is returned
    .then(() => { ... })
    .catch(err => {
      log(err)
    })

  // status 200 will be returned regardless of if db.fetch() resolves or rejects.
  ctx.status = 200
})

Однако это не отвечает моим потребностям, поскольку промежуточное программное обеспечение не использует next, поэтому, насколько я могу судить, это не совсем полезный шаблон.

Может ли кто-нибудь сказать мне, что я пропускаю?

Ответы [ 2 ]

2 голосов
/ 27 марта 2020

next() вызывает цепочку промежуточного программного обеспечения нижнего уровня и возвращает обещание, которое разрешается после завершения всех промежуточных промежуточных программ / обработчиков нижнего уровня.

Это означает, что вы можете просто реализовать собственный обработчик ошибок верхнего уровня, который перехватывает любые ошибки и всегда обеспечивает ответ 200 OK.

const Koa = require('koa')
const app = new Koa()

app.use(async (ctx, next) => {
  next().catch((err) => {
    // Print error for our own records / debugging
    console.error(err)

    // But ensure that outgoing response is always a smile
    ctx.status = 200
    ctx.body = ':)'
  })
})

app.use(async (ctx) => {
  // Do your webhook / biz logic here, but for demonstration
  // let's make it always throw an error. Thus upstream next()
  // will be a rejected promise.
  throw new Error('this middleware will always bubble up a rejected promise')
})

app.listen(3000, () => {
  console.log('listening on 3000')
})

0 голосов
/ 11 марта 2020

Просто для того, чтобы перевести решение в другую сторону, вы можете добавить свою работу к какому-либо MessageQueue, а затем позволить другому процессу выполнить эту задачу за вас. В основном асинхронно, но вы все равно будете важны. Этот тип шаблона соответствует вашим требованиям.

Существует множество систем обмена сообщениями, таких как AWS SQS , которые вы можете рассмотреть. Таким образом, ваш API будет очень легким, и он будет делать то, что ему нужно, и отправит команду в вашу систему обмена сообщениями, чтобы сделать дополнительные вещи. Вы в основном разделяете свою основную логику c и выполняете действия в фоновом режиме, которые также очень хорошо масштабируются.

...