web-dev-qa-db-ja.com

Spring 5WebFluxの@ControllerとRouterFunctionの違い

Spring5でHTTPエンドポイントを公開する方法は2つあります。

  1. @Controllerまたは@RestControllerは、コントローラーのクラスを作成します。例:.
@RestController
@RequestMapping("persons")
public class PersonController { 

    @Autowired
    private PersonRepo repo;

    @GetMapping("/{id}")
    public Mono<Person> personById(@PathVariable String id){
        retrun repo.findById(id);
    }
}
  1. RouterFunctionsを使用して@Configurationクラスにルーティングします。
@Bean
public RouterFunction<ServerResponse> personRoute(PersonRepo repo) {
    return route(GET("/persons/{id}"), req -> Mono.justOrEmpty(req.pathVariable("id"))                                             
                                                 .flatMap(repo::getById)
                                                 .flatMap(p -> ok().syncBody(p))
                                                 .switchIfEmpty(notFound().build()));
}

誰かのアプローチを使用することにパフォーマンスの違いはありますか?アプリケーションを最初から作成する場合は、どちらを使用すればよいですか。

15
Deepak Kumar
  • プログラミングパラダイム:命令型と関数型

@Controllerまたは@RestControllerアノテーションの場合、マッピングに(だけでなく)アノテーションを使用し、その結果として副作用(で許可されていない)を使用するアノテーションベースのモデルに同意します。機能的な世界)APIを機能させるため。このような副作用は、リクエストの本文に組み込みのBean検証を提供する@Validアノテーション、またはコントローラー全体のルートパスを含む@RequestMappingである可能性があります。

一方、ルーター関数を使用すると、API実装に関する副作用で構成されるアノテーションを取り除き、それを機能チェーンrouter -> handlerに直接委任します。これらの2つは、一連のイベントと2つの主人公、これらのイベントの発行者とサブスクライバーという基本的なリアクティブブロックを構築するのに最適です。

  • MVCレガシー:サーブレットスタックとNettyスタック

@Controllerについて話しているとき、私たちは通常、同期Java world:ServletsServletContextServletContainerInitializerDispatcherServletなど。アプリケーションをリアクティブにするためにコントローラーからMonoを返す場合でも、Servlet 3.0をサポートするJava.nio.*仕様で再生します。 ] _そしてJettyTomcatなどの同じサーブレットコンテナで実行されます。その後、ここでは、対応するデザインパターンとアプローチを使用してWebアプリを構築します。

一方、RouterFunctionは、async Java world -- Netty とそのChannel Modelに由来する真のリアクティブアプローチに触発されました。

その後、リアクティブ環境用の新しいクラスのセットとそのAPIが登場しました: ServerRequestServerResponseWebFilter など。私の場合、これらは、フレームワークを維持し、新しいWebシステム要件を理解してきた過去数年間に基づいてSpringチームによって設計されました。これらの要件の名前は Reactive Manifesto です。

実際のケース

最近、私のチームは、 SwaggerRouterFucntionエンドポイントと統合することが不可能であるという問題に直面しました。 @Controlersに賛成する可能性がありますが、Springチームはソリューションを導入しました Spring REST Docs リアクティブに簡単に接続できます WebTestClient 。ここでWord'connected 'を使用すると、背後にある真のリアクティブな意味に従います。オーバーロードされた構成と副作用アノテーションを備えたSwaggerの代わりに、作業コードにまったく触れることなく、テストでAPIドキュメントを簡単に作成できます。

最終ビット

パフォーマンスへの影響がないため、「何を使用するかは個人の好みに完全に基づいています」のようなものが聞こえる可能性があります。そして私は、それが2つの選択肢の中で実際に個人的な好みであることに同意します。つまり、10年間同じドメインにとどまるようにしたときに、前進するか後退するかです。 @Controllerの事後対応サポートは、古いプロジェクトが何らかの形で時間の要件に適合し、少なくとも移行の機会を持つことを可能にするために、Springチームによって行われたと思います。 Webアプリケーションを最初から作成する場合は、導入されたリアクティブスタックを躊躇せずに使用してください。

2