JAX-RS - Lab 1
In this lab, we will explore the JAX-RS capability of creating a fish API.
1. Defining the model object
Steps
- Open the
02-jax-rs
project and navigate to thesrc/main/java
- Create a
record
calledFish
in theexpert.os.labs.persistence
package - Add the following parameters as
String
:id
name
color
Expected results
- Record
Fish
representing a simple Java record to model a fish created
Solution
2. Defining the database class
Steps
- Create a
class
calledFishDatabase
in theexpert.os.labs.persistence
package - Annotate the class with the
@ApplicationScoped
from thejakarta.enterprise.context
package -
Add a field to represent a collection of fishes
-
Add a constructor to initialize the collection of fishes
-
Add the following methods with its specific return and body:
method method retun body findAll()
List<Fish>
return List.copyOf(this.fishes.values());
findById(String id)
Optional<Fish>
return Optional.ofNullable(this.fishes.get(id));
save(Fish fish)
void
this.fishes.put(fish.id(), fish);
delete(String id)
void
this.fishes.remove(id);
clear()
void
this.fishes.clear();
Expected results
- Database class with methods to support CRUD operations
Solution
Click to see...
import jakarta.enterprise.context.ApplicationScoped;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@ApplicationScoped
public class FishDatabase {
private Map<String, Fish> fishes;
public FishDatabase() {
this.fishes = new HashMap<>();
}
public List<Fish> findAll() {
return List.copyOf(this.fishes.values());
}
public Optional<Fish> findById(String id) {
return Optional.ofNullable(this.fishes.get(id));
}
public void save(Fish fish) {
this.fishes.put(fish.id(), fish);
}
public void delete(String id) {
this.fishes.remove(id);
}
public void clear() {
this.fishes.clear();
}
}
3. Defining the resource class
Steps
- Create a
class
calledFishResource
in theexpert.os.labs.persistence
package -
Annotate the class with the following
Annotations Package @Path("/fishes")
jakarta.ws.rs
@Consumes(MediaType.APPLICATION_JSON)
jakarta.ws.rs
andjakarta.ws.rs.core
@Produces(MediaType.APPLICATION_JSON)
jakarta.ws.rs
andjakarta.ws.rs.core
-
Inject the
FishDatabase
class by creating a field calleddatabase
-
Implement the
findAll()
method:- use the
@GET
annotation - the method returnss a
List<Fish>
-
the body should call the database-related method
- use the
-
Implement the
findById()
method:- use the
@GET
annotation together with the@Path
to the/{id}
- the method returns the
Fish
class - the method has the
String id
parameter annotated with@PathParam("id")
-
the body should call the database-related method, if it's not found throw a
WebApplicationException
exception with HTTP 404
- use the
-
Implement the
save()
method- use the
@POST
annotation - the method is a
void
- the method has the
Fish fish
parameter -
the body should call the database-related method
Note
We know that an HTTP
POST
method should return the status code 201 and the location header for the resource created. In this exercise, it does not have a return to ease the persistence understanding.
- use the
-
Implement the
deleteById()
method- use the
@DELETE
annotation together with the@Path
to the/{id}
- the method returns
void
- the method has the
String id
parameter annotated with@PathParam("id")
-
the body should call the database-related method
- use the
Expected results
- A simple RESTful web service for managing fish records
Solution
Click to see...
import jakarta.inject.Inject;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import java.util.List;
@Path("/fishes")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class FishResource {
@Inject
FishDatabase database;
@GET
public List<Fish> findAll() {
return this.database.findAll();
}
@GET
@Path("/{id}")
public Fish findById(@PathParam("id") String id) {
return this.database.findById(id)
.orElseThrow(() -> new WebApplicationException("Fish not found", Response.Status.NOT_FOUND));
}
@POST
public void save(Fish fish) {
this.database.save(fish);
}
@DELETE
@Path("/{id}")
public void deleteById(@PathParam("id") String id) {
this.database.delete(id);
}
}
4. Testing the resources
Steps
- Open your Terminal
- Navigate to the
02-jax-rs
in the root project folder -
Execute the following command to start the application
-
Open a new Terminal window
-
Run the following
curl
commands, looking at the related expected results:Command Expected result curl -X POST -H "Content-Type: application/json" -d '{"id":"1","name":"Nemo","color":"Orange"}' http://localhost:8080/fishes
nothing in the terminal curl -X GET http://localhost:8080/fishes
[{"color":"Orange","id":"1","name":"Nemo"}]
curl -X GET http://localhost:8080/fishes/1
[{"color":"Orange","id":"1","name":"Nemo"}]
curl -X DELETE http://localhost:8080/fishes/1
nothing in the terminal
Expected results
- A simple RESTful web service for managing fish records where
- the
FishDatabase
class manages the data - the
FishResource
class exposes REST endpoints to interact with the data
- the