0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Ktorでネストしたクラスのルーティング(resources)がうまくいかない

Last updated at Posted at 2023-01-09

はじめに

以下の書籍の10章でKtorのルーティングをしている際にかなり躓いたのでまとめます

KtorのType-safe routingがうまく行かない方がいれば参考になればと思います

問題

書籍のP258パスの共通化をKtorのType-safe routingで行いました

書籍ではLocationを使っていたため、Resourcesに書き換えて以下のコードにしました

Routing.kt
package com.example.plugins

import io.ktor.server.routing.*
import io.ktor.http.*
import io.ktor.resources.*
import kotlinx.serialization.Serializable
import io.ktor.server.application.*
import io.ktor.server.response.*
import io.ktor.server.request.*
import io.ktor.server.resources.*
import io.ktor.server.resources.Resources

fun Application.configureRouting() {
    install(Resources)

    routing {
        get<User.New> { param ->
            val id = param.id
            call.respondText("$id")
        }
    }
}

@Serializable
@Resource("/user")
class User() {
    @Serializable
    @Resource("{id}")
    class New(val id: Long)
}

しかしアクセスすると以下のエラーが発生します

curl http://localhost:8080/user/1
  /{id}, segment:1 -> SUCCESS; Parameters [id=[user]] @ /{id}
    /{id}/(method:GET), segment:1 -> FAILURE "Not all segments matched" @ /{id}/(method:GET)
Matched routes:
  No results
Route resolve result:
  FAILURE "No matched subtrees found" @ /

ログを見る限り、/{id}というルーティングはありますが、/userはなさそうでした
どうすれば/user/{id}のルーティングを用意できるのでしょうか

解決方法

まずは最終的なコードを載せます

Routing.kt
package com.example.plugins

import io.ktor.server.routing.*
import io.ktor.http.*
import io.ktor.resources.*
import kotlinx.serialization.Serializable
import io.ktor.server.application.*
import io.ktor.server.response.*
import io.ktor.server.request.*
import io.ktor.server.resources.*
import io.ktor.server.resources.Resources

fun Application.configureRouting() {
    install(Resources)

    routing {
        get<User.New> { param ->
            val id = param.id
            call.respondText("$id")
        }
    }
}

@Serializable
@Resource("/user")
class User() {
    @Serializable
    @Resource("{id}")
    class New(val parent: User = User(), val id: Long)
}

ポイントは

class New(val parent: User = User(), val id: Long)

の行になります。ここでval parent: User = User()をやっていますが、この箇所があることによって/userがパスの先頭(親)になるようでした

おわりに

何度も公式のコードを見たり、調べたりしますがなかなか気づけなかったので多くの時間を使ってしまいました

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?