Spring Web API の Quarkus エクステンションの使用

Red Hat build of Quarkus 1.11

概要

Spring Web のアノテーションを使用し、Quarkus アプリケーションで RESTful サービスのエンドポイントを作成します。

はじめに

アプリケーション開発者は、Spring Web アノテーションを使用して、Quarkus アプリケーションで RESTful サービスを定義できます。

Red Hat ドキュメントへのフィードバック (英語のみ)

弊社の技術的な内容についてのフィードバックに感謝します。ご意見をお聞かせください。コメントの追加、Insights の提供、誤字の修正、および質問を行う必要がある場合は、ドキュメントで直接行うこともできます。

注記

Red Hat アカウントがあり、カスタマーポータルにログインしている必要があります。

カスタマーポータルからドキュメントのフィードバックを送信するには、以下の手順を実施します。

  1. Multi-page HTML 形式を選択します。
  2. ドキュメントの右上にある Feedback ボタンをクリックします。
  3. フィードバックを提供するテキストのセクションを強調表示します。
  4. ハイライトされたテキストの横にある Add Feedback ダイアログをクリックします。
  5. ページの右側のテキストボックスにフィードバックを入力し、Submit をクリックします。

フィードバックを送信すると、自動的に問題の追跡が作成されます。Submit をクリックすると表示されるリンクを開き、問題の監視を開始するか、さらにコメントを追加します。

貴重なフィードバックにご協力いただきありがとうございます。

多様性を受け入れるオープンソースの強化

Red Hat では、コード、ドキュメント、Web プロパティーにおける配慮に欠ける用語の置き換えに取り組んでいます。まずは、マスター (master)、スレーブ (slave)、ブラックリスト (blacklist)、ホワイトリスト (whitelist) の 4 つの用語の置き換えから始めます。この取り組みは膨大な作業を要するため、今後の複数のリリースで段階的に用語の置き換えを実施して参ります。詳細は、Red Hat CTO である Chris Wright のメッセージ をご覧ください。

Quarkus は、Spring Web のアノテーションを使用してアプリケーションの REST エンドポイントを定義するための互換レイヤーを提供します。この機能は、デフォルトの JAX-RS アノテーションを使用して REST エンドポイントを定義する代わりに、quarkus-spring-web エクステンションによって提供されます。

重要

Quarkus の Spring 互換レイヤーは、アプリケーションの起動時に Spring Application Context を起動したり、Spring が提供するインフラストラクチャークラスを実行したりしません (例: org.springframework.beans.factory.config.BeanPostProcessor)。Quarkus は Spring クラスおよびアノテーションからのメタデータのみを読み取り、Spring 固有のユーザーコードメソッドの戻り値の型とパラメーター型を解析することができます。ただし、Spring Framework の一部である任意のライブラリーを Quarkus アプリケーションに追加する場合、Quarkus ではこのようなライブラリーを使用するように設計されていないため、適切に機能しません。

注記

本書に従い、Spring Web API の Quarkus エクステンションを使用するサンプルを作成するか、完了したサンプルをダウンロードして表示することができます。完了した Quarkus Spring Web のサンプルを表示するには、これを アーカイブ としてダウンロードするか、または Quarkus サンプル Git リポジトリー をクローンします。Spring Web サンプルは、spring-web-quickstart ディレクトリー にあります。

第1章 前提条件

  • OpenJDK 11 がインストールされ、システムで OpenJDK がインストールされているディレクトリーへのパスと一致するように、JAVA_HOME 環境変数が設定されている。
  • Apache Maven 3.6.2 以降がインストールされている。

第2章 Spring Web サンプルの Maven プロジェクトの作成

新しい Quarkus プロジェクトを作成して、REST コントローラークラスを自動的に生成し、Quarkus Maven プラグインを使用して単一のコマンドで quarkus-spring-web 依存関係を追加できます。pom.xml ファイルを更新して、REST コントローラークラスと、REST コントローラーテストクラスを手動で作成することもできます。

手順

  • このセクションに示されている以下のアプローチのいずれかを使用して、Quarkus Spring Web のサンプル Maven プロジェクトを作成します。

    • Maven プロジェクトがない場合は、Quarkus Maven プラグインを使用して新しい Maven プロジェクトを作成できます。以下のコマンドを入力し、以下を実行します。

      • Maven プロジェクトディレクトリー構造を作成する
      • アプリケーションの REST エンドポイントを定義する org.acme.spring.web.GreetingController クラスを作成する
      • quarkus-spring-web エクステンションをインポートする

        <project_name> は、プロジェクトファイルが含まれるディレクトリーの名前に置き換える必要があります。

        mvn io.quarkus:quarkus-maven-plugin:1.11.7.Final-redhat-00009:create \
            -DprojectGroupId=org.acme \
            -DprojectArtifactId=<project_name> \
            -DclassName="org.acme.spring.web.GreetingController" \
            -Dpath="/greeting" \
            -Dextensions="spring-web"
    • Quarkus Maven プロジェクトがすでにある場合は、コマンドラインを使用して quarkus-spring-web エクステンションをこれに追加する必要があります。
    1. プロジェクトのルートディレクトリーに移動します。

      cd <project_name>
    2. quarkus-spring-web エクステンションをプロジェクトの pom.xml ファイルに追加します。

      ./mvnw quarkus:add-extension -Dextensions="spring-web"

      このコマンドを使用して、以下のエントリーを pom.xml ファイルに追加します。

      pom.xml

      <dependency>
          <groupId>io.quarkus</groupId>
          <artifactId>quarkus-spring-web</artifactId>
      </dependency>

第3章 GreetingController のメインクラスおよびテストクラスの作成

コマンドラインでプロジェクトを作成すると、Quarkus Maven プラグインは、REST エンドポイントを定義する Spring Web アノテーションを使用した GreetingController クラスファイルおよび GreetingController のユニットテストが含まれるクラスファイルを自動的に生成します。

手順

  1. 以下のコードを含む src/main/java/org/acme/spring/web/GreetingController.java ファイルを作成します。

    src/main/java/org/acme/spring/web/GreetingController.java

    package org.acme.spring.web;
    
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @RequestMapping("/greeting")
    public class GreetingController {
    
        @GetMapping
        public String hello() {
            return "Hello Spring";
        }
    }

  2. 以下のコードを含む src/test/java/org/acme/spring/web/GreetingControllerTest.java ファイルを作成します。

    src/test/java/org/acme/spring/web/GreetingControllerTest.java

    package org.acme.spring.web;
    
    import io.quarkus.test.junit.QuarkusTest;
    import org.junit.jupiter.api.Test;
    
    import static io.restassured.RestAssured.given;
    import static org.hamcrest.CoreMatchers.is;
    
    @QuarkusTest
    public class GreetingControllerTest {
    
        @Test
        public void testHelloEndpoint() {
            given()
              .when().get("/greeting")
              .then()
                 .statusCode(200)
                 .body(is("Hello Spring"));
        }
    
    }

第4章 Spring Web サンプルのコンパイルおよび起動

Quarkus Maven プラグインを使用してサンプルアプリケーションをコンパイルして起動します。アプリケーションを ネイティブ実行可能ファイル としてコンパイルして起動することもできます。

手順

  1. プロジェクトのルートディレクトリーに移動します。

    cd <project_name>
  2. Quarkus Maven プラグインを使用して、開発モードでアプリケーションを実行します。

    ./mvnw compile quarkus:dev
  3. http://localhost:8080/greeting に移動します。以下のメッセージがブラウザーに表示されます。

    Hello Spring

第5章 JSON レスポンスを返すように GreetingController を設定する

Spring Web サンプルの設定時に自動的に生成される GreetingController は、テキスト文字列をレスポンスとして返す単純なエンドポイントです。より複雑なアプリケーションでは、レスポンスを JSON 形式で返すように REST コントローラーを設定しなければならない場合があります。以下の例は、JSON コンテンツを返すように Spring RestController を設定する方法を示しています。

手順

  1. 以下の例のように、GreetingController クラスを展開します。拡張されたクラスは、greeting および名前が含まれる JSON 形式のレスポンスを返します。Spring Web から PathVariable アノテーションクラスをインポートして、設定が正しく機能することを確認する必要があります。

    src/main/java/org/acme/spring/web/GreetingController.java

    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @RequestMapping("/greeting")
    public class GreetingController {
    
        @GetMapping
        public String hello() {
            return "hello";
        }
    
        @GetMapping("/{name}")
        public Greeting hello(@PathVariable(name = "name") String name) {
            return new Greeting("hello " + name);
        }
    
        public static class Greeting {
            private final String message;
    
            public Greeting(String message) {
                this.message = message;
            }
    
            public String getMessage(){
                return message;
            }
        }
    }

  1. REST エンドポイントに変更を加える場合は、REST エンドポイントのユニットテストが含まれるクラスファイルも更新する必要があります。

    src/test/java/org/acme/spring/web/GreetingControllerTest.java

    package org.acme.spring.web;
    
    import io.quarkus.test.junit.QuarkusTest;
    import org.junit.jupiter.api.Test;
    
    import static io.restassured.RestAssured.given;
    import static org.hamcrest.CoreMatchers.is;
    
    @QuarkusTest
    public class GreetingControllerTest {
    
        @Test
        public void testHelloEndpoint() {
            given()
              .when().get("/greeting/quarkus")
              .then()
                .statusCode(200)
                .body("message", is("hello quarkus"));
        }
    
    }

    Quarkus で Spring Web 互換レイヤーを使用すると、com.fasterxml:jackson.core 依存関係がアプリケーションのクラスパスに自動的に追加されて設定される点に留意してください。

第6章 Spring Web サンプルの OpenAPI および Swagger-UI サポートの有効化

Swagger-UI を使用した REST エンドポイントの OpenAPI スキーマドキュメントの生成へのサポートは、quarkus-smallrye-openapi エクステンションを追加することで、アプリケーションに追加できます。

手順

  1. 以下のコマンドを入力し、quarkus-smallrye-openapi エクステンションを Spring Web サンプルの依存関係として追加します。REST エンドポイントから基本的な OpenAPI スキーマドキュメントを生成するには、エクステンションを追加するだけで十分です。

    ./mvnw quarkus:add-extension -Dextensions="io.quarkus:quarkus-smallrye-openapi"

    このコマンドにより、以下の依存関係が pom.xml に追加されます。

    pom.xml

    <dependency>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-smallrye-openapi</artifactId>
    </dependency>

  2. 以下のコマンドを入力して、/q/openapi からスキーマドキュメントを取得します。

    curl http://localhost:8080/q/openapi

    YAML 形式の生成された OpenAPI スキーマドキュメントでレスポンスを受け取ります。

    ---
    openapi: 3.0.3
    info:
      title: Generated API
      version: "1.0"
    paths:
      /greeting:
        get:
          responses:
            "200":
              description: OK
              content:
                text/plain:
                  schema:
                    type: string
      /greeting/{name}:
        get:
          parameters:
          - name: name
            in: path
            required: true
            schema:
              type: string
          responses:
            "200":
              description: OK
              content:
                application/json:
                  schema:
                    $ref: '#/components/schemas/Greeting'
    components:
      schemas:
        Greeting:
          type: object
          properties:
            message:
              type: string

第7章 MicroProfile OpenAPI アノテーションの REST コントローラーコードへの追加

MicroProfile OpenAPI アノテーションを REST コントローラーコードに追加し、REST エンドポイントの詳細な OpenAPI スキーマを生成できます。

手順

  1. @OpenApiDefinition アノテーションを GreetingController のクラスレベルに追加します。アノテーションの例に示されているデータを含めます。

    @OpenAPIDefinition(
        info = @Info(
            title="Greeting API",
            version = "1.0.1",
            contact = @Contact(
                name = "Greeting API Support",
                url = "http://exampleurl.com/contact",
                email = "techsupport@example.com"),
            license = @License(
                name = "Apache 2.0",
                url = "https://www.apache.org/licenses/LICENSE-2.0.html"))
    )
  2. @Tag アノテーションを使用してエンドポイント定義にアノテーションを付けます。エンドポイントごとに名前と説明を指定します。

    @Tag(name = "Hello", description = "Just say hello")
    @GetMapping(produces=MediaType.TEXT_PLAIN_VALUE)
    public String hello() {
        return "hello";
    }
    
    @GetMapping(value = "/{name}", produces=MediaType.APPLICATION_JSON_VALUE)
    @Tag(name = "Hello to someone", description = "Just say hello to someone")
    public Greeting hello(@PathVariable(name = "name") String name) {
        return new Greeting("hello " + name);
    }

    アノテーションで指定したデータは、生成された OpenAPI スキーマに表示されます。

    openapi: 3.0.3
    info:
      title: Greeting API
      contact:
        name: Greeting API Support
        url: http://exampleurl.com/contact
        email: techsupport@example.com
      license:
        name: Apache 2.0
        url: https://www.apache.org/licenses/LICENSE-2.0.html
      version: 1.0.1
    tags:
    - name: Hello
        description: Just say hello
    - name: Hello to someone
        description: Just say hello to someone
    paths:
      /greeting:
        get:
          tags:
          - Hello
          responses:
            '200':
              description: OK
              content:
                text/plain:
                  schema:
                    type: string
      /greeting/{name}:
        get:
          tags:
          - Hello to someone
          parameters:
          - name: name
            in: path
            required: true
            schema:
              type: string
          responses:
            '200':
              description: OK
              content:
                application/json:
                  schema:
                    $ref: '#/components/schemas/Greeting'
    
    components:
      schemas:
        Greeting:
          type: object
          properties:
            message:
              type: string

第8章 Quarkus でサポートされる Spring Web アノテーションの概要

Quarkus の Spring 互換レイヤーは、Spring Web が提供する機能のサブセットを限定的にサポートします。具体的には、Quarkus は Spring Web の REST 関連のアノテーションのみをサポートします (例: @RestController はサポートしますが @Controller はサポートません)。

Quarkus は以下の Spring Web のアノテーションをサポートします。

  • @RestController
  • @RequestMapping
  • @GetMapping
  • @PostMapping
  • @PutMapping
  • @DeleteMapping
  • @PatchMapping
  • @RequestParam
  • @RequestHeader
  • @MatrixVariable
  • @PathVariable
  • @CookieValue
  • @RequestBody
  • @ResponseStatus
  • @ExceptionHandler [1]
  • @RestControllerAdvice [2]


[1] @RestControllerAdvice クラスでのみ使用でき、コントローラーごとでは使用できません。
[2] Quarkus では、@ExceptionHandler 機能のみがサポートされます。

第9章 Spring Web アノテーションと JAX-RS アノテーションの概要

以下の表は、Spring Web アノテーションを JAX-RS アノテーションに変換する方法を示しています。

表9.1 Spring Web アノテーションと JAX-RS アノテーション

SpringJAX-RS注記

@RestController

 

JAX-RS アノテーションはありません。@Path でクラスにアノテーションを付ければ十分です。

@RequestMapping(path="/api")

@Path("/api")

 

@RequestMapping(consumes="application/json")

@Consumes("application/json")

 

@RequestMapping(produces="application/json")

@Produces("application/json")

 

@RequestParam

@QueryParam

 

@PathVariable

@PathParam

 

@RequestBody

 

JAX-RS にアノテーションはありません。リクエストのボディーに対応するメソッドパラメーターは、アノテーションを必要とすることなく JAX-RS で処理されます。

@RestControllerAdvice

 

JAX-RS にアノテーションはありません。

@ResponseStatus

 

JAX-RS にアノテーションはありません。

@ExceptionHandler

 

JAX-RS には同等のアノテーションはありません。例外は、javax.ws.rs.ext.ExceptionMapper を実装することで処理されます。

第10章 Quarkus でサポートされるコントローラーメソッドのパラメーター型

前述の表の適切な Spring Web アノテーションでアノテーションを付けることができるメソッドパラメーターの他に、javax.servlet.http.HttpServletRequest および javax.servlet.http.HttpServletResponse もサポートされます。ただし、機能するようにするには、ユーザーは quarkus-undertow 依存関係を追加する必要があります。

第11章 Quarkus でサポートされるコントローラーメソッドの戻り値の型

Quarkus で Spring Web を使用する場合は、以下のメソッドの戻り値の型がサポートされます。

  • プリミティブ型
  • 文字列 (リテラルとして使用します。Quarkus は Spring MVC ビューをサポートしません)
  • JSON を使用してシリアライズされる POJO クラス
  • org.springframework.http.ResponseEntity

第12章 Quarkus でサポートされる例外ハンドラーメソッドのパラメーター型

Spring Web API の Quarkus エクステンションは、以下の例外ハンドラーメソッドのパラメーター型をサポートします。(型が一覧表示されている順序は任意であり、個々のパラメーター型を使用する際の優先順位を反映したものではありません。)

  • 例外引数: 一般的な Exception またはより具体的な例外として宣言されます。これは、アノテーション自体が value() を使用して例外型を指定していない場合に、マッピングヒントとしても機能します。
  • (通常は Servlet API からの) リクエストまたはレスポンスオブジェクト (あるいは両方)。特定のリクエストまたはレスポンス型を選択できます (例: ServletRequest または HttpServletRequest)。Servlet API を使用するには、quarkus-undertow 依存関係をプロジェクトに追加する必要があります。

Quarkus では、Spring ExceptionHandler Java API ドキュメント に記載されている他のパラメーター型はサポートされません。

第13章 Quarkus でサポートされる例外ハンドラーメソッドの戻り値の型

Quarkus で Spring Web を使用する場合は、以下のメソッドの戻り値の型がサポートされます。

  • org.springframework.http.ResponseEntity
  • java.util.Map

Quarkus では、Spring ExceptionHandler Java API ドキュメント に記載されている他の戻り値のタイプはサポートされません。

第14章 関連情報

改訂日時: 2023-05-16

法律上の通知

Copyright © 2023 Red Hat, Inc.
The text of and illustrations in this document are licensed by Red Hat under a Creative Commons Attribution–Share Alike 3.0 Unported license ("CC-BY-SA"). An explanation of CC-BY-SA is available at http://creativecommons.org/licenses/by-sa/3.0/. In accordance with CC-BY-SA, if you distribute this document or an adaptation of it, you must provide the URL for the original version.
Red Hat, as the licensor of this document, waives the right to enforce, and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent permitted by applicable law.
Red Hat, Red Hat Enterprise Linux, the Shadowman logo, the Red Hat logo, JBoss, OpenShift, Fedora, the Infinity logo, and RHCE are trademarks of Red Hat, Inc., registered in the United States and other countries.
Linux® is the registered trademark of Linus Torvalds in the United States and other countries.
Java® is a registered trademark of Oracle and/or its affiliates.
XFS® is a trademark of Silicon Graphics International Corp. or its subsidiaries in the United States and/or other countries.
MySQL® is a registered trademark of MySQL AB in the United States, the European Union and other countries.
Node.js® is an official trademark of Joyent. Red Hat is not formally related to or endorsed by the official Joyent Node.js open source or commercial project.
The OpenStack® Word Mark and OpenStack logo are either registered trademarks/service marks or trademarks/service marks of the OpenStack Foundation, in the United States and other countries and are used with the OpenStack Foundation's permission. We are not affiliated with, endorsed or sponsored by the OpenStack Foundation, or the OpenStack community.
All other trademarks are the property of their respective owners.