Micronautでリクエストを受け取る方法!@Getと@PathVariableの基礎を初心者向けに徹底解説
生徒
「MicronautでGETリクエストを受け取る方法を教えてください!URLの一部を変数として受け取ることもできるんですか?」
先生
「Micronautでは@Getアノテーションを使ってGETリクエストを受け取ることができます。URLの一部を変数として受け取るには、パスパラメータという仕組みを使います。」
生徒
「パスパラメータってどうやって書くんですか?Springの@PathVariableみたいなものですか?」
先生
「そうです!Micronautでも似た書き方ができます。URLに波括弧でパラメータ名を書くだけで、メソッドの引数に自動的に値が渡されます。実際のコードを見ながら順番に理解していきましょう!」
生徒
「複数のパスパラメータを同時に受け取ることもできますか?」
先生
「もちろんできます!URLに複数の波括弧を書いて、メソッドの引数を増やすだけです。ひとつひとつ丁寧に説明していきますね!」
1. MicronautにおけるGETリクエストとは何か
ウェブアプリケーション開発において、HTTPリクエストはクライアントとサーバーがデータをやり取りするための基本的な仕組みです。中でもGETリクエストは、サーバーからデータを取得するときに使われる最も基本的なリクエスト方式です。ブラウザでURLを入力してページを開くときも、内部的にはGETリクエストが発生しています。
Micronautはマイクロサービスやクラウドネイティブなアプリケーション開発に特化したJavaフレームワークです。起動速度の速さとメモリ消費の少なさが大きな特徴で、従来のSpring Frameworkとは異なり、コンパイル時にDI(依存性の注入)や設定処理を行います。そのため実行時のオーバーヘッドが非常に小さく、コンテナ環境やサーバーレス環境との相性が抜群です。
MicronautでGETリクエストを受け取るには、コントローラクラスのメソッドに@Getアノテーションを付けます。このアノテーションはMicronautにそのメソッドがGETリクエストを処理することを伝える役割を持ちます。設定はこれだけで、余計な設定ファイルを書く必要はありません。シンプルな記述でエンドポイントを作れるのがMicronautの魅力のひとつです。
これからGETリクエストの受け取り方を基本から順番に説明していきます。初めてMicronautを触る方でも理解できるよう、サンプルコードを交えながら丁寧に解説します。
2. @Getアノテーションの基本的な使い方
@Getアノテーションは、Micronautのコントローラメソッドに付けることでそのメソッドをGETリクエストのハンドラとして登録します。アノテーションの引数にはURLのパスを文字列で指定します。パスを省略した場合は、コントローラの@Controllerアノテーションで指定したベースパスがそのまま使われます。
最もシンプルな例を見てみましょう。下記のコードでは、/messageというパスにGETリクエストが来たとき、固定の文字列を返すエンドポイントを作っています。
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
@Controller("/message")
public class MessageController {
@Get
public String getMessage() {
return "Micronautへようこそ!GETリクエストを受け取りました。";
}
}
このコードを動かすと、ブラウザやcurlコマンドでhttp://localhost:8080/messageにアクセスしたときに下記のような結果が返ってきます。
Micronautへようこそ!GETリクエストを受け取りました。
たったこれだけの記述でGETエンドポイントが完成します。@Controllerでベースパスを決め、@GetでそのパスへのGETリクエストを受け取るメソッドを定義する、という流れを覚えておきましょう。
また、@Getの引数にサブパスを指定することで、ベースパスの下に追加のパスを設定することもできます。たとえば@Controller("/api")のクラスの中に@Get("/welcome")と書いたメソッドは、/api/welcomeというURLで受け取れます。このように階層的にパスを組み立てることで、APIの構造を整理して管理しやすくなります。
3. パスパラメータの仕組みを理解する
固定のURLだけでなく、URLの一部を動的に変えてリクエストを受け取りたい場合があります。たとえば「ユーザーIDが1のユーザー情報を取得する」「商品IDが5の商品詳細を表示する」といったケースです。このようなときに活躍するのがパスパラメータという仕組みです。
パスパラメータとは、URLの一部分をプレースホルダー(変数の置き場所)にして、そこに入った値をメソッドの引数として受け取る仕組みのことです。Micronautでは、@Getのパス文字列の中で変数にしたい部分を波括弧で囲むことでパスパラメータを定義できます。
たとえば@Get("/{id}")と書くと、URLの該当部分に入った値がidという名前でメソッドに渡されます。メソッドの引数名をパスパラメータの名前と同じにするだけで、Micronautが自動的に値を割り当ててくれます。
Springを使ったことがある方は@PathVariableアノテーションに馴染みがあると思いますが、Micronautでは引数名とパスパラメータ名が一致していれば特別なアノテーションを付けなくても自動的にバインドされます。明示的にアノテーションを付けたい場合は後ほど紹介します。
4. パスパラメータを使った実践的なサンプルコード
パスパラメータの具体的な使い方をサンプルコードで確認してみましょう。下記の例では、ユーザーIDをURLから受け取り、そのIDを使ったメッセージを返すエンドポイントを作っています。
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
@Controller("/users")
public class UserController {
@Get("/{userId}")
public String getUser(Long userId) {
return "ユーザーID「" + userId + "」の情報を取得しました!";
}
}
このコードでは/users/{userId}というパスを定義しています。実際に/users/42というURLにアクセスすると、下記のような結果が返ってきます。
ユーザーID「42」の情報を取得しました!
URLの42という部分がメソッドの引数userIdにLong型として自動的に変換されて渡されています。Micronautは文字列として受け取ったURLの値を、引数の型に合わせて自動的に型変換してくれます。LongだけでなくIntegerやStringなど、様々な型に対応しています。
もし型変換に失敗した場合(たとえば数値が期待されているところに文字列を入れた場合)は、Micronautが自動的に400番台のエラーレスポンスを返してくれます。エラーハンドリングも自動で行ってくれるので安心して使えます。
5. 複数のパスパラメータを同時に受け取る方法
ひとつのURLに複数のパスパラメータを含めることもできます。たとえば「カテゴリIDと商品IDを両方URLで指定して商品を取得する」といったケースです。このような場合は、パス文字列に複数の波括弧を書き、メソッドの引数を増やすだけで対応できます。
下記のサンプルでは、カテゴリ名と商品IDという二つのパスパラメータを受け取るエンドポイントを作っています。
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
@Controller("/shop")
public class ShopController {
@Get("/{category}/{productId}")
public String getProduct(String category, Integer productId) {
return "カテゴリ「" + category + "」の商品ID「" + productId + "」を取得しました!";
}
}
このコードで/shop/electronics/101というURLにアクセスすると、下記のような結果が返ってきます。
カテゴリ「electronics」の商品ID「101」を取得しました!
URLのelectronicsがcategory引数に、101がproductId引数にそれぞれ自動的にマッピングされています。引数の順番はパスの順番と対応している必要はなく、引数名がパスパラメータの名前と一致していれば正しく割り当てられます。
複数のパスパラメータを使う場合も、記述量が増えることはほとんどありません。パスの定義と引数の追加だけで済むため、シンプルなコードを保ちながら柔軟なURLの設計ができます。
6. @PathVariableアノテーションを明示的に使う場面
Micronautでは、引数名とパスパラメータ名が一致していれば@PathVariable(正確にはMicronautの場合は@PathVariableではなく引数名による自動バインド)を省略できます。しかし、引数名をパスパラメータ名と異なる名前にしたい場合や、コードの意図を明確にしたい場合には、明示的にアノテーションを使うことができます。
Micronautでパスパラメータを明示的に指定する場合は@PathVariableアノテーションを使います。このアノテーションの引数にパスパラメータの名前を文字列で渡すと、引数名とは別にパスパラメータ名を指定できます。
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.annotation.PathVariable;
@Controller("/books")
public class BookController {
@Get("/{bookId}/author/{authorId}")
public String getBookAuthor(
@PathVariable("bookId") Long bId,
@PathVariable("authorId") Long aId
) {
return "書籍ID「" + bId + "」の著者ID「" + aId + "」の情報を取得しました!";
}
}
このサンプルでは、パスパラメータ名はbookIdとauthorIdですが、引数名はそれぞれbIdとaIdという短い名前にしています。@PathVariableに元のパスパラメータ名を指定することで、引数名が違っても正しくマッピングされます。
/books/10/author/3というURLにアクセスすると、下記のような結果が返ります。
書籍ID「10」の著者ID「3」の情報を取得しました!
明示的なアノテーションを使うことで、コードを読む人がこの引数はパスパラメータから来ていることをひと目で理解できるようになります。チーム開発においてはコードの可読性がとても重要なので、明示的に書くスタイルを好む開発チームも多くあります。
7. パスパラメータと型変換の注意点
パスパラメータはURLの文字列として受け取られますが、Micronautは引数の型に合わせて自動的に型変換を行います。整数にはIntegerやLong、浮動小数点数にはDoubleやFloat、真偽値にはBooleanなど、様々な型に対応しています。
ただし、型変換に失敗するケースには注意が必要です。たとえばLong型の引数に対して「abc」という文字列が渡された場合、変換できずにエラーが発生します。このような場合、Micronautはデフォルトで400番のエラーレスポンスを自動的に返します。
型変換のエラーをより丁寧に制御したい場合は、引数の型をStringにして受け取り、メソッドの中で自分で変換処理を書く方法もあります。また、Micronautの@Errorアノテーションを使ったエラーハンドラを定義することで、エラー発生時のレスポンスをカスタマイズすることも可能です。
初心者のうちはまず基本的な型での受け取りから始め、慣れてきたらエラーハンドリングについても学んでいくとよいでしょう。Micronautのドキュメントには型変換に関する詳細な情報が記載されているので、必要に応じて参照してみてください。
なお、パスパラメータで受け取れる値の種類はURLで使用できる文字列に限られます。スラッシュ(/)はパスの区切り文字として扱われるため、パスパラメータの値にスラッシュを含めることはデフォルトではできません。特殊なケースでスラッシュを含む値を受け取りたい場合は、別途設定が必要になります。
8. @Getとクエリパラメータを組み合わせる活用例
パスパラメータだけでなく、クエリパラメータと組み合わせることでより柔軟なエンドポイントを作ることができます。クエリパラメータはURLの末尾に「?キー=値」という形式で付けるもので、検索条件やフィルタリング条件の指定によく使われます。
たとえば「/products/5?lang=ja」というURLの場合、5がパスパラメータでlang=jaがクエリパラメータです。Micronautではクエリパラメータを受け取るために@QueryValueアノテーションを使います。
下記のサンプルでは、商品IDをパスパラメータで、表示言語をクエリパラメータで受け取るエンドポイントを作っています。
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.annotation.QueryValue;
import java.util.Optional;
@Controller("/products")
public class ProductController {
@Get("/{productId}")
public String getProduct(Long productId, @QueryValue Optional<String> lang) {
String language = lang.orElse("ja");
return "商品ID「" + productId + "」を言語「" + language + "」で取得しました!";
}
}
/products/7というURLにアクセスすると下記の結果が返ります。
商品ID「7」を言語「ja」で取得しました!
/products/7?lang=enというURLにアクセスすると下記の結果が返ります。
商品ID「7」を言語「en」で取得しました!
クエリパラメータをOptional型で受け取ることで、パラメータが省略された場合もエラーにならずにデフォルト値を使って処理できます。パスパラメータとクエリパラメータを組み合わせることで、実際のサービスに近い柔軟なAPIが実現できます。
9. MicronautのGETエンドポイントをテストする方法
作成したGETエンドポイントが期待通りに動作しているかを確認するために、テストを書くことはとても重要です。Micronautにはテスト用の仕組みが充実しており、@MicronautTestアノテーションを使うことでアプリケーションを丸ごと起動してテストを実行することができます。
テストクラスの中ではHttpClientを注入して実際にHTTPリクエストを送り、レスポンスの内容やステータスコードを確認します。下記はUserControllerに対するシンプルなテストの例です。
import io.micronaut.http.HttpRequest;
import io.micronaut.http.client.HttpClient;
import io.micronaut.http.client.annotation.Client;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
@MicronautTest
public class UserControllerTest {
@Inject
@Client("/")
HttpClient client;
@Test
public void testGetUser() {
String result = client.toBlocking()
.retrieve(HttpRequest.GET("/users/42"));
assertTrue(result.contains("42"));
}
}
このテストでは/users/42にGETリクエストを送り、レスポンスに「42」という文字列が含まれているかどうかを確認しています。assertTrueを使うことで、レスポンスの内容を柔軟に検証できます。
テストを書いておくことで、コードを修正したときに既存の機能が壊れていないかをすぐに確認できます。GETエンドポイントはシンプルなものが多いため、テストも書きやすく、テスト駆動開発の練習としても最適です。Micronautのテスト機能はJUnit5とも相性がよく、既存のJavaの知識を活かして書けるのも嬉しいポイントです。
最初はシンプルなテストから始めて、徐々にパスパラメータやクエリパラメータを含む複雑なケースのテストも追加していくとよいでしょう。テストの積み重ねがアプリケーションの信頼性を高めることにつながります。