Handlers
Here is the code for the different API router handlers.
Root resource
private void apiRoot(RoutingContext context) {
dbService.fetchAllPagesData(reply -> {
JsonObject response = new JsonObject();
if (reply.succeeded()) {
List<JsonObject> pages = reply.result()
.stream()
.map(obj -> new JsonObject()
.put("id", obj.getInteger("ID")) (1)
.put("name", obj.getString("NAME")))
.collect(Collectors.toList());
response
.put("success", true)
.put("pages", pages); (2)
context.response().setStatusCode(200);
context.response().putHeader("Content-Type", "application/json");
context.response().end(response.encode()); (3)
} else {
response
.put("success", false)
.put("error", reply.cause().getMessage());
context.response().setStatusCode(500);
context.response().putHeader("Content-Type", "application/json");
context.response().end(response.encode());
}
});
}
We just remap database results in page information entry objects.
The resulting JSON array becomes the value for the
pages
key in the response payload.JsonObject#encode()
gives a compactString
representation of the JSON data.
Getting a page
private void apiGetPage(RoutingContext context) {
int id = Integer.valueOf(context.request().getParam("id"));
dbService.fetchPageById(id, reply -> {
JsonObject response = new JsonObject();
if (reply.succeeded()) {
JsonObject dbObject = reply.result();
if (dbObject.getBoolean("found")) {
JsonObject payload = new JsonObject()
.put("name", dbObject.getString("name"))
.put("id", dbObject.getInteger("id"))
.put("markdown", dbObject.getString("content"))
.put("html", Processor.process(dbObject.getString("content")));
response
.put("success", true)
.put("page", payload);
context.response().setStatusCode(200);
} else {
context.response().setStatusCode(404);
response
.put("success", false)
.put("error", "There is no page with ID " + id);
}
} else {
response
.put("success", false)
.put("error", reply.cause().getMessage());
context.response().setStatusCode(500);
}
context.response().putHeader("Content-Type", "application/json");
context.response().end(response.encode());
});
}
Creating a page
private void apiCreatePage(RoutingContext context) {
JsonObject page = context.getBodyAsJson();
if (!validateJsonPageDocument(context, page, "name", "markdown")) {
return;
}
dbService.createPage(page.getString("name"), page.getString("markdown"), reply -> {
if (reply.succeeded()) {
context.response().setStatusCode(201);
context.response().putHeader("Content-Type", "application/json");
context.response().end(new JsonObject().put("success", true).encode());
} else {
context.response().setStatusCode(500);
context.response().putHeader("Content-Type", "application/json");
context.response().end(new JsonObject()
.put("success", false)
.put("error", reply.cause().getMessage()).encode());
}
});
}
This handler and other handlers need to deal with incoming JSON documents. The following validateJsonPageDocument
method is a helper for doing validation and early error reporting, so that the remainder of the processing assume the presence of certain JSON entries:
private boolean validateJsonPageDocument(RoutingContext context, JsonObject page, String... expectedKeys) {
if (!Arrays.stream(expectedKeys).allMatch(page::containsKey)) {
LOGGER.error("Bad page creation JSON payload: " + page.encodePrettily() + " from " + context.request().remoteAddress());
context.response().setStatusCode(400);
context.response().putHeader("Content-Type", "application/json");
context.response().end(new JsonObject()
.put("success", false)
.put("error", "Bad request payload").encode());
return false;
}
return true;
}
Updating a page
private void apiUpdatePage(RoutingContext context) {
int id = Integer.valueOf(context.request().getParam("id"));
JsonObject page = context.getBodyAsJson();
if (!validateJsonPageDocument(context, page, "markdown")) {
return;
}
dbService.savePage(id, page.getString("markdown"), reply -> {
handleSimpleDbReply(context, reply);
});
}
The handleSimpleDbReply
method is a helper for finishing the request processing:
private void handleSimpleDbReply(RoutingContext context, AsyncResult<Void> reply) {
if (reply.succeeded()) {
context.response().setStatusCode(200);
context.response().putHeader("Content-Type", "application/json");
context.response().end(new JsonObject().put("success", true).encode());
} else {
context.response().setStatusCode(500);
context.response().putHeader("Content-Type", "application/json");
context.response().end(new JsonObject()
.put("success", false)
.put("error", reply.cause().getMessage()).encode());
}
}
Deleting a page
private void apiDeletePage(RoutingContext context) {
int id = Integer.valueOf(context.request().getParam("id"));
dbService.deletePage(id, reply -> {
handleSimpleDbReply(context, reply);
});
}