Course – LS (cat=REST)

Get started with Spring and Spring Boot, through the reference Learn Spring course:

>> CHECK OUT THE COURSE

1. Overview

In this tutorial, we’ll examine two important HTTP methods, PUT and POST, that we frequently use within the REST architecture. It’s no secret that developers sometimes struggle to choose between these two methods while designing a RESTful web service. Therefore, we’ll address this issue with a simple implementation of a RESTful application in Spring Boot.

2. PUT vs POST Dilemma

In a typical REST architecture, a client sends requests in the form of HTTP methods to the server to create, retrieve, modify, or destroy resources. While we can use both PUT and POST to create resources, there are significant differences between them in terms of their intended applications.

According to the RFC 2616 standard, the POST method should be used to request that the server accept the enclosed entity as a subordinate of the existing resource identified by the Request-URI. This means the POST method call will create a child resource under a collection of resources.

Conversely, the PUT method should be used to request that the server store the enclosed entity under the provided Request-URI. If the Request-URI points to an existing resource on the server, the supplied entity will be considered a modified version of the existing resource. Therefore, the PUT method call will either create a new resource or update an existing one.

Another important difference between the methods is that PUT is an idempotent method, while POST isn’t. For instance, calling the PUT method multiple times will either create or update the same resource. In contrast, multiple POST requests will lead to the creation of the same resource multiple times.

3. Sample Application

To demonstrate the difference between PUT and POST, we’ll create a simple RESTful web application using Spring Boot. The application will store the names and addresses of people.

3.1. Maven Dependencies

To begin with, we need to include the dependencies for Spring Web, Spring Data JPA, and the in-memory H2 database in our pom.xml file:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>runtime</scope>
</dependency>

3.2. Domain Entity and Repository Interface

Let’s start by creating the domain object first. For the address book, we’ll define an Entity class called Address that we’ll use to store the address information of individuals. For the sake of simplicity, we’ll use three fields, name, city, and postalCode, for our Address entity:

@Entity
public class Address {

    private @Id @GeneratedValue Long id;
    private String name;
    private String city;
    private String postalCode;

    // constructors, getters, and setters
}

The next step is to access the data from the database. For simplicity, we’ll leverage Spring Data JPA’s JpaRepository. This will allow us to perform CRUD functionalities on the data without writing any additional code:

public interface AddressRepository extends JpaRepository<Address, Long> {
}

3.3. REST Controller

Finally, we need to define the API endpoints for our application. We’ll create a RestController that will consume HTTP requests from the client and send back the appropriate response.

Here, we’ll define a @PostMapping for creating new addresses and storing them in the database, and a @PutMapping to update the content of the address book based on the request URI. If the URI isn’t found, it will create a new address and store it in the database:

@RestController
public class AddressController {

    private final AddressRepository repository;

    AddressController(AddressRepository repository) {
        this.repository = repository;
    }

    @PostMapping("/addresses")
    Address createNewAddress(@RequestBody Address newAddress) {
        return repository.save(newAddress);
    }

    @PutMapping("/addresses/{id}")
    Address replaceEmployee(@RequestBody Address newAddress, @PathVariable Long id) {

        return repository.findById(id)
            .map(address -> {
                address.setCity(newAddress.getCity());
                address.setPin(newAddress.getPostalCode());
                return repository.save(address);
            })
            .orElseGet(() -> {
                return repository.save(newAddress);
            });
    }
    //additional methods omitted
}

3.4. cURL Requests

Now we can test our developed application by using cURL to send sample HTTP requests to our server.

For creating a new address, we’ll enclose the data in JSON format and send it through a POST request:

curl -X POST --header 'Content-Type: application/json' \
    -d '{ "name": "John Doe", "city": "Berlin", "postalCode": "10585" }' \ 
    http://localhost:8080/addresses

Now let’s update the content of the address we created. We’ll send a PUT request using the id of that address in the URL. In this example, we’ll update the city and the postalCode section of the address we just created. We’ll suppose it was saved with id=1:

curl -X PUT --header 'Content-Type: application/json' \
  -d '{ "name": "John Doe", "city": "Frankfurt", "postalCode": "60306" }' \ 
  http://localhost:8080/addresses/1

4. Conclusion

In this article, we discussed the conceptual differences between the HTTP methods PUT and POST. Additionally, we learned how these methods can be implemented using the Spring Boot framework for developing RESTful applications.

In conclusion, we should use the POST method to create a new resource, and the PUT method to update an existing resource.

As always, the code for this article is available over on GitHub.

Course – LS (cat=REST)

Get started with Spring and Spring Boot, through the Learn Spring course :

>> CHECK OUT THE COURSE
res – REST (eBook) (cat=REST)
Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.