🌐 REST API
📖 REST API란?
REST API는 HTTP 메서드(GET, POST, PUT, DELETE)를 사용해 자원을 관리하는 웹 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)
}
🎨 테스트하기
cURL 예제
# 생성
curl -X POST http://localhost:8080/todos \
-H "Content-Type: application/json" \
-d '{"title": "Kotlin 공부하기"}'
# 목록 조회
curl http://localhost:8080/todos
# 단건 조회
curl http://localhost:8080/todos/1
# 수정
curl -X PUT http://localhost:8080/todos/1 \
-H "Content-Type: application/json" \
-d '{"completed": true}'
# 삭제
curl -X DELETE http://localhost:8080/todos/1