Contents

Jakarta EE REST API HTTP methods

Written by: David Vlijmincx

Introduction

Jakarta EE provides standard HTTP methods, such as GET, POST, PUT, and DELETE, that enable developers to interact with web resources. Understanding these HTTP methods and their proper usage is essential for building web applications. This article will explore how to use different HTTP methods with Jakarta EE and provide examples of their implementation.

Setup

The examples were built inside the following class. The class is annotated with @Path to set the base path of the class. The @Produces(MediaType.APPLICATION_JSON) is placed at the class level because every method returns a JSON object to the client.

As the @Path name does suggest, the methods are about a pet shop. We will implement basic REST calls to keep track of the animals inside our shop. The animals are stored inside a Hashmap.

1
2
3
4
5
6
7
@Path("/pet-shop")
@Produces(MediaType.APPLICATION_JSON)
public class RestResource {

    static Map<String, Pet> pets = new HashMap<>();

}

@GET

The @GET annotation is used to retrieve information from the REST resource. When a client sends a GET request to a URL mapped to a resource method annotated with @GET, the Jakarta EE server invokes that method and returns the response to the client.

In the following example, the @GET annotated method returns a response object.

1
2
3
4
5
6
7
8
@GET()
@Path("/{name}")
public Response getPet(@PathParam("name") String name) {
    return Optional.ofNullable(pets.get(name))
            .map(Response::ok)
            .orElse(Response.status(Response.Status.NOT_FOUND))
            .build();
}

@OPTIONS

Use the @OPTIONS to tell the client which HTTP methods your resource support.

1
2
3
4
5
6
@OPTIONS
public Response httpOptions() {
    return Response.ok()
            .header(HttpHeaders.ALLOW, "OPTIONS,HEAD,GET,POST,PUT,DELETE")
            .build();
}

@POST

The POST method is used to send data to the application. In this case, we use it to create a new pet.

When creating the response, we also build a URI that points to the newly created pet. When a client creates a Pet, the response will have a header called location with the URL as a value. If you create a pet called Jason, the URL would be: http://localhost:8080/my-app/Jason.

1
2
3
4
5
6
7
8
@POST
public Response create(Pet pet) {
    pets.put(pet.getName(), pet);
    URI uri = UriBuilder.fromMethod(RestResource.class, "getPet")
        .build(pet.getName())
        .normalize();
    return Response.created(uri).entity(pet).build();
}

@DELETE

Next up is the @DELETE annotation to delete a pet from the hop. The DELETE HTTP verb is used to delete a resource from the server, and the server responds with a 204 No Content status code to indicate the request was successful.

In the example, we check if there is a pet with the given name. If the pet exists, we delete it from the map and return a 204 status code. If the pet does not exist, a 404 not found is returned to the client.

1
2
3
4
5
6
7
8
@DELETE
@Path("/{name}")
public Response delete(@PathParam("name") String name) {
    return Optional.ofNullable(pets.remove(name))
            .map(p -> Response.noContent())
            .orElse(Response.status(Response.Status.NOT_FOUND))
            .build();
}

The HEAD request is often used to check if a resource exists. In the following example, we return a “204 no content” to tell the client that the pet exists. If the pet doesn't exist, a 404 not found is returned.

1
2
3
4
5
6
7
8
@HEAD
@Path("/{name}")
public Response head(@PathParam("name") String name) {
    return Optional.ofNullable(pets.get(name))
            .map(p -> Response.noContent())
            .orElse(Response.status(Response.Status.NOT_FOUND))
            .build();
}

@PUT

@PUT is used to update an existing resource if it exists. In the following example, we update the age and type with the new values the client sent. Lke with the @POST, we again sent a location back to the client of where it can find the pet in the future.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
@PUT
@Path("/{name}")
public Response put(@PathParam("name") String name, Pet pet) {
    return Optional.ofNullable(pets.get(name)).map(ExistingPet -> {
                ExistingPet.setAge(pet.getAge());
                ExistingPet.setType(pet.getType());

                URI uri = UriBuilder.fromMethod(RestResource.class, "getPet")
                                    .build(ExistingPet.getName())
                                    .normalize();
                return Response.created(uri).entity(pet);
            })
            .orElse(Response.status(Response.Status.NOT_FOUND))
            .build();
}

Conclusion

Jakarta provides a wide range of HTTP verbs that can be used to interact with RESTful web services. These verbs include GET, POST, PUT, DELETE, HEAD, and OPTIONS, each of which has a specific purpose and functionality.