In this article, we will provide an overview of the upcoming Jakarta RESTful Web Services 4.0 features. We will show how to test the latest version of this API on WildFly and how to run some examples with it.
What’s New in Jakarta REST 4.0: Key Features and Enhancements
The latest Jakarta REST 4.0 release brings a host of exciting updates, aimed at enhancing integration with Jakarta EE technologies and improving overall functionality. Here’s a concise look at the key features and changes:
- Integration with Jakarta EE Technologies: Jakarta REST 4.0 removes the @ManagedBean annotation support, integrating managed bean support fully into Contexts and Dependency Injection (CDI).
- Clarified Java SE Publishing: The update refines specifications to clarify when developers must support the two alternative ways of publishing on Java SE.
- Code Clean-Up: The API simplifies by removing the inner classes
Link.JaxbLink
andLink.JaxbAdapter.
- New Methods for Enhanced Control:
- Added the
containsHeaderString()
method toClientRequestContext
,ClientResponseContext
,ContainerRequestContext
,ContainerResponseContext
, andHttpHeaders
, allowing for more precise header management. - Introduced the
getMatchedResourceTemplates()
method toUriInfo
to improve resource matching capabilities.
- Added the
- New Media Types: The update introduces
APPLICATION_MERGE_PATCH_JSON
andAPPLICATION_MERGE_PATCH_JSON_TYPE
toMediaType
, supporting the JSON Merge Patch format.
These updates provide developers with more robust tools and clearer guidelines, ensuring a smoother and more efficient development experience with Jakarta REST.
Preparing WildFly for Jakarta REST 4.0
Firstly, you need a WildFly version which includes support for Jakarta REST 4.0. At the time of writing, you can do that by provisioning a server distribution including the resteasy-7.0
channel which supports Jakarta REST 4.0:
<plugin> <groupId>org.wildfly.plugins</groupId> <artifactId>wildfly-maven-plugin</artifactId> <version>5.0.0.Final</version> <executions> <execution> <id>server-provisioning</id> <phase>generate-test-resources</phase> <goals> <goal>provision</goal> </goals> <configuration> <feature-packs> <feature-pack> <groupId>org.wildfly</groupId> <artifactId>wildfly-ee-galleon-pack</artifactId> </feature-pack> </feature-packs> <channels> <channel> <manifest> <groupId>org.wildfly.channels</groupId> <artifactId>wildfly-ee</artifactId> </manifest> </channel> <channel> <manifest> <groupId>dev.resteasy.channels</groupId> <artifactId>resteasy-7.0</artifactId> </manifest> </channel> </channels> </configuration> </execution> </executions> </plugin>
You can read more details about configuring WildFly channels in this article: Custom WildFly distributions using Channels
Then, to be able to build your applications, you need to include the following dependency:
<dependency> <groupId>jakarta.ws.rs</groupId> <artifactId>jakarta.ws.rs-api</artifactId> <scope>provided</scope> <version>4.0.0</version> </dependency> <dependency> <groupId>jakarta.xml.bind</groupId> <artifactId>jakarta.xml.bind-api</artifactId> <scope>provided</scope> <version>4.0.0</version> </dependency>
Testing Jakarta 4.0 REST new features
One of the addition of this new API is the containsHeaderString()
method to which is now available to ClientRequestContext, ClientResponseContext, ContainerRequestContext, ContainerResponseContext
, and HttpHeaders
.
This method simplifies working with request and response headers, specifically focusing on headers containing comma-separated values.
Currently, checking for specific values within headers that can appear multiple times (like Cache-Control
) is cumbersome. Developers often resort to:
- Regular Expressions: This can be slow as it concatenates the entire header string before splitting it.
- Iterating through all values: This can be tedious and not very readable.
The following method allows a simple check on the no-store HTTP Header. It returns true if its value is “no-store” (ignoring the case):
@GET @Path("header") @Produces("text/plain") public boolean getHeaderString(@Context HttpHeaders headers) { return headers.containsHeaderString("cache-control", ",", "no-store"::equalsIgnoreCase); }
Therefore:
Another new feature of Jakarta REST API 4.0 is the getMatchedResourceTemplate() method. This method provides the path template used to handle the request.
Traditionally, developers might rely on ResourceInfo
to get the resource class and method serving the request. They could then use reflection to analyze @Path
annotations and construct the route template. This approach becomes unreliable when sub-resources are involved, as it doesn’t capture the complete path hierarchy.
For example, the following example will return a Response (the reg expression itself), given that the Path matches the regular expression "[a-zA-Z][a-zA-Z_0-9]*
“
@GET @Path("{name:[a-zA-Z][a-zA-Z_0-9]*}") public Response get(@Context UriInfo info) { return Response.ok(info.getMatchedResourceTemplate()).build(); }
Therefore:
Finally, Jakarta REST 4.0 also adds the JSON Merge Patch Media Type which is a way to describe changes to a JSON document. It assumes an existing JSON document (the original) that needs modifications.
You define a separate JSON document (the patch) that outlines the changes. This patch document uses a structure similar to the original document, but it specifies the modifications to be made. When you “apply” the patch to the original document, a new, modified JSON document is created.
Unlike JSON Patch, which uses specific operations (add, remove, replace), JSON Merge Patch describes the desired outcome directly within the patch document.
Here is some sample pseudo-code to give you an idea of how APPLICATION_MERGE_PATCH_JSON works:
@Path("/items/{id}") @Consumes(MediaType.APPLICATION_MERGE_PATCH_JSON) public class ItemResource { @Inject private ItemController itemController; @PATCH public Response updateItem(@PathParam("id") String id, String patch) { itemController.updateItem(id, patch); return Response.ok().build(); } }
Conclusion
This article provides an overview of the new Jakarta REST API 4.0 features, part of the upcoming Jakarta EE 11 specification. As soon as the specification is fully available, we will combine these snippets in a full quickstart demo. Stay tuned!
References: https://jakarta.ee/specifications/restful-ws/4.0/jakarta-restful-ws-spec-4.0