Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Routes and handlers

A route connects an HTTP method and an address to code. The code that runs for a route is called a handler. In Javalin a handler is an object of the Handler interface with a single method handle(Context ctx), so it is usually written as a lambda ctx -> .... All routes are declared in the configuration block through config.routes.

Routes for different methods

Each HTTP method has its own config.routes method. Replace the contents of the configuration block in Main.java:

// src/main/java/com/example/blog/Main.java
Javalin app = Javalin.create(config -> {
    config.routes.get("/posts", ctx -> ctx.result("List of posts"));
    config.routes.post("/posts", ctx -> ctx.status(201).result("Post created"));
    config.routes.put("/posts/{id}", ctx -> ctx.result("Post updated"));
    config.routes.delete("/posts/{id}", ctx -> ctx.status(204));
});

One address /posts answers GET and POST differently. The part of the address in curly braces {id} is a parameter, covered in the next lesson. The ctx.status method sets the response code: 201 means "created", 204 means "success, no body".

Check the routes with curl. The -X option sets the method, the -i option shows the status line and headers (the Date and Content-Length headers are omitted here and below):

curl http://localhost:8080/posts
curl -i -X POST http://localhost:8080/posts
List of posts
HTTP/1.1 201 Created
Content-Type: text/plain

Post created

What ctx can do

Through ctx a handler reads the request and builds the response:

MethodWhat it does
ctx.method(), ctx.path()The request method and path
ctx.header("User-Agent")A request header
ctx.result("text")The response body as a string
ctx.status(201)The response code
ctx.header("X-Blog", "Javalin")A response header
// src/main/java/com/example/blog/Main.java
config.routes.get("/info", ctx -> {
    ctx.header("X-Blog", "Javalin");
    ctx.result(ctx.method() + " " + ctx.path() + " from " + ctx.userAgent());
});
curl -i http://localhost:8080/info
HTTP/1.1 200 OK
Content-Type: text/plain
X-Blog: Javalin

GET /info from curl/8.21.0

A handler as a method

Longer code is easier to move into a method with a Context parameter and pass by reference:

// src/main/java/com/example/blog/Main.java
config.routes.get("/about", Main::about);
 
// in the Main class, next to the main method (import io.javalin.http.Context)
private static void about(Context ctx) {
    ctx.result("A blog on Javalin");
}

The request curl http://localhost:8080/about returns A blog on Javalin. Later such methods move into a separate controller class.

When there is no route

For an address or method without a route, Javalin answers 404 by itself:

curl -i -X PATCH http://localhost:8080/posts/7
HTTP/1.1 404 Not Found
Content-Type: text/plain

Endpoint PATCH /posts/7 not found

Common mistake

Javalin checks routes in the order they are declared. If a route with a parameter comes before a specific address, it catches that address too:

// src/main/java/com/example/blog/Main.java
config.routes.get("/posts/{id}", ctx -> ctx.result("Post #" + ctx.pathParam("id")));
config.routes.get("/posts/new", ctx -> ctx.result("Form for a new post"));
curl http://localhost:8080/posts/new
Post #new

Declare specific addresses like /posts/new above routes with parameters.

Thanks for reading!

Donate to the site — we work hard for you.