Book Excerpt: Real World Jakarta REST Example
Tags: enterprisejava, cloudnative, jakarta, java
Published: 2021-08-10 18:36:48

---
title: Book Excerpt: Real World Jakarta REST Example
published: true
date: 2021-08-03 12:46:00 UTC
tags: EnterpriseJava,cloudnative,Jakarta,java
canonical_url: https://andymc12.net/2021/08/03/book-excerpt-real-world-jakarta-rest-example/
---

The following in an excerpt from [Practical Cloud-Native Java Development with MicroProfile](https://www.amazon.com/gp/product/1801078807/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1801078807&linkCode=as2&tag=andymc12-20&linkId=700b082a8ed53af047ab2d880cf395de) from [Packt Publishing](https://www.packtpub.com/). It is available for pre-order from [Amazon.com](https://www.amazon.com/gp/product/1801078807/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1801078807&linkCode=as2&tag=andymc12-20&linkId=700b082a8ed53af047ab2d880cf395de) and directly from [Packt](https://www.packtpub.com/product/practical-cloud-native-java-development-with-microprofile/9781801078801). It is scheduled for release in September. This excerpt comes from chapter 4: Building Cloud-Native Applications and describes how to build a more real-world RESTful application using Jakarta REST (aka JAX-RS):

* * *

## A More Real-world Example

Now that we have built a simple JAX-RS application, let’s build a more complex application – a thesaurus service where clients can search and update synonymous words. First, we’ll start with an _exception mapper_:

```
@Provider
public class NoSuchWordExceptionMapper implements ExceptionMapper<NoSuchWordException> {

    @Override
    public Response toResponse(NoSuchWordException ex) {
        return Response.status(404)
                       .entity(ex.getMessage())
                       .build();
    }
}

```

Most applications will have _business exceptions_ – exceptions specific to the application domain. For a thesaurus service, that might include a `NoSuchWordException`, which could be used to indicate that a searched word does not exist. It is clear in the application that somebody specified a word that does not exist, but it is not clear to an HTTP client. The provider class, `NoSuchWordExceptionMapper`, makes that possible. It enables the resource class methods to throw a `NoSuchWordException`, and the JAX-RS container will map the exception to an HTTP response (in this case, a `404 Not Found`).

Next is the resource class (full source code available at: [https://github.com/PacktPublishing/Practical-Cloud-Native-Development-with-MicroProfile-4.0/blob/main/Chapter04/src/main/java/com/packt/microprofile/book/ch4/thesaurus/ThesaurusResource.java](https://github.com/PacktPublishing/Practical-Cloud-Native-Development-with-MicroProfile-4.0/blob/main/Chapter04/src/main/java/com/packt/microprofile/book/ch4/thesaurus/ThesaurusResource.java)):

```
@Path(“/thesaurus/{word}”)
@Consumes(MediaType.TEXT_PLAIN)
@Produces(MediaType.TEXT_PLAIN)
public class ThesaurusResource { // … 

```

There are a few new annotations on the resource class: `@Produces` and `@Consumes`. These annotations can be placed on resource classes or methods – like most annotations of this type in JAX-RS, annotations on the method take priority over annotations on the class. These annotations help control the matching of requests and the entity providers (`MessageBodyReaders` and `MessageBodyWriters`) to be used in deserializing the HTTP entity from the request or serializing the HTTP entity in the response.

HTTP requests and responses may contain a header that indicates the _media type_ (also known as _MIME type_) of the HTTP entity – `Content-Type`. HTTP requests may also contain a header that specifies the media type(s) that it expects to receive in the response – Accept. In the absence of these headers, all media types are allowed (i.e., `*/*`).

In the previous example, the resource class specifies `MediaType.TEXT_PLAIN`, or `text/plain`. Other media types include `text/html`, `application/json`, `application/xml`, `image/jpeg`, and much more. By specifying `text/plain`, that would prevent the resource methods from being invoked if a request contained a header like `Content-Type: application/pdf` or `Accept: image/png` – instead of invoking the resource method, the JAX-RS container would return a `415 Unsupported Media Type` error.

| Best practice: |
| -------------- |
| Always use `@Produces` and `@Consumes` to limit media types. This will place limits on the types of requests your service will respond to. It will ensure that your application (if properly tested) can handle requests of the specified media types. |

This example also introduces new method-level HTTP verb annotations: `@POST`, `@PUT`, `@DELETE` and `@PATCH`. Like `@GET`, these annotations specify which method should be invoked based on the HTTP request’s verb (also known as method – HTTP method is probably the more commonly used term, but we will use verb in this book to disambiguate from Java methods). The JAX-RS API set includes these five verb annotations as well as `@HEAD` and `@OPTIONS` that are less commonly used.

| Special note: |
| ------------- |
| If the resource class contains a method annotated with `@GET` but not `@HEAD`, the JAX-RS container would invoke the `@GET` method for matching HTTP HEAD requests, but it would remove the entity. Likewise, if a resource class contains any HTTP verb annotation other than `@OPTIONS`, the JAX-RS container would return a response indicating all of the valid verbs that could be matched for that request. Using the example above, an OPTIONS request would result in a response with a header like, `Allow: DELETE, HEAD, GET, OPTIONS, PATCH, POST, PUT`. |

This example also introduces the idea of HTTP parameters, specifically:  
` @PathParam(“word”) String word;`

This annotation can be placed on fields or method parameters. The value of `@PathParam` is _word_ which corresponds to the template variable in the resource class’s `@Path` value (`“/thesaurus/{word}”`). This means that for an HTTP request like `http://localhost:9080/myApp/rest/thesaurus/funny`, the value injected in to the word field would be _funny_.

There are other HTTP parameter types that can be used in JAX-RS including `@QueryParam`, `@FormParam`, `@CookieParam`, `@HeaderParam`, `@MatrixParam` which all correspond to different parts of an HTTP request. JAX-RS also allows multiple HTTP parameter annotations to be aggregated on a single Java class and then referenced in the resource class or method as a `@BeanParam`.

* * *

I hope you found this excerpt helpful and enticing. Chapter 4 is _packed_ (pun intended) full of useful knowledge for building and consuming robust RESTful services. It covers the basics, but also a lot of hidden gems in JAX-RS, JSON-B/P, CDI and MicroProfile Rest Client. And if that’s not enough, there’s eleven more chapters filled with cloud-native goodness. Ok, that’s enough advertising for one blog post… ![🙂](https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f642.png) Thanks for reading!