In this tutorial, we will learn how to create a JAX-RS CRUD example with RESTEasy. The Create, Read, Update, and Delete (CRUD) are the four basic functions of persistent storage.
Before getting started, I would like to give you an overview of JAX-RS Java API.
What is JAX-RS?
JAX-RS (Java API for RESTful Web Services) is a set of Java API that provides support in creating REST APIs. And the framework makes good use of JAX-RS annotations to simplify the development and deployment of these APIs.
JAX-RS 2.0 (JSR-339) and JAX-RS 2.1 (JSR-370), are JCP (Java Community Process) specifications that provide a Java API for RESTful Web Services over the HTTP protocol.
Some of the more well known JAX-RS API implementations are RESTEasy and Jersey.

JAX-RS HTTP annotations
JAX-RS has annotations for responding to HTTP requests.
@GET
– indicates that the annotated method responds to HTTP GET request@POST
– indicates that the annotated method responds to an HTTP POST request@DELETE
– indicates that the annotated method responds to an HTTP DELETE request@PUT
– indicates that the annotated method responds to HTTP PUT request
What is RESTEasy?
RESTEasy is a Java framework for developing RESTful Web Services. It is a fully certified and portable implementation of the JAX-RS 2.0 specification.
RESTEasy provides tighter integration with the JBoss Application Server but we can deploy it on any servlet container like Tomcat, Jetty, etc.
In this tutorial, we use the tomcat server to deploy the RESTEasy web application.
Tools and Technologies used
- JDK 1.8 or later
- Maven 3.5+
- Eclipse IDE
- JAX-RS 2.0 +
- RESTEasy – 3.9.3.Final
- Tomcat 8.5+
Development Steps
- Create a Maven Web project in Eclipse IDE
- Add Maven Dependencies
- Project Structure
- Create a User model class
- Create a UserService class
- Create a UserResource class
- Create an Application Class
- RESTEasy Client for REST API
- Conclusion
1. Create a Maven Web project in Eclipse IDE
Refer below guide to create a web project in eclipse IDE:

2. Add maven dependencies
Here is the complete Maven pom.xml file. It contains dependencies for RESTEasy, Jackson provider, and RESTEasy client.
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.favtuts</groupId> <artifactId>resteasy-crud-example-tutorial</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <name>resteasy-crud-example-tutorial Maven Webapp</name> <!-- FIXME change it to the project's website --> <url>https://www.tuts.heomi.net</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.7</maven.compiler.source> <maven.compiler.target>1.7</maven.compiler.target> <resteasy.version>3.9.3.Final</resteasy.version> </properties> <dependencies> <!-- Set up RESTEasy --> <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-jaxrs</artifactId> <version>${resteasy.version}</version> </dependency> <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-servlet-initializer</artifactId> <version>${resteasy.version}</version> </dependency> <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-jackson-provider</artifactId> <version>${resteasy.version}</version> </dependency> <!-- RESTEasy Client Dependency --> <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-client</artifactId> <version>${resteasy.version}</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> </dependencies> <build> <finalName>resteasy-crud-example-tutorial</finalName> </build> </project>
3. Project Structure
Refer below screenshot for project structure and packaging structure:
resteasy-crud-example-tutorial/
├── pom.xml
├── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ └── favtuts
│ │ │ └── resteasy
│ │ │ ├── model
│ │ │ │ └── User.java
│ │ │ ├── resource
│ │ │ │ ├── RestEasyServices.java
│ │ │ │ └── UserResource.java
│ │ │ └── service
│ │ │ └── UserService.java
│ │ └── webapp
│ │ ├── index.jsp
│ │ └── WEB-INF
│ │ └── web.xml
│ └── test
│ └── java
│ └── com
│ └── favtuts
│ └── resteasy
│ └── UserResourceTest.java
└── target
4. Create a User model class
This is a User
model class. It contains three attributes: id
, name
, and email
.
package com.favtuts.resteasy.model; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class User { private Long id; private String name; private String email; public User() { } public User(Long id, String name, String email) { super(); this.id = id; this.name = name; this.email = email; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } @Override public String toString() { return "User [id=" + id + ", name=" + name + ", email=" + email + "]"; } }
5. Create a UserService class
Let’s create UserService
which provides in-memory storage for user objects. UserService
contains CRUD contract methods. We have methods for finding users, saving a user, updating a use, and deleting a user.
package com.favtuts.resteasy.service; import java.util.ArrayList; import java.util.List; import javax.ws.rs.NotFoundException; import com.favtuts.resteasy.model.User; public class UserService { private static List<User> users = new ArrayList<User>(); public List<User> findAll() { if (users.size() <= 0) { users.add(new User(100L, "Ramesh", "ramesh@gmail.com")); users.add(new User(101L, "Tony", "tony@gmail.com")); users.add(new User(102L, "Tom", "tom@gmail.com")); } return users; } public User fetchBy(long id) throws NotFoundException { for (User user : findAll()) { if (id == user.getId()) { return user; } else { throw new NotFoundException("Resource not found with Id :: " + id); } } return null; } public boolean create(User newUser) { for (User user : users) { if (user.getId().equals(newUser.getId())) { return false; } } return users.add(newUser); } public boolean update(User updateUser) { for (User user : users) { if (user.getId().equals(updateUser.getId())) { users.remove(user); users.add(updateUser); return true; } } return false; } public boolean delete(Long id) throws NotFoundException { for (User user : users) { if (user.getId().equals(id)) { users.remove(user); return true; } } return false; } }
6. Create UserResource class
Finally, let’s see an actual CRUD API definition here:
package com.favtuts.resteasy.resource; import java.util.List; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import com.favtuts.resteasy.model.User; import com.favtuts.resteasy.service.UserService; /* * CRUD Rest APIs for User Resource * @author FAVTUTS.COM * */ @Path("users") public class UserResource { private UserService userService = new UserService(); @GET @Produces(MediaType.APPLICATION_JSON) public Response getUsers() { List<User> users = userService.findAll(); if (!users.isEmpty()) { return Response.ok(users).build(); } else { return Response.status(Response.Status.NOT_FOUND).build(); } } @GET @Path("/{id}") @Produces(MediaType.APPLICATION_JSON) public Response getUserById(@PathParam("id") Long id) { User user = userService.fetchBy(id); if (user.getId() != null) { return Response.ok(user).build(); } else { return Response.status(Response.Status.NOT_FOUND).build(); } } @POST @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public Response createUser(User user) { boolean result = userService.create(user); if (result) { return Response.ok().status(Response.Status.CREATED).build(); } else { return Response.notModified().build(); } } @PUT @Path("/{id}") @Consumes(MediaType.APPLICATION_JSON) public Response updateUser(@PathParam("id") long id, User user) { user.setId(id); boolean result = userService.update(user); // return Response.ok().status(Response.Status.NO_CONTENT).build(); if (result) { return Response.ok().status(Response.Status.NO_CONTENT).build(); } else { return Response.notModified().build(); } } @DELETE @Path("/{id}") @Produces(MediaType.APPLICATION_JSON) public Response deleteUser(@PathParam("id") Long id) { boolean result = userService.delete(id); if (result) { return Response.ok().status(Response.Status.NO_CONTENT).build(); } else { return Response.notModified().build(); } } }
Let’s understand the JAX-RS annotations from the above code:
- The
@Path
annotation specifies the URL to which the resource responds. - The
@GET
annotation indicates that the annotated method responds to HTTP GET requests. - The
@Produces
annotation is used to specify the MIME media types of representations a resource can produce and send back to the client. - When creating a new resource, we use
@POST
annotation. - The
@Consumes
annotation is used to specify which MIME media types of representations a resource can accept, or consume, from the client.
7. Create Application Class
Let’s create an application configuration class. The Application defines the components of a JAX-RS application and supplies additional meta-data. The javax.ws.rs.core.Application
class is a standard JAX-RS class that you may implement to provide information on your deployment:
package com.favtuts.resteasy.resource; import java.util.HashSet; import java.util.Set; import javax.ws.rs.ApplicationPath; import javax.ws.rs.core.Application; @ApplicationPath("/restapi") public class RestEasyServices extends Application { private Set<Object> singletons = new HashSet<Object>(); public RestEasyServices() { singletons.add(new UserResource()); } @Override public Set<Object> getSingletons() { return singletons; } }
Notice that with the @ApplicationPath
annotation, we set the path to RESTful web services.
8. RESTEasy Client for REST API
JAX-RS 2.0 introduces a new client API so that you can make HTTP requests to your remote RESTful web services. It is a ‘fluent’ request building API with really 3 main classes: Client
, WebTarget
, and Response
.
The Client
interface is a builder of WebTarget
instances.
WebTarget
represents a distinct URL or URL template from which you can build more sub-resource WebTargets or invoke requests on.
There are really two ways to create a Client. The standard way or you can use the ResteasyClientBuilder
class. The advantage of the latter is that it gives you a few more helper methods to configure your client. Sample code:
Client client = ClientBuilder.newClient(); ... or... Client client = ClientBuilder.newBuilder().build(); WebTarget target = client.target("http://foo.com/resource"); Response response = target.request().get(); String value = response.readEntity(String.class); response.close(); // You should close connections! ResteasyClient client = new ResteasyClientBuilder().build(); ResteasyWebTarget target = client.target("http://foo.com/resource");
To user RESTEasy Client, we need to add a resteasy-client
dependency in the pom.xml
:
<dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-client</artifactId> <version>3.9.3.Final</version> </dependency>
Let’s create a JUnit test cases to GET, POST, PUT and DELETE Rest web services with RESTEasy:
package com.favtuts.resteasy; import javax.ws.rs.client.Entity; import javax.ws.rs.core.Response; import org.jboss.resteasy.client.jaxrs.ResteasyClient; import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder; import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget; import org.junit.FixMethodOrder; import org.junit.Test; import org.junit.runners.MethodSorters; import com.favtuts.resteasy.model.User; @FixMethodOrder(MethodSorters.NAME_ASCENDING) // force name ordering public class UserResourceTest { private static final String FULL_PATH = "http://localhost:8080/resteasy-crud-example-tutorial/restapi/users"; @Test public void test1ListAllUsers() { System.out.println("test1ListAllUsers ..."); final ResteasyClient client = new ResteasyClientBuilder().build(); final ResteasyWebTarget target = client.target(FULL_PATH); String response = target.request().get(String.class); System.out.println(response); } @Test public void test2CreateUser() { System.out.println("test2CreateUser ..."); User user = new User(103L, "Amir", "amir@gmail.com"); final ResteasyClient client = new ResteasyClientBuilder().build(); final ResteasyWebTarget target = client.target(FULL_PATH); Response response = target.request() .post(Entity.entity(user, "application/json")); System.out.println(response.getStatus()); response.close(); } @Test public void test3UpdateUser() { System.out.println("test3UpdateUser ..."); User user = new User(); user.setName("Ram"); user.setEmail("ram@gmail.com"); final ResteasyClient client = new ResteasyClientBuilder().build(); final ResteasyWebTarget target = client.target(FULL_PATH + "/100"); Response response = target.request() .put(Entity.entity(user, "application/json")); System.out.println(response.getStatus()); response.close(); } @Test public void test4DeleteUser() { System.out.println("test4DeleteUser ..."); final ResteasyClient client = new ResteasyClientBuilder().build(); final ResteasyWebTarget target = client.target(FULL_PATH + "/101"); Response response = target.request() .delete(); System.out.println(response.getStatus()); response.close(); final ResteasyWebTarget target1 = client.target(FULL_PATH); String response1 = target1.request().get(String.class); System.out.println(response1); } }
Run above the JUnit test case to test all CRUD REST APIs. Here is the output of JUnit test cases:

9. Test CRUD APIs with Postman or cURL
List all users
curl --location --request GET 'http://localhost:8080/resteasy-crud-example-tutorial/restapi/users'
Create new user
curl --location --request POST 'http://localhost:8080/resteasy-crud-example-tutorial/restapi/users' \
--header 'Content-Type: application/json' \
--data-raw '{
"id":103,
"name": "Amir",
"email": "amir@gmail.com"
}'
Update user info
curl --location --request PUT 'http://localhost:8080/resteasy-crud-example-tutorial/restapi/users/100' \
--header 'Content-Type: application/json' \
--data-raw '{
"name": "Ram",
"email": "ram@gmail.com"
}'
Delete the user
curl --location --request DELETE 'http://localhost:8080/resteasy-crud-example-tutorial/restapi/users/101'
Conclusion
In this tutorial, we have created a CRUD RESTFul application with RESTEasy. The application was deployed on Tomcat/JBoss EAP 7.4.
Download Source Code
$ git clone https://github.com/favtuts/java-jax-rs-tutorials.git
$ cd resteasy-crud-example-tutorialRun web project on JBoss EAP 7.4 or Tomcat
$ mvn test