🌐 REST API
📖 REST APIとは?
REST APIは、HTTPメソッド(GET、POST、PUT、DELETE)を使用してリソースを管理するWeb APIです。標準化された方法でクライアントとサーバーが通信します!
💡 HTTPメソッド
CRUDマッピング
GET /users - リスト取得 (Read)
GET /users/1 - 単一取得 (Read)
POST /users - 作成 (Create)
PUT /users/1 - 更新 (Update)
DELETE /users/1 - 削除 (Delete)
🎯 完全なCRUD API
データモデル
import kotlinx.serialization.Serializable
@Serializable
data class Todo(
val id: Int,
val title: String,
val completed: Boolean = false
)
@Serializable
data class CreateTodoRequest(
val title: String
)
@Serializable
data class UpdateTodoRequest(
val title: String?,
val completed: Boolean?
)
完全な実装
import io.ktor.server.application.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import io.ktor.http.*
import io.ktor.serialization.kotlinx.json.*
import io.ktor.server.plugins.contentnegotiation.*
fun Application.todoAPI() {
install(ContentNegotiation) {
json()
}
val todos = mutableListOf<Todo>()
var nextId = 1
routing {
route("/todos") {
// 목록 조회
get {
call.respond(todos)
}
// 단건 조회
get("/{id}") {
val id = call.parameters["id"]?.toIntOrNull()
val todo = todos.find { it.id == id }
if (todo != null) {
call.respond(todo)
} else {
call.respond(HttpStatusCode.NotFound, mapOf("error" to "Todo를 찾을 수 없습니다"))
}
}
// 생성
post {
val request = call.receive<CreateTodoRequest>()
val todo = Todo(
id = nextId++,
title = request.title
)
todos.add(todo)
call.respond(HttpStatusCode.Created, todo)
}
// 수정
put("/{id}") {
val id = call.parameters["id"]?.toIntOrNull()
val request = call.receive<UpdateTodoRequest>()
val index = todos.indexOfFirst { it.id == id }
if (index == -1) {
call.respond(HttpStatusCode.NotFound, mapOf("error" to "Todo를 찾을 수 없습니다"))
return@put
}
val todo = todos[index]
val updated = todo.copy(
title = request.title ?: todo.title,
completed = request.completed ?: todo.completed
)
todos[index] = updated
call.respond(updated)
}
// 삭제
delete("/{id}") {
val id = call.parameters["id"]?.toIntOrNull()
val removed = todos.removeIf { it.id == id }
if (removed) {
call.respond(HttpStatusCode.NoContent)
} else {
call.respond(HttpStatusCode.NotFound, mapOf("error" to "Todo를 찾을 수 없습니다"))
}
}
}
}
}
fun main() {
embeddedServer(Netty, port = 8080) {
todoAPI()
}.start(wait = true)
}