Introduction to Jooby Framework

Overview

Jooby is a scalable fast micro web server framework that allows you to build microservices as well as full stack applications with backend service and a front-end build using any of the following template engines.

Among the many Java/Kotlin based frameworks for web developments Jooby shines because of its simplicity and high performance.

TechEmpower, a publisher posting Web Framework benchmarks, have found that it is one of the fastest servers in the marketplace. As a matter of fact, they find it to be almost 300% faster than the most popular Java Spring framework.

Snapshot of benchmarks from TechEmpower.

In this post,I will go over the details of how to create a web application with Jooby. I will go over the details of creating both a GET as well as a POST service. In addition, we will add static content to the application as well.

Let’s go…

Create new Jooby Application

There are a few ways to create a Jooby application. I will take the easiest one, which is by using the Jooby application generator.

Download the zip file and unzip it anywhere on your file system. I have unzipped the Jooby files in the location C:\apps.The folder structure should look similar to the image below.

jooby
- bin
 - jooby
 - jooby.bat
- lib
 - jooby-cli-2.16.1.jar

Open a command shell and enter the following file to create a new Jooby App.

D:\temp> C:\apps\jooby\bin\jooby create joobyapp --server jetty

This command will create Jooby App joobyapp in the location D:\temp\joobyapp\, using Jetty as the bundled server. Jooby comes with options to select either Netty or Undertow as the bundled engine.

Note: You can switch between any of these by updating pom.xml with the relevant repository entry

Do note that Jooby also has a Maven archetype. You can use it to create a sample project with necessary dependencies by using the following command.

mvn archetype:generate -B -DgroupId=com.baeldung.jooby -DartifactId=jooby -Dversion=1.0 -DarchetypeArtifactId=jooby-archetype  -DarchetypeGroupId=org.jooby -DarchetypeVersion=2.16.1

Application Code Layout

joobyapp
- conf
 - application.conf
 - logback.xml
- src
 - main
   - java
     - app
       - App.java
 - test
   - java
     - app
       - IntegarationTest.java
       - UnitTest.java
- pom.xml
- README.md

Under the conf folder you will find two files:

  • application.conf: Configuration file to enter variables that can be used by the application to configure and initialize resources. In this file you can enter values to configure databases, cache or use for your own custom variables.
  • logback.xml: Jooby uses Slf4j for logging. You are free to use either LogBack or Log4J2.

Below the src folder you will find you general code files, adding more as your application grows.

The test folder has the test files for creating integration and unit test cases using JUnit.

pom.xml is the standard file required for use with Maven build tools.

Full video coming soon to YouTube.

Building the Application

Before we build the application, let’s start by looking at the pom.xml to understand the structure of the project so we know what is going on. First, we look at the core dependencies, which basically show that the Jetty engine is being used with LogBack for logging.

<dependency>
  <groupId>io.jooby</groupId>
    <artifactId>jooby-jetty</artifactId>
</dependency>

<dependency>
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback-classic</artifactId>
</dependency>

Next, there are test dependencies.

<dependency>
  <groupId>org.junit.jupiter</groupId>
  <artifactId>junit-jupiter-api</artifactId>
  <scope>test</scope>
</dependency>

<dependency>
  <groupId>org.junit.jupiter</groupId>
  <artifactId>junit-jupiter-engine</artifactId>
  <scope>test</scope>
</dependency>

<dependency>
  <groupId>io.jooby</groupId>
  <artifactId>jooby-test</artifactId>
  <scope>test</scope>
</dependency>

<dependency>
  <groupId>com.squareup.okhttp3</groupId>
  <artifactId>okhttp</artifactId>
  <scope>test</scope>
</dependency>

Here in addition to JUnit you will find OkHttp dependency which is used for building test cases.

Main Jooby Application

The heart of Jooby is in the man App.java file where the loop for creating web requests is created.

public class App extends Jooby {               
  {
    get("/", ctx -> "Welcome to Jooby!");      
  }

  public static void main(final String[] args) {
    runApp(args, App::new);                  
  }
}

There are three main lines in this code block.

  • Line 1: The main application class extends Jooby. This brings in all relevant HTTP methods such as GET and POST.
  • Line 3: Here we create a simple GET route “/” that returns the message calling this web service. In this app, we are using Java Lambda expression to write our code. Jooby also provides MVC API which is an alternative method to define routes using annotations. In a later post, I will go over how to build services using MVC API.
  • Line 7: using the static runApp method of Jooby class a new Web Application loop is created.

Running Jooby Web Application

Now that we have seen the files created by the Jooby app generator, we are now going to run the application. You can run the application from the IDE (Eclipse, IntelliJ or Netbeans) of your choice.

For this initial test run, we are going to use the command line to run our application. Since I have put the application at D:\temp\joobyapp, I will go there and run the following commands.

D:\temp\joobyapp> mvn build

D:\temp\joobyapp> java -jar target\joobyapp-1.0.0.jar

The first command will build the application and the second will execute the built jar. On successful run you will see the following messages generated by Jooby web application.

[2022-10-19 22:32:35,543]-[main] INFO  org.eclipse.jetty.util.log - Logging initialized @1269ms to org.eclipse.jetty.util.log.Slf4jLog
[2022-10-19 22:32:35,651]-[main] INFO  org.eclipse.jetty.server.Server - jetty-9.4.48.v20220622; built: 2022-06-21T20:42:25.880Z; git: 6b67c5719d1f4371b33655ff2d047d24e171e49a; jvm 17.0.2+8-86
[2022-10-19 22:32:35,678]-[main] INFO  org.eclipse.jetty.server.handler.ContextHandler - Started o.e.j.s.h.ContextHandler@2a54a73f{/,null,AVAILABLE}
[2022-10-19 22:32:35,806]-[main] INFO  org.eclipse.jetty.server.AbstractConnector - Started ServerConnector@4009e306{HTTP/1.1, (http/1.1)}{0.0.0.0:8080}
[2022-10-19 22:32:35,806]-[main] INFO  org.eclipse.jetty.server.Server - Started @1537ms
[2022-10-19 22:32:35,809]-[main] INFO  app.App - App started with:
[2022-10-19 22:32:35,809]-[main] INFO  app.App -     PID: 13212
[2022-10-19 22:32:35,809]-[main] INFO  app.App -     jetty {port: 8080, workerThreads: 200, bufferSize: 16384, maxRequestSize: 10485760, httpsOnly: false}
[2022-10-19 22:32:35,809]-[main] INFO  app.App -     env: [dev]
[2022-10-19 22:32:35,809]-[main] INFO  app.App -     execution mode: default
[2022-10-19 22:32:35,809]-[main] INFO  app.App -     user: sohai
[2022-10-19 22:32:35,809]-[main] INFO  app.App -     app dir: D:\temp\joobyapp
[2022-10-19 22:32:35,809]-[main] INFO  app.App -     tmp dir: D:\temp\joobyapp\tmp
[2022-10-19 22:32:35,809]-[main] INFO  app.App - routes: 

  GET /

listening on:
  http://localhost:8080/

The server is running on port 8080 on localhost. You can access it through your browser.

Jooby Web Application in Firefox


Adding Additional Features to Jooby

Simple though Jooby is to start with, it comes with a lot of features. Many of these are configurable through the application.conf file. In this section I will be adding the following features to our base JoobyApp.

Creating a New Web Service

Add a new Java class named AuthService.java and extend it using Jooby as the base class.

First, I will add a User class with the properties username and password. I will also add getters and setters for the properties. My User.java file will now be:

public class User {

    private String username;
    private String password;

    // Omitting the getters and setters

}

Add an initialization block to your class and create a GET route named /auth/user/{username}. The {username} adds a path parameter to the route.

I will also add a POST path for the user authentication mechanism.

public class AuthService extends Jooby {

    {
        get("/auth/user/{username}", (Context ctx) -> { 

            var user = new User(ctx.path("username").value(), "nopass");

            return user;
        });

        post("/auth/authenticate", ctx -> {
            var user = ctx.body(User.class);          

            return user;
        });
    }
}

Let go over the code:

  • Line 4: A new route is defined that accepts a path parameter {username}.
  • Line 6: Read the value of the path parameter from the URL.
  • Line 13: Read the posted user information from the body of the request.

Once my service class and user class have been created, I will add them to the App.java file to enable the new routes.

install(AuthService::new);

Adding Dependencies

In my requests, I am working with JSON. The data with POST body is going to be in JSON format and the responses I send back are in JSON as well.

Although you can add Gson or Jackson jars and do this process of conversion yourself, Jooby provides a Modules for this functionality to make coding easier.

To support JSON, there are modules for Gson, Jackson, JSON-B. I will be using Gson module. For this add the correct Maven dependency.

<dependency>
	<groupId>io.jooby</groupId>
	<artifactId>jooby-gson</artifactId>
</dependency>

Now you need load it and you do that by adding the following to the initialization block of the App.

install(new GsonModule());

Now we are ready to deal with appropriate Accept and Content-Type headers.

Using Authentication Web Service

Now that all the coding changes are in place I will build the code. Check the directions above, if missed earlier on how to build the code.

Handling Static Content

Jooby supports serving static content in addition to building web services using the framework. As a matter of fact you can build full-stack web application using Jooby and one of the templating frameworks such as HandleBars or ThymeLeaf.

I won’t get into using the available templating engines but would add an index.html file. So let’s start…

Create a folder in the root of the project. I will name it public but you can name it whatever you would like. Once the folder is created, delete the default get(“/”) route from App. Our index.html will serve this function. add the line shown below to the App class.

assets("/*", Paths.get("public"));  

get("/", ctx -> "Welcome to Jooby!"); 

What do the two changes above do:

  • Line 1: Use the folder public in the file system and serve content mapped to “/” located in it.
  • Line 3: Delete this line as we are no longer using the route path.

Testing Changes

Rebuild the code using mvn build and execute the jar file. Go to the browser and enter the URL, http://localhost:8080/ or http://localhost:8080/index.html.

Contents of the index.html will be displayed.

Session Management in Jooby

Jooby provides multiple ways to manage sessions. The default method uses cookie based sessions stored in memory. You can modify this to use a header instead.

Using default session mechanism means that if the server is behind a load balancer and or proxy, then you will need to have a sticky sessions proxy to ensure that each subsequent request to the server comes back to the same server.

One way to manage sessions without dependency on a particular application server is by storing session information in a cache like Redis, which can be available to all Jooby application instances.

Jooby provides ways to manage the state in a session-less manner by using either signed sessions or using JWTs.

Let’s look at the most basic ways to create and use sessions. Below is the POST request modified to get a session and use it in the return data.

post("/auth/authenticate", ctx -> {

	var user = ctx.body(User.class);
	Session session = ctx.session();                 
	session.put("username", "Hello " + user.getUsername());
	
	user.setUsername(session.get("username").toString());  
	return user;
});
Let’s look at the code
  • Line 4: Get a session. If this is a first time call and a session does not exist a new one is created. You can also use sessionOrNull(), in which case a null is returned when there is no existing session.
  • Line 5: Store a value in the session.
  • Line 7: Get the value from the session.

After the changes when I compile and run the code, a modified username is returned in the JSON, but if I look at the header I will find that a session id is returned in a session cookie. Shown below is a sample screenshot of what the response will be.

Jooby cookie based session

Application Configuration Settings

Jooby provides a mechanism to load property settings from config(.conf) files after startup. Using key value entries in the config file you can specify settings for the database, cache or just custom variables your application may need.

In this section I will show you how you can change the port Jooby‘s embedded server listens on. By default it is 8080 and I will change it to 9090.

Enable Jooby HTTPS Support with Self Signed Certificate

Open the file <project_root>/conf/application.conf in your editor and add the following entries in the file.

server.port = 9090                
server.securePort = 9443        
server.ssl.type = self-signed             
server.httpsOnly = false              
server.http2 = true                         

Let go over details of what each line does.

  • Line 1: Change the default port. This sets Jooby to start listening on port 9090.
  • Line 2: Set secure SSL port to 9443.
  • Line 3: Enable self signed certificate mode.
  • Line 4: This option I added only to show that you can set up Jooby to listen only on HTTPS and ignore all requests on non-secure port. To activate this mode change this to true. I am going to keep the false(which is the default option anyways) so the server listens on both secure and non-secure ports.
  • Line 5: The default value for Jooby is to support HTTP/1.1. With this config setting you can enable HTTP/2 support as well, which I suggest that you do for all of your services.

Testing Changes

Rebuild the code using mvn build and execute the jar file. Monitor the console logs generated during the server startup. At end you should find the following two lines:

listening on:
  http://localhost:9090/
  https://localhost:9443/

That is is. You have successfully changed the values of the ports your applications are listening on using .conf file settings.

There is a lot more you can do and in subsequent posts, I will bring you more information. Keep checking on the website for new articles.

Wait, there is more…

Jooby has a lot more to it then what I have shown here. Other than build in functionality, the team has added support for many integrations using modules. Below is a partial list by category.

Cloud

AWS Support is built in as an extension module. Currently SDK 1.x is supported.

JSON

Multiple options are available such as Gson, Jackson and JSON-B.

Data

  • Ebean ORM
  • Flyway migration
  • GraphQL
  • HikariCP for connection pooling
  • Hibernate
  • Jdbi

Templating Engines

Session Stores

  • Caffeine cache
  • JWT
  • Redis cache

Dependency Injection

  • Guice
  • Spring
  • Weld

Security

  • Jasypt: For encrypted configuration files.
  • Pac4j: Build secure applications with multiple authentications built in such as for Google, Twitter and JWTs.

Development

  • Jooby Run: Run and hot reload your application.
  • Node: Download, Install and Run node locally.
  • Whoops: Pretty page stacktrace reporter.
  • Metrics: Application metrics from the excellent metrics library.

Other

  • OpenAPI
  • Node: Node integration module.
  • Quartz: Quartz scheduler module.

The best part is you can extend Jooby further by writing your own Modules.

There is a lot more to Jooby and I will be bringing you more information as our journey proceeds.

Why you should use Jooby for your own applications

I have built the back-end web services of this web site using Jooby. I have found it to be an excellent framework to create web services. The performance has been excellent.

There are a few drawback such as lack of info across the web making it difficult to find answers but you have options to look at the excellent documentation they provide as well as a forum where you can post questions. I have found responses on the forum take a little bit of time but someone always seems to get in touch.

Other than the issue of help resources on the web I found not many broken glasses lining my path to the creation of useful web services.

Check out Jooby on their own website or on GitHub.

Let me know what you think about Jooby. If you have questions, do post in the comments below.

Download the Code

You can download the complete from GitHub.

Leave a Comment