Парадигма программирования: императив против функционального
В случае с аннотациями @Controller
или @RestController
мы согласны с моделью на основе аннотаций, в которой мы используем аннотации для сопоставлений (и не только) и, как следствие, побочные эффекты (что недопустимо в функциональном мире), чтобы наш API работал. . Такими побочными эффектами могут быть @Valid
аннотация, обеспечивающая встроенную проверку bean-компонентов для тел запросов, или @RequestMapping
корневой путь для всего контроллера.
С другой стороны, с помощью функций маршрутизатора мы избавляемся от аннотаций, которые содержат какие-либо побочные эффекты с точки зрения реализации API, и делегируем их непосредственно функциональной цепочке: router -> handler
. Эти два идеально подходят для построения базового реактивного блока: последовательность событий и два главных героя, издатель и подписчик на эти события.
Наследие MVC: стек сервлетов против стека Netty
Когда мы говорим о @Controller
, я бы сказал, что мы обычно думаем в терминах синхронного мира Java: Servlets
, ServletContext
, ServletContainerInitializer
, DispatcherServlet
и т. Д. Даже если мы вернем Mono
из контроллера, чтобы сделать наше приложение реактивным, мы все равно будем играть в терминах спецификации Servlet 3.0
, которая поддерживает java.nio.*
и работает в тех же контейнерах сервлетов, как Jetty
или Tomcat
. Впоследствии здесь мы будем использовать соответствующие шаблоны проектирования и подходы для создания веб-приложений.
RouterFunction
, с другой стороны, был вдохновлен истинным реактивным подходом, который происходит из мира асинхронной Java - Netty и ее Channel Model
.
Впоследствии появился новый набор классов и их API для реактивной среды: ServerRequest, ServerResponse, WebFilter и другие. Что касается меня, они были разработаны командой Spring в соответствии с предыдущими годами поддержки фреймворка и понимания требований новых веб-систем. Эти требования называются Reactive Manifesto.
Сценарий использования
Недавно моя команда столкнулась с проблемой невозможности интеграции Swagger с RouterFucntion
конечными точками. Он мог проголосовать за @Controlers
, но команда Spring представила свое решение - Spring REST Docs, которое могло быть легко подключается к реактивному WebTestClient. И я использую здесь слово «подключен», потому что оно следует истинному реактивному значению: вместо Swagger с его перегруженными конфигурациями и аннотациями побочных эффектов вы легко можете создавать свои документы API в тестах, вообще не касаясь своего рабочего кода.
Обновление 2020: несмотря на то, что теперь Spring Webflux уже может быть интегрирован с Swagger с последующим использованием спецификации OpenAPI, ему по-прежнему не хватает простоты конфигурации и прозрачности, что, по моему скромному мнению, является следствием быть частью архаичного подхода MVC.
Закрытие (мнение)
Из-за отсутствия влияния на производительность, скорее всего, вы услышите что-то похожее на «это абсолютно зависит от индивидуальных предпочтений, что использовать». И я согласен с тем, что это действительно индивидуальное предпочтение среди двух вариантов: движение вперед или движение назад, когда вы позволяете себе оставаться в одной и той же сфере в течение десяти лет. Я думаю, что реактивная поддержка @Controller
была сделана командой Spring, чтобы старые проекты как-то соответствовали требованиям времени и имели хотя бы возможность для миграции. Если вы собираетесь создать веб-приложение с нуля, не сомневайтесь и используйте представленный реактивный стек.
person
Serhii Povísenko
schedule
27.07.2019