Vert.x Backend

Simplifying the HTTP verticle code

A client-side application needs a backend that exposes:

  1. the static HTML, CSS and JavaScript content to bootstrap applications in web browsers, and

  2. a web API, typically a HTTP/JSON service.

We simplified the HTTP verticle implementation to just cover what is needed. Starting from the RxJava version from step #8, we removed all server-side rendering code as well as the authentication and JWT token issuing code to expose a plain open HTTP/JSON interface.

Of course building a version that leverages JWT tokens and authentication makes sense for a real-world deployments, but now that we have covered these features we would rather focus on the essential bits in this part of the guide.

As an example, the apiUpdatePage method implementation code is now:

  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.rxSavePage(id, page.getString("markdown")).subscribe(
  8. () -> apiResponse(context, 200, null, null),
  9. t -> apiFailure(context, t));
  10. }

Exposed routes

The HTTP/JSON API is exposed through the sames routes as in the previous steps:

  1. router.get("/api/pages").handler(this::apiRoot);
  2. router.get("/api/pages/:id").handler(this::apiGetPage);
  3. router.post().handler(BodyHandler.create());
  4. router.post("/api/pages").handler(this::apiCreatePage);
  5. router.put().handler(BodyHandler.create());
  6. router.put("/api/pages/:id").handler(this::apiUpdatePage);
  7. router.delete("/api/pages/:id").handler(this::apiDeletePage);

The front application static assets are being served from /app, and we redirect requests to / to the /app/index.html static file:

  1. router.get("/app/*").handler(StaticHandler.create().setCachingEnabled(false)); (1) (2)
  2. router.get("/").handler(context -> context.reroute("/app/index.html"));
  1. Disabling caching is useful in development.

  2. By default the files are expected to be in the webroot package on the classpath, so the files shall be placed under src/main/resources/webroot in a Maven or Gradle project.

Last but not least, we anticipate that the application will need the backend to render Markdown to HTML, so we offer a HTTP POST endpoint for this purpose:

  1. router.post("/app/markdown").handler(context -> {
  2. String html = Processor.process(context.getBodyAsString());
  3. context.response()
  4. .putHeader("Content-Type", "text/html")
  5. .setStatusCode(200)
  6. .end(html);
  7. });