【Spring Boot × Kotlin】REST API を作成する
今回は、Spring Boot と Kotlin で REST API を作成する方法を解説します。
なお、ここに掲載しているソースコードは以下の環境で動作確認しています。
プロジェクト作成
プロジェクトを Spring Initializr にて作成します。各設定項目は以下のように設定します。
- Project: Gradle Project
- Language: Kotlin
- Spring Boot: 2.7.3
- Project Metadata: デフォルト値
- Dependencies: Spring Web
今回、REST API のルーティングを行うため、Dependencies に Spring Web を設定しています。
以上で、プロジェクトの作成は完了です。
REST API を作成する
プロジェクトの作成が完了したら、実際に REST API の作成に入ります。
今回、以下のような JSON を応答する REST API を作成します。
{ "datetime": "yyyy-mm-ddThh:MM:ss.SSSSSS", "message": "Hello, {name}!" }
datetime
はバックエンドがリクエストを受けたときの日時とします。また、message
の文字列の一部をクライアントからリクエストできるようにします。
今回は、以下の 3 つのデータの渡し方について、それぞれ実装します。
URL クエリパラメータ
最初に、URL クエリパラメータにてデータを渡す方法です。具体的には、以下のような REST API を実装します。
GET http://localhost:8080/get-greeting/query?name={name} HTTP/1.1
まず、REST API のルーティングをコントロールするクラスを以下のように実装します。
// GreetingController.kt @RestController class GreetingController { @GetMapping("/get-greeting/query") fun getGreetingByQuery( @RequestParam( name = "name", required = false, defaultValue = "world" ) name: String ) = GreetingResponse( datetime = LocalDateTime.now().toString(), message = "Hello, $name!" ) }
REST API のコントローラクラスには @RestController を付与します。このコントローラクラスには、HTTP リクエストごとにメソッドを追加します。
GET リクエストに対応するメソッドには、@GetMapping を付与し、そのリクエストのパスを @GetMapping の引数に設定します。
メソッドの引数には URL クエリパラメータを受け取る name
を追加します。省略された場合のデフォルト値は "world"
とします。
そして、メソッドの戻り値には JSON レスポンスに対応するデータクラスのインスタンスを設定します。このレスポンスのデータクラスは以下のように実装します。
// GreetingResponse.kt data class GreetingResponse( val datetime: String, val message: String, )
プロジェクトを実行すると、以下のようなコマンドを実行できます。
$ curl 'http://localhost:8080/get-greeting/query?name=tatsuro' {"datetime":"2022-09-24T13:14:41.071979","message":"Hello, tatsuro!"}
期待通りの JSON を受け取れています。
パスパラメータ
次に、パスパラメータにてデータを渡す方法です。具体的には、以下のような REST API を実装します。
GET http://localhost:8080/get-greeting/path/{name} HTTP/1.1
REST API のコントローラクラスを以下のように実装します。
// GreetingController.kt @RestController class GreetingController { @GetMapping("/get-greeting/path/{name}") fun getGreetingByPath( @PathVariable("name") name: String ) = GreetingResponse( datetime = LocalDateTime.now().toString(), message = "Hello, $name!" ) }
実装は URL クエリパラメータとほぼ同じですが、@GetMapping に設定するリクエストのパスと、引数のアノテーションが異なります。
@GetMapping に設定するパスについては、パラメータになる箇所を波括弧で囲い、波括弧の中にパラメータ名を設定します。
メソッドの引数には、パスパラメータを受け取る name
に @PathVariable("name")
を付与します。
なお、メソッドの戻り値に使用するデータクラスは、さきほどの GreetingResponse を流用します。
プロジェクトを実行すると、以下のようなコマンドを実行できます。
$ curl 'http://localhost:8080/get-greeting/path/tatsuro' {"datetime":"2022-09-24T13:14:54.326179","message":"Hello, tatsuro!"}
期待通りの JSON を受け取れています。
JSON リクエストボディ
最後に、JSON のリクエストボディにてデータを渡す方法です。具体的には、以下のような REST API を実装します。
POST http://localhost:8080/post-name HTTP/1.1 {"name":"{name}"}
まず、JSON リクエストボディに対応するデータクラスを以下のように実装します。
// NameRequest.kt data class NameRequest(val name: String)
次に、REST API のコントローラクラスを以下のように実装します。
// GreetingController.kt @RestController class GreetingController { @PostMapping("/post-name") fun postName( @RequestBody request: NameRequest ) = GreetingResponse( datetime = LocalDateTime.now().toString(), message = "Hello, ${request.name}!" ) }
今回は POST リクエストで実装するので、メソッドには @PostMapping を付与します。
JSON リクエストボディを受け取るためには、@RequestBody を付与した引数を追加します。この引数の型には、JSON リクエストボディに対応するデータクラス NameRequest を使います。
なお、メソッドの戻り値に使用するデータクラスは、いままで使った GreetingResponse を流用します。
プロジェクトを実行すると、以下のようなコマンドを実行できます。
$ curl -H 'Content-Type:application/json' \ -X POST \ -d '{"name":"tatsuro"}' \ 'http://localhost:8080/post-name' {"datetime":"2022-09-24T13:15:12.659395","message":"Hello, tatsuro!"}
期待通りの JSON を受け取れています。