This guide shows you how to use Jakarta EE to make a RESTful web service.
To create a RESTful web service using Jakarta EE, we will begin by summarizing what we want to build.
We will build a service that will accept an HTTP GET1 request at http://localhost:8080/restfulservice/hello.
It will respond with the following JSON payload, as the following listing shows:
{"text": "Hello from Jakarta EE"}
We can then further customize and improve it according to our needs.
OK, now that we have specified our requirements, you will need to follow these steps:
To install all of these, we can use the SDKMan. We can go through the steps mentioned in the how-to guide.
In this getting started guide, you may start using Eclipse Starter for Jakarta EE, finish each step, or skip fundamental setup stages that you already know. You can also begin with an IDE or choose a project structure from well-known Maven archetypes.
To use Eclipse Starter for Jakarta EE, we need to take the following steps:
mvn archetype:generate -DarchetypeGroupId=org.eclipse.starter -DarchetypeArtifactId=jakartaee10-minimal -DarchetypeVersion=1.1.0 -DgroupId=org.eclipse.rest -DartifactId=rest-service -Dprofile=web-api -Dversion=1.0.0-SNAPSHOT -DinteractiveMode=false
This will give us the project structure and sample code, which we can then build and run.
When we unpack the generated code, we will have the following code structure:
.
├── pom.xml
└── src
├── main
│ └── java
│ └── org
│ └── eclipse
│ └── restfulservice
│ ├── ApplicationConfig.java
│ └── resources
│ ├── Hellorecord.java
│ └── RestResource.java
├── resources
│ └── META-INF
│ └── beans.xml
└── webapp
In this code structure, along with other classes and configurations, we are
interested in two classes in particular: RestResource.java
and
HelloRecord.java
.
Let’s open the RestResource.java
file first.
package org.eclipse.restfulservice.resources;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
@Path("hello")
public class RestResource {
@GET
@Produces(MediaType.APPLICATION_JSON)
public HelloRecord hello(){
return new HelloRecord("Hello from Jakarta EE");
}
}
This defines a RESTful web service that returns a JSON representation of a
RestResource
when a GET
request is made to the "/hello"
endpoint.
The jakarta.ws.rs.Path
annotation establishes a connection between the URL
given by the user and the Java class responsible for handling the request. The
jakarta.ws.rs.GET
annotation tells us we must use the HTTP GET
method to
access our endpoint. The jakarta.ws.rs.Produces
annotation allows you to
specify the format of the response. In our case, it will produce a
JSON2
response by converting the
object of HelloRecord
.
The method hello()
is defined to return a HelloRecord
. This is the new
record class that was released in Java 16.
package org.eclipse.restfulservice.resources;
public record HelloRecord(String text) {
}
But if you use a lower version of Java, you can change it to a traditional POJO3 .
package org.eclipse.restfulservice.resources;
public final class HelloRecord {
private final String text;
public HelloRecord(String text) {
this.text = text;
}
public String text() {
return text;
}
}
The project structure was generated without having a runtime associated with it. The merit of it is that we can choose from a multitude of runtimes. A list of compatible Jakarta EE can be found here.
We will use WildFly in this tutorial.
To do that, we need to add an additional plugin to the pom.xml
file.
<plugin>
<groupId>org.wildfly.plugins</groupId>
<artifactId>wildfly-maven-plugin</artifactId>
<version>2.1.0.Beta1</version>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>deploy</goal>
</goals>
</execution>
</executions>
</plugin>
Include the above plugin in the plugins sections of the pom.xml
.
The wildfly-maven-plugin
is used to deploy, redeploy, undeploy or run the
Jakarta EE application. There is also the ability to execute CLI commands. The
whole configuration of this plugin can be found here:
WildFly Maven Plugin – Introduction.
There are multiple ways you can configure a local instance of WildFly. Some configurations can be found here: WildFly Maven Plugin – Run Example.
However, in this tutorial, we can leave all the configurations as they are, as we will use the default, and that’s enough for us.
In particular, we are interested in wildfly:run
CLI command. Let’s run the
following command from the command line:
mvn clean package wildfly:run
The command above will build the app and put it on Wildfly. If Wildfly is not installed, it will download and run it, and then the war file will be deployed.
Once the application runs, we will get the following output in the terminal:
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------in< org.eclipse:restfulservice >---------------------
[INFO] Building restfulservice 1.0.0-SNAPSHOT
[INFO] --------------------------------[ war ]---------------------------------
[INFO]
.....
skipped the log for brevity
.....
03:35:02,323 INFO [org.jboss.resteasy.resteasy_jaxrs.i18n] (ServerService Thread Pool -- 32) RESTEASY002225: Deploying jakarta.ws.rs.core.Application: class org.eclipse.restfulservice.ApplicationConfig
03:35:02,346 INFO [org.wildfly.extension.undertow] (ServerService Thread Pool -- 32) WFLYUT0021: Registered web context: '/restfulservice' for server 'default-server'
03:35:02,365 INFO [org.jboss.as.server] (management-handler-thread - 1) WFLYSRV0010: Deployed "restfulservice.war" (runtime-name : "restfulservice.war")
Now that the service is running let’s visit http://localhost:8080/restfulservice/hello.
It should return:
{ "text": "Hello from Jakarta EE" }
Alternatively, we can curl from the command line:
curl -v http://localhost:8080/restfulservice/hello
* Trying 127.0.0.1:8080...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /restfulservice/hello HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.86.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Connection: keep-alive
< Content-Type: application/json
< Content-Length: 32
< Date: Sun, 18 Dec 2022 08:45:51 GMT
<
* Connection #0 to host localhost left intact
{"text":"Hello from Jakarta EE"}%
Let us have a look at the URL structure.
http://<hostname>:<port>/<context-root>/<REST-config>/<resource-config>
Let’s unpack the URL pattern here:
Hostname: the name of the machine on which WildFly Server is installed.
Port: The WildFly Server’s listening port for incoming HTTP requests. This is port 8080 by default, but it can be configured.
Context-root: The context root to which the deployed application has been assigned. By default, this is the filename (without the extension) of the WAR file that is being deployed. But it can be changed when the file is being deployed.
REST-config: The value we have defined for the @ApplicationPath
annotation in our project. By default, it is empty, which is indicated simply
by /. We can easily configure it in our ApplicationConfig
class.
Resource-config: the value defined in the @Path
annotation on the Java
class defines an endpoint. In our case, "/hello"
is handled by the
RestResource
class.
If we want to change the REST-config
part, for example, to "/api"
, we can
change the value in the @ApplicationPath
annotation like this:
import jakarta.ws.rs.ApplicationPath;
import jakarta.ws.rs.core.Application;
@ApplicationPath("/api")
public class ApplicationConfig extends Application {
}
After making this change, if we run again, we have to change the curl command to consume the service as follows:
curl -v http://localhost:8080/restfulservice/api/hello
Congratulations! You have just learned how to develop a RESTful web service using Jakarta EE.