The English version of quarkus.io is the official project site. Translated sites are community supported on a best-effort basis.
このページを編集

Spring Web APIのためのQuarkus エクステンション

RESTエンドポイントの定義には、Jakarta REST(旧称JAX-RS)アノテーションを使用することが推奨されていますが、Quarkusは、 spring-web エクステンションという形でSpring Webの互換性レイヤーを提供しています。

このガイドでは、よく知られているSpring Webアノテーションを利用して、QuarkusアプリケーションでRESTfulサービスを定義する方法を説明します。

前提条件

このガイドを完成させるには、以下が必要です:

このガイドを完成させるには、以下が必要です:

  • 約15分

  • IDE

  • JDK 17+がインストールされ、 JAVA_HOME が適切に設定されていること

  • Apache Maven 3.9.9

  • 使用したい場合は、 Quarkus CLI

  • ネイティブ実行可能ファイルをビルドしたい場合、MandrelまたはGraalVM(あるいはネイティブなコンテナビルドを使用する場合はDocker)をインストールし、 適切に設定していること

ソリューション

次の章で紹介する手順に沿って、ステップを踏んでアプリを作成することをお勧めします。ただし、完成した例にそのまま進んでも構いません。

Gitレポジトリをクローンするか git clone https://github.com/quarkusio/quarkus-quickstarts.gitアーカイブ をダウンロードします。

ソリューションは spring-web-quickstart ディレクトリ にあります。

Mavenプロジェクトの作成

まず、新しいプロジェクトが必要です。以下のコマンドで新規プロジェクトを作成します:

コマンドラインインタフェース
Maven
quarkus create app org.acme:spring-web-quickstart \ --extension='spring-web,rest-jackson' \ --no-code cd spring-web-quickstart

Gradleプロジェクトを作成するには、 --gradle または --gradle-kotlin-dsl オプションを追加します。

Quarkus CLIのインストールと使用方法の詳細については、 Quarkus CLI ガイドを参照してください。

mvn io.quarkus.platform:quarkus-maven-plugin:3.17.5:create \ -DprojectGroupId=org.acme \ -DprojectArtifactId=spring-web-quickstart \ -Dextensions='spring-web,rest-jackson' \ -DnoCode cd spring-web-quickstart

Gradleプロジェクトを作成するには、 -DbuildTool=gradle または -DbuildTool=gradle-kotlin-dsl オプションを追加します。

Windowsユーザーの場合:

  • cmdを使用する場合、(バックスラッシュ \ を使用せず、すべてを同じ行に書かないでください)。

  • Powershellを使用する場合は、 -D パラメータを二重引用符で囲んでください。例: "-DprojectArtifactId=spring-web-quickstart"

このコマンドは、プロジェクトを生成し、 spring-web エクステンションをインポートします。

すでにQuarkusプロジェクトが設定されている場合は、プロジェクトのベースディレクトリで以下のコマンドを実行することで、 spring-web エクステンションをプロジェクトに追加することができます。

コマンドラインインタフェース
Maven
Gradle
quarkus extension add spring-web,rest-jackson
./mvnw quarkus:add-extension -Dextensions='spring-web,rest-jackson'
./gradlew addExtension --extensions='spring-web,rest-jackson'

これにより、ビルドファイルに以下が追加されます:

pom.xml
build.gradle
<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-spring-web</artifactId> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-rest-jackson</artifactId> </dependency>
implementation("io.quarkus:quarkus-spring-web") implementation("io.quarkus:quarkus-rest-jackson")

quarkus-spring-web は、 quarkus-rest-jackson または quarkus-resteasy-jackson と共に使用する必要があります。

GreetingController

RESTエンドポイントを定義するためのSpring Webアノテーションを持つコントローラである 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"; } }

GreetingControllerTest

なお、コントローラのテストも作成されています:

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")); } }

アプリケーションをパッケージ化して実行する

アプリケーションを次のように実行します:

コマンドラインインタフェース
Maven
Gradle
quarkus dev
./mvnw quarkus:dev
./gradlew --console=plain quarkusDev

ブラウザで http://localhost:8080/greeting を開きます。

結果は {"message": "hello"} のようになります。

アプリケーションをネイティブ実行可能ファイルとして実行する

以下を使用して、ネイティブ実行可能ファイルを生成することができます:

コマンドラインインタフェース
Maven
Gradle
quarkus build --native
./mvnw install -Dnative
./gradlew build -Dquarkus.native.enabled=true

JSONを返すエンドポイントでその先へ

上の GreetingController は、非常にシンプルなエンドポイントの例でした。しかし、多くの場合、JSONコンテンツを返さなければなりません。次の例では、Spring RestControllerを使用して、これを実現しています。

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("/{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; } } }

対応するテストは次のようになります:

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サポートを使用する場合、 Jackson は自動的にクラスパスに追加され、適切に設定されることに注意してください。

OpenAPIとSwagger-UIの追加

quarkus-smallrye-openapi エクステンションを使うことで、 OpenAPISwagger-UIのサポートを追加することができます。

このコマンドを実行してエクステンションを追加:

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

これにより、 pom.xml に以下が追加されます:

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

これだけでRESTエンドポイントから基本的なOpenAPIスキーマドキュメントを生成するのには十分です:

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

生成されたOpenAPIスキーマのドキュメントが表示されます:

--- openapi: 3.0.1 info: title: Generated API version: "1.0" paths: /greeting: get: responses: "200": description: OK content: '*/*': 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

OpenAPI ガイド も参照してください。

MicroProfile OpenAPIアノテーションの追加

MicroProfile OpenAPIを使用して、スキーマをより良く文書化することができます。例えば、 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")) )

そして、エンドポイントをこのように記述します:

@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.1 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: '*/*': 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: '*/*': schema: $ref: '#/components/schemas/Greeting' components: schemas: Greeting: type: object properties: message: type: string

Swagger UIの使用

Swagger UIは、 Dev または Test モードで実行するとデフォルトで含まれており、オプションで Prod モードに追加することができます。詳細は Swagger UI ガイドをご覧ください。

localhost:8080/q/swagger-ui/ に移動すると、Swagger UIの画面が表示されます:

Swagger UI

サポートされているSpring Webの機能

Quarkusは現在、Spring Webが提供する機能のサブセットをサポートしています。具体的には、QuarkusはSpring WebのREST関連の機能をサポートしています( @Controller の代わりに @RestController を考えてみてください)。

アノテーション

下の表は、サポートされているアノテーションをまとめたものです:

Table 1. サポートされているSpring Webアノテーション
名前 コメント

@RestController

@RequestMapping

@GetMapping

@PostMapping

@PutMapping

@DeleteMapping

@PatchMapping

@RequestParam

@RequestHeader

@MatrixVariable

@PathVariable

@CookieValue

@RequestBody

@ResponseStatus

@ExceptionHandler

コントローラごとではなく、@RestControllerAdviceクラスでのみ使用可能です

@RestControllerAdvice

サポートされているのは@ExceptionHandler機能のみです

コントローラメソッドの戻り値の型

以下のメソッドの戻り値の型がサポートされています:

  • プリミティブ型

  • 文字列 (リテラルとして使用されます。Spring MVC ビューのサポートはありません)

  • JSON 経由でシリアライズされる POJO クラス

  • org.springframework.http.ResponseEntity

コントローラメソッドのパラメーターの型

前の表にある適切なSpring Webアノテーションでアノテーションできるメソッドパラメータに加えて、 jakarta.servlet.http.HttpServletRequestjakarta.servlet.http.HttpServletResponse もサポートされています。ただし、これを機能させるためには、 quarkus-undertow の依存関係を追加する必要があります。

例外ハンドラーメソッドの戻り値の型

以下のメソッドの戻り値の型がサポートされています:

  • org.springframework.http.ResponseEntity

  • java.util.Map

Spring ExceptionHandler javadoc に記載されているその他の戻り値型はサポートされていません。

例外ハンドラーメソッドのパラメーターの型

以下のパラメーターの型がサポートされています(順不同):

  • 例外の引数:一般的な Exception として、またはより具体的な例外として宣言されています。これは、アノテーション自体が value() を使って例外の型を狭めていない場合、マッピングのヒントにもなります。

  • リクエストおよび/またはレスポンスオブジェクト(通常、サーブレットAPIからのもの)。ServletRequest / HttpServletRequest のように、 特定のリクエスト/レスポンス型を選択することができます。Servlet APIを使用するには、 quarkus-undertow の依存関係を追加する必要があります。

Spring ExceptionHandler javadoc に記載されているその他のパラメーターの型はサポートされていません。

重要な技術的注意点

Quarkus での Spring サポートは、Spring Application Context を開始せず、Spring インフラストラクチャークラスも実行しないことに注意してください。Spring クラスとアノテーションは、メタデータの読み取りにのみ使用されるか、ユーザーコードメソッドの戻り値の型またはパラメーター型として使用されます。エンドユーザーにとってそれが意味することは、任意の Spring ライブラリーを追加しても効果がないということです。さらに、Spring インフラストラクチャークラス (たとえば、org.springframework.beans.factory.config.BeanPostProcessor など) は実行されません。

変換テーブル

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

Spring Jakarta REST コメント

@RestController

Jakarta RESTには同等のものはありません。クラスを@Pathでアノテーションするので十分です。

@RequestMapping(path="/api")

@Path("/api")

@RequestMapping(consumes="application/json")

@Consumes("application/json")

@RequestMapping(produce="application/json")

@Produces("application/json")

@RequestParam

@QueryParam

@PathVariable

@PathParam

@RequestBody

Jakarta RESTに同等のものはありません。リクエスト本体に対応するメソッドパラメータは、Jakarta RESTではアノテーションを必要とせずハンドリングされます。

@RestControllerAdvice

Jakarta RESTに同等のものはありません。

@ResponseStatus

Jakarta RESTに同等のものはありません。

@ExceptionHandler

Jakarta RESTには同等のアノテーションはありません。例外の処理には jakarta.ws.rs.ext.ExceptionMapper の実装によってハンドリングされます。

関連コンテンツ