Skip to main content

Introduction to REST Services

Important Message to Students​

ATTENTION: This chapter is an optional review.

This chapter is offered as an additional resource for those who wish to deepen their understanding of REST web services. Although this content is not mandatory for the course, it can be useful for:

  • Students with gaps in web service concepts
  • Those who want a thorough review before tackling Spring Boot
  • People wanting to understand the theoretical foundations of REST

If you are already comfortable with REST web services, you can proceed directly to the next module.


Chapter Content​

This section includes four parts:

  • Part 1: Introduction to REST - Introduction to REST architecture, key principles, and stateless vs stateful concepts
  • Part 2: HTTP Methods - Details on HTTP methods in REST and usage examples with Java
  • Part 3: Practical Examples - Using GET, POST, PUT, and DELETE methods with Java code
  • Part 4: Error Handling - HTTP status codes and error handling in REST APIs

Part 1: Introduction to REST​

REST (Representational State Transfer) is a software architecture designed to create scalable and efficient web services. It was introduced in 2000 by Roy T. Fielding, one of the main creators of the HTTP protocol. REST is based on a set of constraints that make distributed systems simpler and more efficient.

Key Principles of REST​

1. Uniform Interface​

Interactions between the client and server are standardized by using HTTP methods, URIs to identify resources, and standard representation formats like JSON or XML. This allows for clear and consistent communication.

2. Stateless​

The server does not retain any information about the state of sessions between requests. Each client request must contain all the information necessary to process the request. This simplifies session management.

3. Cacheable​

Server responses can be cached to improve performance. Cache directives are specified in HTTP headers, reducing response times and server load.

4. Client-Server​

There is a separation of responsibilities between the client (which manages the user interface) and the server (which handles data storage and business logic). This facilitates independent development of the user interface and backend.

5. Layered System​

The REST architecture can be built in layers, improving the system's flexibility and scalability. For example, one layer can handle authentication, while another can manage data storage.


Stateless vs Stateful​

Stateless Architecture​

In REST, the architecture is stateless. This means that each request sent by a client to the server must contain all the information necessary to process the request. The server does not retain information about the state of previous interactions, simplifying system management.

Example:

GET /api/users/123 HTTP/1.1
Host: example.com
Authorization: Bearer <token>

In this example, the client sends all the necessary information to authenticate the request (via the Authorization header) and identify the requested resource (/api/users/123).

Stateful Architecture​

Conversely, in a stateful architecture, the server retains the session state between requests. This can complicate session management and make the system less flexible and less scalable.


HTTP Methods in REST​

HTTP methods are verbs that indicate the action to be performed on a resource identified by a URI (Uniform Resource Identifier). Here are the most commonly used methods in REST.

HTTP Methods Table​

+-------------+---------------------+---------------------------------------------------------+
| Method | Description | Code Examples |
+-------------+---------------------+---------------------------------------------------------+
| GET | Retrieve a | GET /api/users/123 HTTP/1.1 |
| | resource | Host: example.com |
+-------------+---------------------+---------------------------------------------------------+
| POST | Create a | POST /api/users HTTP/1.1 |
| | resource | Host: example.com |
| | | Content-Type: application/json |
| | | |
| | | { |
| | | "name": "John Doe", |
| | | "email": "john@example.com" |
| | | } |
+-------------+---------------------+---------------------------------------------------------+
| PUT | Replace an | PUT /api/users/123 HTTP/1.1 |
| | entire resource | Host: example.com |
| | | Content-Type: application/json |
+-------------+---------------------+---------------------------------------------------------+
| PATCH | Partially modify | PATCH /api/users/123 HTTP/1.1 |
| | a resource | Host: example.com |
| | | Content-Type: application/json |
+-------------+---------------------+---------------------------------------------------------+
| DELETE | Delete a | DELETE /api/users/123 HTTP/1.1 |
| | resource | Host: example.com |
+-------------+---------------------+---------------------------------------------------------+

Less Commonly Used Methods​

+-------------+---------------------+---------------------------------------------------------+
| OPTIONS | Determine the | OPTIONS /api/users HTTP/1.1 |
| | methods the server | Host: example.com |
| | can handle | |
| | | Response: |
| | | HTTP/1.1 200 OK |
| | | Allow: GET, POST, OPTIONS |
+-------------+---------------------+---------------------------------------------------------+
| HEAD | Retrieve headers | HEAD /api/users/123 HTTP/1.1 |
| | of a resource | Host: example.com |
| | without body | |
| | | Response: |
| | | HTTP/1.1 200 OK |
| | | Content-Type: application/json |
+-------------+---------------------+---------------------------------------------------------+

HTTP Headers​

HTTP headers are important elements that provide additional information about the data transmitted during HTTP requests and responses.

HTTP Headers Table​

+-------------------+----------------------------------+------------------------------------------------+
| Header | Description | Code Example |
+-------------------+----------------------------------+------------------------------------------------+
| Content-Type | Specifies the content type | Content-Type: application/json |
| | of the resource | |
+-------------------+----------------------------------+------------------------------------------------+
| Accept | Indicates the content types | Accept: application/json |
| | the client accepts | |
+-------------------+----------------------------------+------------------------------------------------+
| Authorization | Provides authentication | Authorization: Bearer <token> |
| | information | |
+-------------------+----------------------------------+------------------------------------------------+
| Cache-Control | Sets caching directives | Cache-Control: no-cache |
| | | |
+-------------------+----------------------------------+------------------------------------------------+
| Content-Length | Specifies the size of the | Content-Length: 348 |
| | response body | |
+-------------------+----------------------------------+------------------------------------------------+
| Location | Indicates the location of a | Location: http://example.com/api/users/123 |
| | created resource | |
+-------------------+----------------------------------+------------------------------------------------+

Managing HTTP Codes​

HTTP status codes are used to indicate the result of an HTTP request.

HTTP Status Codes Table​

+-------------------+----------------------------------+------------------------------------------------+
| HTTP Code | Meaning | Example Scenario |
+-------------------+----------------------------------+------------------------------------------------+
| 200 OK | The request succeeded | Response to a GET request to retrieve a |
| | | resource |
+-------------------+----------------------------------+------------------------------------------------+
| 201 Created | A new resource was created | Response to a POST request to create a |
| | | new user |
+-------------------+----------------------------------+------------------------------------------------+
| 204 No Content | The request succeeded but there | Response to a DELETE request after deleting a |
| | is no content to return | resource |
+-------------------+----------------------------------+------------------------------------------------+
| 400 Bad Request | The request is malformed or | The client sends a request with invalid data |
| | contains errors | |
+-------------------+----------------------------------+------------------------------------------------+
| 401 Unauthorized | Authentication required | The client tries to access a resource without |
| | | providing an authentication token |
+-------------------+----------------------------------+------------------------------------------------+
| 403 Forbidden | Access forbidden | The client does not have the necessary |
| | | permission to access the resource |
+-------------------+----------------------------------+------------------------------------------------+
| 404 Not Found | The resource was not found | The client tries to access a resource that |
| | | does not exist |
+-------------------+----------------------------------+------------------------------------------------+
| 500 Internal | An internal server error | An unexpected exception occurs on the server |
| Server Error | occurred | while processing the request |
+-------------------+----------------------------------+------------------------------------------------+

Part 2: HTTP Methods in Detail​

In a REST architecture, HTTP methods define the action the client wishes to perform on a resource.

Summary Table​

MethodDescriptionTypical Usage
GETRetrieves a resource without modifying its stateReading a web page, retrieving data
POSTSends data to create a new resourceSubmitting a form, adding a new entry
PUTUpdates a resource by sending the complete versionReplacing or creating a resource
PATCHPartially updates a resourcePartial modification of an existing resource
DELETEDeletes a specific resourceDeleting an entry, a file
HEADRetrieves headers of a resource, similar to GET, without the bodyChecking the last modification
OPTIONSQueries the server for available methodsPreparing a request, discovering methods

Part 3: Practical Examples with Java​

GET Example: Retrieve a Resource​

@GET
@Path("/testGet")
public Response getTestResource() {
// Logic to retrieve the resource
return Response.ok("Resource successfully retrieved").build();
}

Details:

  1. @GET: This annotation indicates that the method will respond to an HTTP GET request
  2. @Path("/testGet"): Defines the relative URL for this method
  3. Response.ok(): Creates an HTTP response with a 200 (OK) code

Typical usage: Displaying information to the user (user details, product details, etc.)


POST Example: Create a New Resource​

@POST
@Path("/testPost")
@Consumes(MediaType.APPLICATION_JSON)
public Response createTestResource(String json) {
// Logic to create a resource from the received JSON
return Response.status(Response.Status.CREATED).entity("Resource created").build();
}

Details:

  1. @POST: This annotation indicates that the method will respond to an HTTP POST request
  2. @Consumes(MediaType.APPLICATION_JSON): Indicates that the method expects data in JSON format
  3. Response.Status.CREATED: Code 201 indicating that a new resource has been created

Typical usage: Registering a new user, creating a new product


PUT Example: Update a Resource​

@PUT
@Path("/testPut/{id}")
@Consumes(MediaType.APPLICATION_JSON)
public Response updateTestResource(@PathParam("id") String id, String json) {
// Logic to update the resource identified by id
return Response.ok("Resource updated").build();
}

Details:

  1. @PUT: This annotation indicates that the method will respond to an HTTP PUT request
  2. @PathParam("id"): Extracts the resource identifier from the URL
  3. Response.ok(): Code 200 to indicate that the update was successful

Typical usage: Modifying product details, updating a user profile


DELETE Example: Delete a Resource​

@DELETE
@Path("/testDelete/{id}")
public Response deleteTestResource(@PathParam("id") String id) {
// Logic to delete the resource identified by id
return Response.status(Response.Status.NO_CONTENT).build();
}

Details:

  1. @DELETE: This annotation indicates that the method will respond to an HTTP DELETE request
  2. Response.Status.NO_CONTENT: Code 204 indicating that a resource has been deleted with no content to return

Typical usage: Deleting a user, a product, a comment


Part 4: Error Handling​

Proper error handling is essential in REST APIs. Here is how to return the most commonly used status codes.

Code 200 OK​

The 200 OK code indicates that the request was successfully processed.

@GET
@Path("/testGet")
public Response getTestResource() {
return Response.ok("Resource successfully retrieved").build();
}

Code 301 Moved Permanently​

The 301 Moved Permanently code indicates that the resource has been permanently moved.

@GET
@Path("/oldPath")
public Response redirectResource() {
return Response.status(Response.Status.MOVED_PERMANENTLY)
.location(URI.create("/newPath"))
.build();
}

Code 400 Bad Request​

The 400 Bad Request code indicates that the server cannot process the request due to a client error.

@POST
@Path("/testPost")
@Consumes(MediaType.APPLICATION_JSON)
public Response createTestResource(String json) {
if (json == null || json.isEmpty()) {
return Response.status(Response.Status.BAD_REQUEST)
.entity("Invalid data: request body is empty.")
.build();
}
return Response.status(Response.Status.CREATED)
.entity("Resource created")
.build();
}

Code 404 Not Found​

The 404 Not Found code is returned when the requested resource does not exist.

@GET
@Path("/testGet/{id}")
public Response getTestResource(@PathParam("id") String id) {
boolean resourceExists = false;

if (!resourceExists) {
return Response.status(Response.Status.NOT_FOUND)
.entity("Resource not found for ID: " + id)
.build();
}
return Response.ok("Resource found").build();
}

Code 500 Internal Server Error​

The 500 Internal Server Error code indicates that an unexpected error occurred on the server.

@GET
@Path("/testGet/{id}")
public Response getTestResource(@PathParam("id") String id) {
try {
String resource = retrieveResource(id);
return Response.ok(resource).build();
} catch (Exception e) {
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity("Internal server error: " + e.getMessage())
.build();
}
}

Recommendations for Error Handling​

  • Use appropriate HTTP codes: Each code has a specific meaning and allows the client to understand the result of their request
  • Provide clear error messages: Include an explanatory error message in the response body
  • Consider security: Do not disclose too many technical details to avoid providing exploitable information

Conclusion​

This chapter provides a solid foundation for understanding and interacting with RESTful APIs. These concepts are fundamental for working with Spring Boot, which greatly simplifies the creation of REST APIs through its annotations and auto-configuration.

In the following modules, you will see how Spring Boot facilitates the implementation of these REST concepts in an elegant and efficient manner.