Spark

Spark – A micro-framework for Java and Kotlin

I would like the talk about a framework that I really loved, Spark. Spark is a micro-framework that allows us to build back-end services in an easy and flexible way. Although it is very lightweight, it saves us a lot of stuff to do to set up and run a service. You can build a simple endpoint in a minute.

It comes with embedded Jetty web server. It means you can just build and run your .jar file. I like these types of modern frameworks.

Spark’s developers state that it is microservice architecture friendly because microservices work best with micro-frameworks. However, I have experience with building microservice back-end services with Spring Boot and I think although it is not a micro-framework, it is a great framework too for microservice architecture.

I used Spark with Java 8+ and I think NodeJS developers will like it because the code looks like a JS/TS project especially with Java’s lambda expressions feature.

Set up and run a simple test endpoint with just one line.

Spark.get("/test", (request, response) -> "TEST");
// http://localhost:4567/test
// output: TEST

Without telling the port it runs on port 4567. To specify a port.

Spark.port(8080);
Spark.get("/test", (request, response) -> "TEST");
// http://localhost:8080/test
// output: TEST

We can easily set out paths/routes and they consist of three parts.

  • HTTP method (function name)
  • path/endpoint
  • callback (our request handler)

In order to get path params

Spark.get("/test/:id", (request, response) -> request.params("id"));
// http://localhost:4567/test/12345
// output: 12345

In order to get query params

Spark.get("/test", (request, response) -> request.queryParams("name"));
// http://localhost:4567/test?name=XLR
// output: XLR

We can use the wildcard to match dynamic paths.

Spark.get("/test/*/profile/*/display", (request, response) -> request.splat()[0] + " " + request.splat()[1]);
// http://localhost:4567/test/xlr/profile/dashboard/display
// output: xlr, dashboard

If we have a lot of paths that have a common prefix.

Spark.path("/test", () -> {
    // middleware can be added
    Spark.before("/*", (request, response) -> {
        if(request.headers("Authorization") == null) {
            Spark.halt(403);
        }
    });
    Spark.get("/name", (request, response) -> "NAME");
    Spark.get("/id", (request, response) -> "ID");
});
// http://localhost:4567/test/name
// response: HTTP 403

I loved this feature. The exception handling can be separated from the request handler.

Spark.get("/test", (request, response) -> {
    if(request.queryParams("name") == null) {
        throw new IllegalArgumentException("Name param required!");
    }

    return request.queryParams("name");
});
Spark.exception(IllegalArgumentException.class, (exception, request, response) -> {
    System.out.println(request.host());
    System.out.println(exception.getMessage());
});
// http://localhost:4567/test/name
// response: HTTP 404

Spark has also template engine support like other popular frameworks. You can see here the currently supported template engines and their details.

If you need multiple instances to run in your project

Service service1 = Service.ignite();
Service service2 = Service.ignite();
service1.port(8080);
service2.port(8081);
service1.get("/test", (request, response) -> "TEST1");
service2.get("/test", (request, response) -> "TEST2");
// http://localhost:8080/test
// output: TEST1
// http://localhost:8081/test
// output: TEST2

For more details, you can see Spark Doc