Tatsuro のテックブログ

アプリ開発の技術情報を発信します。

【Spring Boot × Kotlin】REST API を作成する

今回は、Spring Boot と Kotlin で REST API を作成する方法を解説します。

なお、ここに掲載しているソースコードは以下の環境で動作確認しています。

  • IntelliJ IDEA 2022.2.2 (Community Edition)
  • JDK 17.0.4.1
  • Kotlin 1.6.21
  • Gradle 7.5
  • Spring Boot 2.7.3

プロジェクト作成

プロジェクトを 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 クエリパラメータ
  • パスパラメータ
  • JSON リクエストボディ

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 を受け取れています。

参考

REST API の作成