RESTful APIs and Dependency Injection - Learn Quarkus Part 3
Introduction
After creating your first Quarkus app in Part 2, it’s time to jump into some of the most important Quarkus core concepts. This article will focus on Dependency Injection (DI) in Quarkus and how to build RESTful APIs more effectively.
Dependency Injection in Quarkus
Dependency Injection is a core concept in modern software design, and Quarkus provides a powerful yet simple DI solution. Dependency Injection is a design pattern that allows a class to receive its dependencies from external sources rather than creating them itself. This pattern facilitates loose coupling, easier testing, and better code organization. Quarkus utilizes CDI (Contexts and Dependency Injection) for its DI mechanism, which is a set of services that allows Java EE components (such as servlets, enterprise beans, and managed beans) to be bound together dynamically.
Implementing DI
- Create a Service Class:
- Create a new service class, for example
GreetingService.java
, and create agreet
method that you will use later fromGreetingResource
- Make sure to mark the class with annotation
@ApplicationScoped
. This annotation makes the class a CDI managed bean and ensures there is only one instance of it in the application, reducing the amount of memory needed to run the app
package com.codevup.quarkus.demo.service; import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped public class GreetingService { public String greet(String name) { return "Hello " + name + "!"; } }
- Create a new service class, for example
- Inject the Service:
- Modify your
GreetingResource
to useGreetingService
- Annotate
GreetingService
field with@Inject
. This ensure that the instance of the service will be automatically injected whenGreetingResource
is created
package com.codevup.quarkus.demo; import com.codevup.quarkus.demo.service.GreetingService; import jakarta.inject.Inject; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import jakarta.ws.rs.Produces; import jakarta.ws.rs.core.MediaType; @Path("/hello") public class GreetingResource { @Inject GreetingService greetingService; @GET @Produces(MediaType.TEXT_PLAIN) public String hello() { return greetingService.greet("Quarkus"); } }
- Modify your
Building RESTful APIs with Quarkus
RESTful APIs are an essential part of modern web development. We’ve already seen how to create GET
endpoint. Let’s see now how to deal with other REST methods and how to handle request bodies
In order to be able to serialize and deserialize JSON requests and responses, add the following dependency to pom.xml
:
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-jackson</artifactId>
</dependency>
Let’s also add two new classes to handle json requests/responses, GreetingRequest
and GreetingResponse
:
public class GreetingRequest {
private String name;
@JsonCreator
public GreetingRequest(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class GreetingResponse {
private String greeting;
public GreetingResponse(String greeting) {
this.greeting = greeting;
}
public String getGreeting() {
return greeting;
}
public void setGreeting(String greeting) {
this.greeting = greeting;
}
}
Let’s modify our endpoints now:
- GET:
- We can add the name as a query parameter with the
@QueryParam
annotation, and return it as a json:
@GET @Produces(MediaType.APPLICATION_JSON) public GreetingResponse hello(@QueryParam("name") String name) { return new GreetingResponse(greetingService.greet(name)); }
- You can test it by opening the browser and going to http://localhost:8080/hello?name=Codevup
- We can add the name as a query parameter with the
- POST:
- This method is usually used for storing data. Since we haven’t set up a data storage yet, we will just use it to test it out request body serialization. For this purpose, we will add
GreetingRequest
in the method signature@POST @Consumes(MediaType.APPLICATION_JSON) public Response createGreeting(GreetingRequest greetingRequest) { // Implementation to create a greeting return Response.ok().build(); }
- You cannot test this with a browser, you need to use Postman or Curl. When you make a POST request with the following body the response will have a
200
status{ "name": "Codevup" }
- This method is usually used for storing data. Since we haven’t set up a data storage yet, we will just use it to test it out request body serialization. For this purpose, we will add
- PUT:
@DELETE @Consumes(MediaType.TEXT_PLAIN) public Response deleteGreeting(String name) { // Implementation to delete a greeting return Response.ok().build(); }
- DELETE:
@PUT @Consumes(MediaType.TEXT_PLAIN) public Response updateGreeting(String name) { // Implementation to update a greeting return Response.ok().build(); }
Conclusion
In this article, you’ve learned about Dependency Injection in Quarkus and how to build RESTful APIs efficiently. These concepts are foundational in creating scalable, maintainable, and efficient applications in Quarkus. In the upcoming tutorials, we’ll explore database integration, microservices architecture, and more advanced features of Quarkus.