Java: Веб-технологии
Теория: Middlewares
При разработке веб-приложений разработчики сталкиваются с задачами, которые нужно решать на каждом этапе обработки запроса. Например, если у нас есть несколько маршрутов, которые требуют аутентификации, или если нам нужно логировать все входящие запросы, то реализация этой логики в каждом маршруте может привести к дублированию кода и усложнению поддержки приложения. Это также увеличивает вероятность ошибок, так как любой измененный маршрут необходимо будет обновить в нескольких местах. Использование мидлваров позволяет решить эти проблемы.
Мидлвара - это функции, которые обрабатывают запросы и ответы в веб-приложениях. Они выполняются между получением запроса от клиента и отправкой ответа. Они могут выполнять различные задачи, такие как проверка прав доступа, логирование или преобразование данных в ответе
В этом уроке мы рассмотрим, как создавать и использовать мидлвары в Javalin, а также изучим примеры их применения
Оборачивание
Прежде чем перейти к изучению непосредственно мидлвар, разберем их принцип действия на примере обычных статических методов.
Представим, что у нас есть метод, который прибавляет 5 к аргументу:
Наша задача расширить функционал этого метода, при этом не меняя сам метод. Например, мы хотим прибавлять 5 к удвоенному значению аргумента. Чтобы решить эту задачу, мы можем написать новую функцию, которая будет внутри себя использовать уже существующую функцию:
Точно так же мы можем расширить и второй метод:
В общем случае расширение метода выглядит так:
Чтобы расширить поведение метода, нужно создать новый метод, который будет использовать исходный. Главное условие — интерфейсы обоих методов должны совпадать: количество и тип аргументов, а также тип возвращаемого результата должны быть одинаковыми. Тогда вы можете просто заменить в коде вызов одного метода на вызов другого, обернутого, и код продолжит работать без изменений, поскольку интерфейс остался прежним. В этом случае код, использующий ваш новый метод, не заметит, что он обернут и его не потребуется переписывать. Этот подход также называется декорированием и описывается в справочниках по шаблонам проектирования как "паттерн Декоратор".
По похожей идее работают мидлвары. Они расширяют функционал обработчиков запросов, оборачивая их в подобные методы. При этом оригинальный обработчик остается неизменным
Использование мидвар
Чтобы использовать мидлвары в Javalin, не нужно ничего устанавливать, фреймворк имеет встроенную поддержку мидлвар. Для добавления мидлвар в Javalin используются методы before() или after(). Метод before() используется для указания кода, который должен быть выполнен до основного обработчика запроса, а метод after() — после.
Рассмотрим пример кода с подключением мидлвары:
В приведенном примере подключена мидлвара, которая для каждого входящего запроса выводит в консоль сообщение с указанием пути. Также добавлена мидлвара, которая выполняется после обработки запроса и выводит в консоль сообщение, информируя о том, что ответ был успешно отправлен клиенту
Каждый раз, когда мы используем before() или after(), очередная мидлвара добавляется в общую цепочку. Каждый запрос, отправляемый на обработку в приложение, проходит через всю цепочку этих мидлвар

Каждая мидлвара представляет собой лямбда-функцию, которая принимает на вход параметр Context ctx. Через объект контекста она может обратиться к данным запроса или дополнить ответ. После того как мидлвара отработает, управление переходит к следующей по порядку мидлваре
В примере выше мы подключили мидлвары, одна из которых выводит в консоль сообщение, а другая добавляет кастомный заголовок X-Custom-Header в каждый ответ.
Запустим сервер и сделаем запрос:
При этом в консоли, где запущено приложение, мы можем увидеть вывод:
Обработчики
Самое интересное в мидлварах, что обработчики конкретных маршрутов — это тоже мидлвары. Но в отличие от мидлвар, которые выполняются для всех запросов, обработчики привязаны к конкретному маршруту
Такие мидлвары позволяют реализовывать базовый роутинг в приложении
Терминальная мидлвара
Далеко не всегда мы хотим двигаться вглубь по всей цепочке добавленных мидлвар. Более того, в какой-то момент одна из мидлвар должна взять обработку запроса на себя. Чтобы завершить обработку, используется метод skipRemainingHandlers(). После вызова этого метода движение по цепочке прекращается, все оставшиеся мидлвары для текущего запроса пропускаются и происходит отправка ответа
Например, хотим создать мидлвару для проверки наличия определенного параметра в запросе, не меняя при этом сам обработчик. Если параметр отсутствует, мы можем сразу отправить ответ с ошибкой и пропустить выполнение остальных мидлвар и обработчиков:
У такого поведения, когда есть цепочка функций и любая из них в процессе обработки может принять решение остановки цепочки и возврата ответа, есть имя. Такие цепочки называют chain responsibility, и это тоже паттерн
Рекомендуемые программы
Завершено
0 / 23



