Управление жизненным циклом запроса с помощью ПО промежуточного слоя

Завершено

Tailwind Traders хотел бы защитить свой веб-API. В некоторых случаях, когда запрос достигает веб-приложения, может потребоваться проверить:

  • Проверка подлинности: кто является пользователем
  • Авторизация: то, что пользователь может видеть или делать

Шаги запроса

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

  1. Предварительная обработка: необязательный шаг для запуска кода перед обработкой запроса.

    Примером является определение того, что пользователь отправил правильные учетные данные с помощью заголовка запроса. Если учетные данные подтверждены, запрос передается на следующий этап. Если ведение журнала завершается ошибкой, сервер возвращает http-ответ 401.

  2. Обработка: обработайте запрос, например, поговорите с каким-либо источником данных, например базой данных или конечной точкой API.

    Этот шаг возвращает ресурс, если запрос правильно запрашивает ресурс.

  3. Postprocessing: необязательный шаг для запуска кода после завершения запроса.

    Примером является ведение журнала результатов для целей мониторинга.

Платформа Express имеет встроенную поддержку обработки запросов таким образом. Чтобы выполнить предварительную обработку или после обработки запроса, реализуйте use() метод в объекте Express app со следующей формой синтаксиса:

app.use((req, res, next) => {})

Метод, переданный в use() метод, имеет следующие параметры:

  • req: входящий запрос, содержащий заголовки запросов и URL-адрес вызова. Он также может содержать текст данных, если клиент отправил данные с помощью запроса.
  • res: поток ответа для записи таких сведений, как заголовки и данные, которые необходимо отправить обратно вызывающему клиенту.
  • next: следующая функция ПО промежуточного слоя в стеке. next() Если функция не вызывается, обработка запроса останавливается. Если запрос выполнен успешно, может потребоваться вызвать next(), чтобы внести изменения в ответ или записать результаты.

Конвейер запроса

Если у вас есть маршруты, которые получают преимущество от предварительной или после обработки ПО промежуточного слоя, настройте функции в файле исходного кода таким образом:

  • ПО промежуточного слоя, которое должно выполняться до определения запроса (предварительной обработки) перед фактическим запросом.
  • ПО промежуточного слоя, которое должно выполняться после запроса (после обработки), определяется после фактического запроса.

Взгляните на этот пример:

app.use((req, res, next) => {
  // Pre request
})
app.get('/protected-resource', () => {
  // Handle the actual request
})
app.use((req, res, next) => {
  // Post request
})

app.get('/login', () => {})

Вы также можете запустить предварительную обработку ПО промежуточного слоя в качестве аргумента обработчика запросов:

app.get(
  '/<some route>',
 () => {
   // Pre request middleware
 }, () => {
   // Handle the actual request
 })

Порядок функций по промежуточного слоя в Express.js имеет решающее значение, так как они выполняются последовательно, в том порядке, в который они определены в коде. Это означает, что если функция промежуточного слоя помещается после обработчика маршрутов, она не будет выполняться для этого маршрута.

Рекомендации по управлению маршрутами

Ниже приведены некоторые рекомендации по управлению порядком функций ПО промежуточного слоя:

  • Поместите глобальное ПО промежуточного слоя в начало: функции по промежуточного слоя, применяемые ко всем маршрутам, должны размещаться в верхней части кода перед любыми обработчиками маршрутов. Это гарантирует, что они выполняются для каждого запроса.

  • Упорядочить ПО промежуточного слоя по определенности: более конкретные функции по промежуточному слоям следует размещать после более общих. Таким образом, общие функции ПО промежуточного слоя могут обрабатывать общие задачи для всех маршрутов, а конкретные могут обрабатывать задачи для определенных маршрутов.

  • Поместите ПО промежуточного слоя обработки ошибок в последний раз: функции по промежуточного слоя по промежуточному слоям по промежуточного слоя по промежуточному слоям промежуточного слоя по промежуточному слоям по промежуточного слоя рассматриваются как функции по промежуточному слоям по промежуточного слоя по промежуточному слоям по промежуточному слоя Они должны размещаться в конце стека ПО промежуточного слоя после всех остальных обработчиков по промежуточного слоя и маршрутов.

Приведем пример:

const express = require('express');
const app = express();

// Global middleware
app.use((req, res, next) => {
  console.log('This is a global middleware');
  next();
});

// Route handler
app.get('/', (req, res, next) => {
  console.log('This is a route handler');
  next();
});

// Specific middleware
app.use((req, res, next) => {
  console.log('This is a specific middleware');
  next();
});

// Error-handling middleware
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).send('Something broke!');
});

app.listen(3000);