RESTEasy: How to create Web Services its clients
Today we are going to see RESTEasy which is a JBoss framework, which offers us an implementation for the JAX-RS 2.0 and 2.1 specifications. And as it is normal, although it is thought for perfect integration with WildFly, it will also offer us the possibility of deploying it in any other servlet container such as Tomcat or Jetty.
Let’s start with the Web Service, which will be very basic, just enough to show how to set up a more complex one. The first thing will be to indicate which are the minimum necessary dependencies:
- resteasy-servlet-initializer
It allows us to generate the Web Service without the need for manual configuration on our part. That is to say, with the following annotations it will be enough to configure our service. We will not need to configure anything in the web.xml file as we did in this other post. We could even not create a web.xml file. But we will not do this, to avoid problems with Maven compilation.
This library has also as dependencies the main libraries of the framework: resteasy-core and the libraries with the implementations of the spec.
- resteasy-jackson2-provider
It is the library that allows the transformation of the response in Java object format to JSON. In case you want to respond XML you should include the resteasy-jaxb-provider library. If we do not include the library we can have an error like: Could not find MessageBodyWriter for response object of type: com.home.example.resteasy.bean.Book of media type: application/json.
Once we have indicated the dependencies in the pom.xml file. And as we said before, we can use a web.xml file well-formed but without content. Now we are going to configure the service in two simple steps.
We must create a class that extends javax.ws.rs.core.Application. And that also has the javax.ws.rs.ApplicationPath annotation with which we will be able to indicate the main path of our Web Service. Therefore, to be able to access the REST methods we will have to indicate the name of the service and the application path indicated in the annotation. Example:
@ApplicationPath("/library")
public class LibraryApplication extends Application {
}
The next step is to create the REST methods. We can do it through different annotations:
- @Path: This allows us to indicate a common path for all the methods.
- @POST, @GET, @DELETE, or @PUT: Indicates which HTTP method the method is associated with.
- @Produces, @Consume: This allows us to indicate what format the input or output will have. JSON or XML.
- @PathParam, @QueryParam: This allows to indicate how we will receive parameters through the invocation URL.
In addition to this, there are other annotations that will allow us a greater configuration of the methods, to indicate the cookies, headers, default values, or even if the parameters are encoded.
If we want to return an object in a specific format we will not need anything more than to return that object. But if we want to return a more customized response, where we indicate cookies, response code, etc., we will do it through the object javax.ws.rs.core.Response. Example:
If we want to use it, we must invoke the command Maven: clean package and deploy the generated .war file in our favorite container or application server. And we will be able to use it by invoking the following command:
curl --location --request GET 'http://localhost:8080/RestEasyService/library/book/1'
Our next step will be to create the client. We can create it in two different ways, but always using the ResteasyClientBuilder utility class. It has a basic method to create the client but it also provides methods for a greater configuration of the client, besides allowing us to create a WebTarget object.
Once at this point, we can invoke the Web Service in two different ways.
- The first one, it will be more rudimentary and will need a greater configuration for each of the calls, as well as to indicate the exact URL at the time of creating the WebTarget object. This object will allow us to make the corresponding REST calls through its get() or post() methods and indicating what type of object we are going to receive.
- For the second way to create the client, we will use the RESTEasy Proxy framework. This will allow us to make simpler invocations but as a negative point, we will have to create an interface that complies with the Web Service contract. The biggest disadvantage of this interface is that we will have to create it manually through JAX-RS annotations, but the most positive thing is that we will be able to create Web Services clients that do not have to have been generated by JAX-RS. An example of the interface:
To create a proxy type object, we can obtain it through the WebTarget object, indicating the interface that has the Web Service contract. For this case we will not need to indicate the exact URL of each one of the methods and the invocations and treatments of the answer, we will make it in a more natural and understandable way.
With this, we already know how to create a Web Service and its client but we are going to see one last important detail such as the configuration through the MicroProfile Config class.
This class will allow us to comply with the 12factor methodology, allowing us to configure the client or service through environment variables, system properties, or a specific configuration file. Next, we will see how we can modify the previous client creation to obtain the service address through an environment variable.
By priority it will first try to get the value of system property, then of an environment variable and finally it will look for it in the classpath file META-INF/microprofile-config.properties. Although these priority values and information sources are also configurable. This will allow us to keep the application code immutable in each environment in which we deploy our application.
And up to here the basic notions to create Web Services and clients with the JBoss framework. If you want you can see the source code here.