Caching REST Resources In Jakarta REST (formerly JAX-RS)

Photo of Luqman Saeed by Luqman Saeed

REST, or Representational State Transfer, is the web standard for building APIs and applications. It offers a lightweight architecture for exchanging data between applications over the web. Jakarta REST (formerly JAX-RS) is the standard API for building RESTful web services on the Jakarta EE Platform. 

This blog post looks at caching within Jakarta REST. We'll explore how to use the built-in features and functionalities to enhance the performance and user experience of your RESTful APIs through resource caching. By using these techniques, you can significantly reduce server load, improve responsiveness, and enhance the overall efficiency of your web resources.

Why Cache?

Imagine visiting a website for the first time. Your browser diligently downloads images, text and other assets. Upon revisiting, wouldn't it be wonderful if everything loaded instantly? Web caching makes this happen. By storing frequently accessed data locally (browser or proxy cache), subsequent requests retrieve them from the local store, significantly reducing latency, server load and enhancing user experience.

Leveraging Caching in RESTful APIs

Any service that can be accessed through an HTTP GET request, which is inherently read-only and idempotent (meaning repeated requests yield the same outcome with the same input), qualifies for caching.

When to Cache:

To enhance your application's performance and responsiveness, consider caching in the following scenarios:

  • Static Data: Information that rarely changes, such as product descriptions, company information or website configuration files, is ideal for caching. Since it's static, there's little risk of staleness.

  • Dynamic Data with Short Validity: Even frequently updated data, like stock quotes, weather forecasts or news feeds, benefit from caching if they have a defined validity window. Caching this types of data reduces network requests and improves responsiveness for users as long as the data is used within its freshness period.

  • Expensive Computations: If specific calculations or operations are resource-intensive, e.g. complex database queries, image processing or data transformations, caching the results can significantly improve performance, eliminating the need to recompute on every request.

  • Frequently Accessed Resources: Content or data accessed with high frequency, regardless of whether it's static or dynamic, is a prime candidate for caching. This reduces load on the origin server and improves overall response times.

  • Bottlenecked Resources: When your system has limited resources or experiences performance bottlenecks, e.g. slow database, external API with rate limits, caching can alleviate pressure on these points of constraint, leading to a smoother user experience.

Understanding HTTP Caching

The HTTP protocol offers a rich set of features for managing the caching behavior. Let's explore two key headers:

Expires Header (HTTP 1.0)

This header informs the browser about the data's expiration date. After this date, the data are considered stale and needs to be reloaded from the server.

Setting The Expires Header In Jakarta REST

ResponseBuilder builder = Response.ok(data, "application/json");

//Set expiration to a day



This response tells the client to cache the response for the next 5 minutes. Any request for the same data should be returned from the cache of the client. 

Cache-Control Header (HTTP 1.1)

This header provides finer-grained control over caching behavior. It includes directives like max-age, which specifies the duration (in seconds) for which the data are considered valid.

Setting The Cache Control In Jakarta REST

CacheControl cc = new CacheControl();

cc.setMaxAge(300); // Valid for 300 seconds

ResponseBuilder builder = Response.ok(data, "application/json");



The CacheControl class has fields to set other cache control options, such as:

  •  no-cache: Instructs the client to not cache the response
  •  private: Allows only the client to cache the data (not proxy servers or CDNs).

Revalidation and Conditional GETs With ETags

ETags (Entity Tags) are unique identifiers assigned by a web server to a specific version of a resource. They help in validating the freshness of cached content, making web caching more efficient.

You can generate ETags in Jakarta REST using the EntityTag class. 


public class ETagExampleResource {



   public Response getResource() {
      var resource = backendService.fetchSomeResource();
      EntityTag eTag = new EntityTag(Integer.toString(resource.hashCode()));

       return Response.ok(resource)



From the above code snippet:

  1. A client makes a request for the resource
  2. The server sends the resource and the ETag in the response
  3. The client's browser caches the resource and the ETag
  4. Next time the client needs the same resource, it sends the stored ETag in the request header
  5. The server compares the ETags. If they match, the server sends a 'Not Modified' response, which tells the client to use its cached version.

In this way, the server can have precious compute resources freed up for serving other requests. The server only returns new data when the requested data changes. 


Caching plays an extremely important role in ensuring responsive and scalable web resources. With Jakarta REST, you have access to API constructs that allow you to control caching in your APIs. By using classes such as CacheControl and EntityTag, along with the object, you can develop high-performance web services that reduce server load and improve the overall user experience.


Want to see these caching concepts in action? Download Payara Community, a free and open-source application server, and start experimenting with Jakarta REST to optimize your web services.

Payara Platform Community

Branding Tagline_Hubspot Banner-1