Handlers

Here is the code for the different API router handlers.

Root resource

  1. private void apiRoot(RoutingContext context) {
  2. dbService.fetchAllPagesData(reply -> {
  3. JsonObject response = new JsonObject();
  4. if (reply.succeeded()) {
  5. List<JsonObject> pages = reply.result()
  6. .stream()
  7. .map(obj -> new JsonObject()
  8. .put("id", obj.getInteger("ID")) (1)
  9. .put("name", obj.getString("NAME")))
  10. .collect(Collectors.toList());
  11. response
  12. .put("success", true)
  13. .put("pages", pages); (2)
  14. context.response().setStatusCode(200);
  15. context.response().putHeader("Content-Type", "application/json");
  16. context.response().end(response.encode()); (3)
  17. } else {
  18. response
  19. .put("success", false)
  20. .put("error", reply.cause().getMessage());
  21. context.response().setStatusCode(500);
  22. context.response().putHeader("Content-Type", "application/json");
  23. context.response().end(response.encode());
  24. }
  25. });
  26. }
  1. We just remap database results in page information entry objects.

  2. The resulting JSON array becomes the value for the pages key in the response payload.

  3. JsonObject#encode() gives a compact String representation of the JSON data.

Getting a page

  1. private void apiGetPage(RoutingContext context) {
  2. int id = Integer.valueOf(context.request().getParam("id"));
  3. dbService.fetchPageById(id, reply -> {
  4. JsonObject response = new JsonObject();
  5. if (reply.succeeded()) {
  6. JsonObject dbObject = reply.result();
  7. if (dbObject.getBoolean("found")) {
  8. JsonObject payload = new JsonObject()
  9. .put("name", dbObject.getString("name"))
  10. .put("id", dbObject.getInteger("id"))
  11. .put("markdown", dbObject.getString("content"))
  12. .put("html", Processor.process(dbObject.getString("content")));
  13. response
  14. .put("success", true)
  15. .put("page", payload);
  16. context.response().setStatusCode(200);
  17. } else {
  18. context.response().setStatusCode(404);
  19. response
  20. .put("success", false)
  21. .put("error", "There is no page with ID " + id);
  22. }
  23. } else {
  24. response
  25. .put("success", false)
  26. .put("error", reply.cause().getMessage());
  27. context.response().setStatusCode(500);
  28. }
  29. context.response().putHeader("Content-Type", "application/json");
  30. context.response().end(response.encode());
  31. });
  32. }

Creating a page

  1. private void apiCreatePage(RoutingContext context) {
  2. JsonObject page = context.getBodyAsJson();
  3. if (!validateJsonPageDocument(context, page, "name", "markdown")) {
  4. return;
  5. }
  6. dbService.createPage(page.getString("name"), page.getString("markdown"), reply -> {
  7. if (reply.succeeded()) {
  8. context.response().setStatusCode(201);
  9. context.response().putHeader("Content-Type", "application/json");
  10. context.response().end(new JsonObject().put("success", true).encode());
  11. } else {
  12. context.response().setStatusCode(500);
  13. context.response().putHeader("Content-Type", "application/json");
  14. context.response().end(new JsonObject()
  15. .put("success", false)
  16. .put("error", reply.cause().getMessage()).encode());
  17. }
  18. });
  19. }

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:

  1. private boolean validateJsonPageDocument(RoutingContext context, JsonObject page, String... expectedKeys) {
  2. if (!Arrays.stream(expectedKeys).allMatch(page::containsKey)) {
  3. LOGGER.error("Bad page creation JSON payload: " + page.encodePrettily() + " from " + context.request().remoteAddress());
  4. context.response().setStatusCode(400);
  5. context.response().putHeader("Content-Type", "application/json");
  6. context.response().end(new JsonObject()
  7. .put("success", false)
  8. .put("error", "Bad request payload").encode());
  9. return false;
  10. }
  11. return true;
  12. }

Updating a page

  1. private void apiUpdatePage(RoutingContext context) {
  2. int id = Integer.valueOf(context.request().getParam("id"));
  3. JsonObject page = context.getBodyAsJson();
  4. if (!validateJsonPageDocument(context, page, "markdown")) {
  5. return;
  6. }
  7. dbService.savePage(id, page.getString("markdown"), reply -> {
  8. handleSimpleDbReply(context, reply);
  9. });
  10. }

The handleSimpleDbReply method is a helper for finishing the request processing:

  1. private void handleSimpleDbReply(RoutingContext context, AsyncResult<Void> reply) {
  2. if (reply.succeeded()) {
  3. context.response().setStatusCode(200);
  4. context.response().putHeader("Content-Type", "application/json");
  5. context.response().end(new JsonObject().put("success", true).encode());
  6. } else {
  7. context.response().setStatusCode(500);
  8. context.response().putHeader("Content-Type", "application/json");
  9. context.response().end(new JsonObject()
  10. .put("success", false)
  11. .put("error", reply.cause().getMessage()).encode());
  12. }
  13. }

Deleting a page

  1. private void apiDeletePage(RoutingContext context) {
  2. int id = Integer.valueOf(context.request().getParam("id"));
  3. dbService.deletePage(id, reply -> {
  4. handleSimpleDbReply(context, reply);
  5. });
  6. }