Это отличная идея, что вы можете реализовать промежуточное ПО в ExpressJS. Многие фреймворки используют эту идею, скопированную с ExpressJS, с тех пор. ExpressJS — это, по сути, промежуточное ПО двойного прохода. Промежуточное программное обеспечение двойного прохода получает как запрос, так и ответ в дополнение к обработчику и передает и запрос, и ответ обработчику при его вызове. Ниже приведена обычная реализация нашей функции ExpressJS:
Запуск промежуточного программного обеспечения до ответа — это здорово. Однако существуют сценарии, в которых может потребоваться ведение журнала после завершения ответа. Вы можете добиться этого в responseHandler или добавив afterMiddleware после нашего responseHandler в реализации маршрута ExpressJS. Давайте посмотрим на код ниже:
Примечание:
Попытка манипулировать ответом или заголовками в функции afterMiddleware приведет к ошибке приложения — предупреждению о том, что ответ был отправлен клиенту.
Однако существует множество сценариев, в которых вы можете захотеть либо манипулировать ответом после запуска responseHandler, либо выполнить другие задачи после создания ответа. Они могут включать в себя расширенное ведение журнала для аналитики перед отправкой ответа, проверку ответа, очистку ответа или просто манипулирование ответом на основе ACL.
Важно отметить, что когда вы используете функцию .send() в ExpressJS, вы не можете манипулировать ни заголовками, ни ответом. Можно выполнять другие действия (кроме обработки заголовка или ответа) после отправки ответа. Это может быть что угодно: ведение журнала, запуск планировщика, электронная почта или какое-либо действие публикации-подписки. Однако снова ни заголовки, ни ответ не могут быть изменены, поскольку ответ уже отправлен клиенту.
Это создает пару вариантов использования. Возможно, после того, как ответ был создан, вы можете проверить, действительно ли переменные объекта ответа или данные, которые должны быть отправлены, действительны, авторизованы, и, если нет, вы можете ограничить их или удалить эти данные ответа. Во-вторых, вы можете просто захотеть отключить его где-нибудь в целях аналитики, очистки ответов или просто манипулирования ответами на основе ACL, или просто инициировать действие приложения pub-sub после того, как ответ был создан / «предположительно» отправлен.
Давайте создадим код, который будет вести себя так. Вместо использования .send() мы создадим функцию манипулятора .send() с именем .response (функция), прикрепленную к объекту ответа ExpressJS, которая позволит нам запускаться после промежуточного программного обеспечения (после запуска функции responseHandler) в нашем приложении ExpressJS. После запуска всех промежуточных программ после ответа мы будем использовать функцию финального обработчика, которая примет предварительно созданный ответ / ответ, обработанный промежуточным программным обеспечением, и отправит его клиенту. Давайте посмотрим на код ниже:
Если вы заметили, функция beforeAfterInjection позволяет нам использовать функцию .response(obj). Это одна из самых важных функций, и она всегда запускается первой в списке промежуточного программного обеспечения. Значение функции в том, что она отделяет логику сохранения ответа от фактической функции обработчика ответа.
Следующим промежуточным программным обеспечением в реализации является функция beforeMiddleware, которая является обычным промежуточным программным обеспечением, которое мы все использовали ранее в ExpressJS.
Затем идет довольно важная реализация промежуточного программного обеспечения, в которой находится обработчик ответов нашего приложения. Обратите внимание, что мы не использовали responseHandler напрямую, но фактически обернули его в функцию-оболочку, которая запускает функцию responseHandler, а затем вызывает next() для передачи триггеров следующему промежуточному программному обеспечению — фактически нашей реализации после промежуточного программного обеспечения — afterMiddleware. Обратите внимание, что наша реализация afterMiddleware не требует отправки ответа клиенту. Ответ все еще сохраняется в объекте запроса как свойство req.res, а не отправляется клиенту. Эта реализация afterMiddleware позволяет нам выполнять проверки ACL, валидацию, санацию и все, что вы можете придумать, более чистым и единоличным способом из приложения. Вместо одной функции, выполняющей всю работу в responseHandler, мы теперь делегируем задачи другим промежуточным программам.
Но опять же, что произойдет, если я воспользуюсь функцией .send() вместо созданной нами функции .response() для манипулирования фреймворком для такого шаблона? Ну, на самом деле ответ будет отправлен клиенту даже при срабатывании afterMiddleware. Это может быть неприятно, если у вас есть бизнес-логика, которая требует, чтобы ответ клиенту был задержан для манипуляции в промежуточном программном обеспечении. Реализация .send() вместо реализации .response() в этом случае приводит к «ошибке приложения» при попытке манипулировать ответом или заголовками; предупреждая нас, что ответ был отправлен клиенту. Однако могут быть случаи, когда вам может не понадобиться задерживать ответ клиенту; например, ведение журнала или отправка триггера электронной почты и т. д. В таких случаях вы можете использовать триггер .send() ExpressJS. Клиент получит ответ быстрее (скорее вовремя), не беспокоясь о задержках из-за логики вашего приложения после ответа. Давайте еще раз посмотрим на такую реализацию ниже:
Теперь у вас есть выбор для вашей реализации — использовать этот шаблон приложения или все другие способы, которыми вы реализовали свою бизнес-логику после создания ответа. Однако тестирование может быть сложной задачей, как и для ваших обычных обработчиков ответов, которым во время тестирования необходимо передать запрос, ответ и следующие аргументы. В таких случаях вам может быть лучше выполнять конечные тесты API или отделить общую логику от промежуточного программного обеспечения для тестирования. Выберите тот, который вам нравится, более проверяемый или тот, который больше соответствует вашим потребностям.
Обобщить:
Этот шаблон приложения с использованием промежуточного программного обеспечения как до, так и после помогает вам лучше разделить код для ответственности, манипулировать ответами (удаление беспорядка в таких случаях), чище код и, что более важно, позволяет вам делать что-то после того, как ответ был создан или отправлен; что угодно, сценарий.
Все блоги серии ExpressJS: https://medium.com/@ganeshsurfs/expressjs-series-links-9e038be8d78b
Дайте мне знать, как я это сделал, и если вы узнали что-то новое. Оставляйте свои комментарии и не забудьте поставить лайк статье.