Skip to content

Commit

Permalink
Add HTML page :wip
Browse files Browse the repository at this point in the history
  • Loading branch information
jaguililla committed Jun 23, 2024
1 parent e2830e2 commit ea46d3b
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 44 deletions.
19 changes: 0 additions & 19 deletions src/main/kotlin/rest/Cors.kt

This file was deleted.

61 changes: 36 additions & 25 deletions src/main/kotlin/rest/Router.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,33 @@ package com.hexagontk.todo.backend.rest

import com.hexagonkt.converters.convert
import com.hexagonkt.core.media.APPLICATION_JSON
import com.hexagonkt.core.media.TEXT_PLAIN
import com.hexagonkt.http.model.ContentType
import com.hexagonkt.http.handlers.HttpContext
import com.hexagonkt.http.handlers.HttpController
import com.hexagonkt.http.handlers.HttpHandler
import com.hexagonkt.http.handlers.path
import com.hexagonkt.http.model.HttpMethod.*
import com.hexagonkt.http.server.callbacks.CorsCallback
import com.hexagonkt.http.server.callbacks.UrlCallback
import com.hexagonkt.serialization.jackson.json.Json
import com.hexagonkt.serialization.parseMap
import com.hexagonkt.serialization.serialize
import com.hexagontk.todo.backend.domain.model.Task
import com.hexagontk.todo.backend.domain.TaskStore
import java.util.UUID

class Router(private val store: TaskStore) {
private val tasksHandler = path("/tasks") {
class Router(private val store: TaskStore) : HttpController {

private val json = ContentType(APPLICATION_JSON)
private val text = ContentType(TEXT_PLAIN)

private val tasksHandler: HttpHandler = path("/tasks") {
get {
val taskResponse =
store.findAll().map { task -> task.convert(TaskRetrievalResponse::class) }
ok(taskResponse)
val tasks = store.findAll()
val taskResponses = tasks.map { task -> task.convert(TaskRetrievalResponse::class) }

ok(taskResponses.serialize(Json), contentType = json)
}

get("/{id}") {
Expand All @@ -26,8 +37,8 @@ class Router(private val store: TaskStore) {
}

post {
val taskCreationRequest =
request.bodyString().parseMap(Json).convert(TaskCreationRequest::class)
val bodyString = request.bodyString()
val taskCreationRequest = bodyString.parseMap(Json).convert(TaskCreationRequest::class)
val task = Task(
id = UUID.randomUUID().toString(),
title = taskCreationRequest.title,
Expand All @@ -39,16 +50,16 @@ class Router(private val store: TaskStore) {

patch("/{id}") {
val id = pathParameters.getValue("id")
val taskUpdateRequest =
request.bodyString().parseMap(Json).convert(TaskUpdateRequest::class)
val bodyString = request.bodyString()
val taskUpdateRequest = bodyString.parseMap(Json).convert(TaskUpdateRequest::class)
store.findOne(id) ?: notFound("Task with id $id not found")
val updates = mapOf(
Task::title.name to taskUpdateRequest.title,
Task::order.name to taskUpdateRequest.order,
Task::completed.name to taskUpdateRequest.completed
)
if (store.updateOne(id, updates)) getTask(id, store)
else badRequest("Unable to update task with id $id")
else badRequest("Unable to update task with id $id", contentType = text)
}

delete {
Expand All @@ -60,27 +71,27 @@ class Router(private val store: TaskStore) {
val id = pathParameters.getValue("id")
store.findOne(id) ?: notFound("Task with id $id not found")
if (store.deleteOne(id)) ok()
else badRequest("Unable to delete task with id $id")
else badRequest("Unable to delete task with id $id", contentType = text)
}
}

val handler = path {
cors()
after("*") {
send(
body = response.body.serialize(Json),
contentType = ContentType(APPLICATION_JSON)
override val handler: HttpHandler = path {
filter(
"*",
CorsCallback(
allowedMethods = setOf(GET, POST, PATCH, DELETE, OPTIONS),
allowedHeaders = setOf("Content-Type")
)
}
)

get(callback = UrlCallback("classpath:static/index.html"))

use(tasksHandler)
}
}

internal fun HttpContext.getTask(id: String, store: TaskStore): HttpContext {
val task = store.findOne(id)?.convert(TaskRetrievalResponse::class)
return if (task != null) {
ok(task)
} else {
notFound("Task with id $id not found")
private fun HttpContext.getTask(id: String, store: TaskStore): HttpContext {
val task = store.findOne(id)?.convert(TaskRetrievalResponse::class)
return if (task != null) ok(task.serialize(Json), contentType = json)
else notFound("Task with id $id not found", contentType = text)
}
}
57 changes: 57 additions & 0 deletions src/main/resources/static/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,60 @@
</head>

<h1>TODO</h1>

<h2>Open</h2>
<table>
<thead>
<tr>
<th>Id</th>
<th>Title</th>
<th>Order</th>
</tr>
</thead>
<tbody id="tasks">
<tr>
<td>a</td>
<td>b</td>
<td>0</td>
</tr>
</tbody>
</table>

<h2>New</h2>
<form>
<label for="title">Title</label>
<input id="title" type="text">
<label for="order">Order</label>
<input id="order" type="number">
</form>
<button onclick="add()">Add</button>

<script>
const http = new XMLHttpRequest();

function httpSend(method, url, body, callback) {
http.open(method, url);
http.setRequestHeader('Content-type', 'application/json');
http.send(JSON.stringify(body));
http.onreadystatechange = callback;
}

function httpGet(url, body, callback) {
httpSend('GET', url, body, callback);
}

function httpPost(url, body, callback) {
httpSend('POST', url, body, callback);
}

function add() {
let body = { title: 'a', order: 0 };
httpPost('/tasks', body, () => console.log(http.responseText));
}

function main() {
httpGet('/tasks', null, () => console.log(http.responseText));
}

main();
</script>

0 comments on commit ea46d3b

Please sign in to comment.