Previously we’ve learned about a method called POST that is used for passing data to a web application server. In this section, we will explore another method for sending data called PUT.

PUT request is idempotent, which means that you can apply it multiple times without changing the result beyond the initial application. In contrast, a POST request is not idempotent, which means that the requests made after the initial one could have additional effects. A PUT request is valuable when we want to handle a request being sent multiple times without making changes every time it is sent.

In this topic, we will further explore how PUT requests are implemented, as well as discuss the situations where PUT requests work best.

PUT vs POST

We will start by getting an idea of how PUT and POST differ from each other. Understanding this will help us decide when to use each method in an application. Typically, PUT is intended to be used for requests where a single entity is associated with a Request-URI. For example, if we are storing user data, we might want to have the functionality to modify a user based on their ID. To accomplish this, we could use a URI like /users/{id}. In this situation, each user is associated with a single URI. The user with ID 1 has the URI /users/1, the user with ID 2 has URI /users/2 , and so on. For this example, a PUT request would be an appropriate way to implement the update for each individual user. With a general URI like /users, we can manipulate a single object or a list of objects. Since there is a possibility of modifying multiple objects, a POST request would be a more appropriate choice.

As well as the number of resources, the anticipated number of requests to the resource can also help you decide which request to use. Since PUT is idempotent, you should use it in any situation where multiple requests to a resource might be made. This can occur in situations where adding and updating are allowed through the same path. If we don’t anticipate multiple requests to the same resource, a POST request is likely a better choice. As a general practice, PUT will be used for any operations which update an existing resource. POST will typically be used for any operation which creates a new resource.

In the next section, we will take a look at an example of how PUT is implemented, and how we can send requests to a PUT handler.

Implementing PUT

The @PutMapping annotation is used in a @RestController to allow for handling of PUT requests. The general structure of a PUT request is similar to a POST request in terms of how it accepts and processes data. Data can be sent to a PUT request using @RequestBody@PathVariable, and @RequestParam. Since PUT requests are usually implemented for a specific Request-URI, it is common to see at least one @PathVariable in the request.

As an example, suppose that you wanted to create a mapping of employee IDs. We want the user to be able to either insert a single employee or modify a single employee’s name. Since we are working with one employee at a time, and want to modify as well as create records, a PUT request seems to be a good choice.

We will create an Employee object, and pass it through a @RequestBody using JSON format. Here is the definition of our Employee object.

public class Employee {

    private long id;
    private String name;
    private int age;

    // getters and setters
}

We will start by creating a @RestController to contain our requests. For this example, we will use a ConcurrentHashMap to store our employee data.

@RestController
public class EmployeeController {
    private ConcurrentMap<Long, Employee> employeeMap = new ConcurrentHashMap<>();
}

Next, we will use the @PutMappingannotation to create our PUT handler. We want to be able to update or add a single employee, using the employee ID as our key. To make this happen, we will create a @PathVariable to store the ID of the employee we want to work with.
We will pass the info about the employee as a single object using the @RequestBody annotation. The code below shows the general structure of a @PutMapping.

@RestController
public class EmployeeController {
    private ConcurrentMap<Long, Employee> employeeMap = new ConcurrentHashMap<>();
	
    @PutMapping("/employees/{id}")
    public Employee updateEmployee(@PathVariable long id, @RequestBody Employee employee) {
        employeeMap.put(id, employee);
        return employee;
    }
}

If we were working only with individual values, we could use a @RequestParam to apply name or another value instead of the whole information about an employee.

Finally, we will implement a @GetMapping to test if our PUT request is successful. You can see completed code below.

@RestController
public class EmployeeController {
    private ConcurrentMap<Long, Employee> employeeMap = new ConcurrentHashMap<>();
	
    @PutMapping("/employees/{id}")
    public Employee updateEmployee(@PathVariable long id, @RequestBody Employee employee) {
        employeeMap.put(id, employee);
        return employee;
    }
	
    @GetMapping("/employees/{id}")
    public Employee getEmployee(@PathVariable long id) {
        return employeeMap.get(id);
    }
}

When we send a PUT request to our application, we will need to provide two values. The first is the employee ID, which is included in the URI path. The second is a JSON representation of the Employee object, which is provided as a @RequestBody to the query. To test this, let’s try creating a new employee.

To verify that the PUT request completed successfully, we can try sending a request through GET.

Finally, we can try updating the record we created to verify that the PUT request is able to update records.

Note that when we send a new PUT request with ID 1, our handler updates the existing employee record rather than creating a new one. That’s why now we expect the GET request to return our updated name.

One final test you can try with the PUT request is to send a request to the same ID multiple times. You will see that no matter how many times you send a single request to an ID, the record will not change from the original request. The only way it will change is if the request changes.

Conclusion

In this topic, we have discussed PUT requests, which are a type of REST request used to send data to a server. Unlike POSTPUT is an idempotent request, meaning that if a request is sent multiple times, it is equivalent to a single request. We typically use PUT requests to modify single resources and PUT works particularly well for update operations. Using GETPOST, and PUT, you can now build applications that can retrieve, add and modify data from users.

Leave a Reply

Your email address will not be published.