使用 Location 和 JSON 的 REST API 示例

Sample for REST API using Location and JSON

标题已经简单说明了我想做的事情:实现一个简单的 REST API,它使用 ktor 的 Location 特性并接受带有 JSON 的请求作为负载。 假设我想要一个资源“books”,它在 URI /books 下可用。 get 请求应该 return 可用图书列表,带有新书数据的 post 请求应该创建一本新书,并且 return 重定向到新创建的书。我的实现如下所示:

@Location ("/books") data class BookRequest(val title: String = "" )

fun Application.bookModule() {
    routing {
        get<BookRequest> {
            val books = bookHandler.listBooks()
            //generate HTML from books and respond
        }
        post<BookRequest> {
            val request = call.receive<BookRequest>()
            //create a new book resource from the data in request
            //and respond with redirect to new book
         }
}

get 请求按预期工作,但是当我尝试 POST 一本像这样使用 curl 的新书时

curl --header "Content-Type: application/json" \
  --request POST \
   --data '{"title":"Hitchhiker"}' \
   http://localhost:8080/books

请求的title属性内容为空

有没有人有指向使用带有 POST 和 JSON 的位置的工作示例的指针?

您需要安装 ContentNegotiation plugin for deserializing JSON data to a BookRequest object and if you use kotlinx.serialization 然后用 Serializable 注释标记 BookRequest class。这是完整的例子:

import io.ktor.application.*
import io.ktor.features.*
import io.ktor.locations.*
import io.ktor.locations.post
import io.ktor.request.*
import io.ktor.response.*
import io.ktor.routing.routing
import io.ktor.serialization.*
import io.ktor.server.engine.*
import io.ktor.server.netty.*
import kotlinx.serialization.Serializable

fun main(args: Array<String>) {
    embeddedServer(Netty, port = 8080) {
        install(ContentNegotiation) {
            json()
        }
        install(Locations)
        routing {
            post<BookRequest> {
                val r = call.receive<BookRequest>()
                call.respondText { r.title }
            }
        }
    }.start()
}

@Location("/books")
@Serializable
data class BookRequest(val title: String = "")