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-rsproject and navigate to thesrc/main/java - Create a
recordcalledFishin theexpert.os.labs.persistencepackage - Add the following parameters as
String:idnamecolor
Expected results
- Record
Fishrepresenting a simple Java record to model a fish created
Solution
2. Defining the database class
Steps
- Create a
classcalledFishDatabasein theexpert.os.labs.persistencepackage - Annotate the class with the
@ApplicationScopedfrom thejakarta.enterprise.contextpackage -
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)voidthis.fishes.put(fish.id(), fish);delete(String id)voidthis.fishes.remove(id);clear()voidthis.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
classcalledFishResourcein theexpert.os.labs.persistencepackage -
Annotate the class with the following
Annotations Package @Path("/fishes")jakarta.ws.rs@Consumes(MediaType.APPLICATION_JSON)jakarta.ws.rsandjakarta.ws.rs.core@Produces(MediaType.APPLICATION_JSON)jakarta.ws.rsandjakarta.ws.rs.core -
Inject the
FishDatabaseclass by creating a field calleddatabase -
Implement the
findAll()method:- use the
@GETannotation - the method returnss a
List<Fish> -
the body should call the database-related method
- use the
-
Implement the
findById()method:- use the
@GETannotation together with the@Pathto the/{id} - the method returns the
Fishclass - the method has the
String idparameter annotated with@PathParam("id") -
the body should call the database-related method, if it's not found throw a
WebApplicationExceptionexception with HTTP 404
- use the
-
Implement the
save()method- use the
@POSTannotation - the method is a
void - the method has the
Fish fishparameter -
the body should call the database-related method
Note
We know that an HTTP
POSTmethod 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
@DELETEannotation together with the@Pathto the/{id} - the method returns
void - the method has the
String idparameter 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-rsin the root project folder -
Execute the following command to start the application
-
Open a new Terminal window
-
Run the following
curlcommands, 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/fishesnothing 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/1nothing in the terminal
Expected results
- A simple RESTful web service for managing fish records where
- the
FishDatabaseclass manages the data - the
FishResourceclass exposes REST endpoints to interact with the data
- the