diff --git a/api/http/test.http b/api/http/test.http index c75f3f6..287d50c 100644 --- a/api/http/test.http +++ b/api/http/test.http @@ -11,4 +11,16 @@ Content-Type: application/json ### Get notes GET http://localhost:8081/notes -Authorization: Bearer {{token}} \ No newline at end of file +Authorization: Bearer {{token}} + +### Create a note +POST http://localhost:8081/notes/babar +Content-Type: application/json +Authorization: Bearer {{token}} + +{ + "tags": [ + "Test", + "Dev" + ] +} \ No newline at end of file diff --git a/api/src/controllers/Controllers.kt b/api/src/controllers/Controllers.kt index f4fc0b1..799361c 100644 --- a/api/src/controllers/Controllers.kt +++ b/api/src/controllers/Controllers.kt @@ -15,4 +15,5 @@ val controllerModule = Kodein.Module(name = "Controller") { bind().inSet() with singleton { UserController(this.kodein) } bind().inSet() with singleton { HealthCheckController(this.kodein) } bind().inSet() with singleton { NotesController(this.kodein) } + bind().inSet() with singleton { NotesTitleController(this.kodein) } } \ No newline at end of file diff --git a/api/src/controllers/KodeinController.kt b/api/src/controllers/KodeinController.kt index 332feec..5231c49 100644 --- a/api/src/controllers/KodeinController.kt +++ b/api/src/controllers/KodeinController.kt @@ -1,5 +1,8 @@ package be.vandewalleh.controllers +import io.ktor.application.ApplicationCall +import io.ktor.http.HttpStatusCode +import io.ktor.response.respond import io.ktor.routing.Routing import org.kodein.di.Kodein import org.kodein.di.KodeinAware @@ -11,4 +14,8 @@ abstract class KodeinController(override val kodein: Kodein) : KodeinAware { * Method that subtypes must override to register the handled [Routing] routes. */ abstract fun Routing.registerRoutes() + + suspend fun ApplicationCall.respondStatus(status: HttpStatusCode) { + this.respond(status, mapOf("message" to status.description)) + } } diff --git a/api/src/controllers/NotesTitleController.kt b/api/src/controllers/NotesTitleController.kt new file mode 100644 index 0000000..f91155a --- /dev/null +++ b/api/src/controllers/NotesTitleController.kt @@ -0,0 +1,70 @@ +package be.vandewalleh.controllers + +import be.vandewalleh.entities.Note +import be.vandewalleh.entities.Tag +import be.vandewalleh.tables.Notes +import be.vandewalleh.tables.Tags +import be.vandewalleh.tables.Users +import io.ktor.application.ApplicationCall +import io.ktor.application.call +import io.ktor.http.HttpStatusCode +import io.ktor.request.receive +import io.ktor.response.respond +import io.ktor.routing.Route +import io.ktor.routing.post +import me.liuwj.ktorm.database.Database +import me.liuwj.ktorm.dsl.eq +import me.liuwj.ktorm.entity.* +import org.kodein.di.Kodein +import org.kodein.di.generic.instance +import java.time.LocalDateTime + +class NotesTitleController(kodein: Kodein) : AuthCrudController("/notes/{noteTitle}", kodein) { + private val db by kodein.instance() + + private fun ApplicationCall.noteTitle(): String? { + return this.parameters["noteTitle"]!! + } + + private class PostRequestBody(val tags: List) + + override val route: Route.() -> Unit = { + post { + val title = call.noteTitle() ?: error("") + val tags = call.receive().tags + + val user = db.sequenceOf(Users) + .find { it.email eq call.userEmail() } ?: error("") + + val exists = db.sequenceOf(Notes) + .filter { it.userId eq user.id } + .filter { it.title eq title } + .firstOrNull() != null + + if (exists) { + return@post call.respondStatus(HttpStatusCode.Conflict) + } + + db.useTransaction { + val note = Note { + this.title = title + this.user = user + this.updatedAt = LocalDateTime.now() + } + + db.sequenceOf(Notes).add(note) + + tags.forEach { tagName -> + val tag = Tag { + this.note = note + this.name = tagName + } + + db.sequenceOf(Tags).add(tag) + } + } + + call.respondStatus(HttpStatusCode.Created) + } + } +} \ No newline at end of file