1. Overview
1.概述
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.
在本教程中,我们将研究在REST架构中经常使用的两种重要的HTTP方法:PUT和POST。在设计RESTful Web服务时,开发人员有时会在这两种方法之间做出选择,这不是什么秘密。因此,我们将通过在Spring Boot中简单实现一个RESTful应用程序来解决这个问题。
2. PUT vs POST Dilemma
2.PUT与POST的两难选择
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.
在典型的REST架构中,客户端以HTTP方法的形式向服务器发送请求,以创建、检索、修改或销毁资源。虽然我们可以使用PUT和POST来创建资源,但它们之间在预期应用方面有很大的区别。
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.
根据RFC 2616标准,应使用POST方法来请求服务器接受所附实体作为由Request-URI标识的现有资源的下级。这意味着POST方法调用将在一个资源集合下创建一个子资源。
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.
相反,PUT方法应该被用来请求服务器在提供的Request-URI下存储所附的实体。如果Request-URI指向服务器上的现有资源,那么提供的实体将被视为现有资源的修改版本。因此,PUT方法调用将创建一个新的资源或更新一个现有的资源。
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.
这两种方法的另一个重要区别是,PUT是一个等价的方法,而POST则不是。例如,多次调用PUT方法将创建或更新同一资源。相反,多次POST请求将导致多次创建同一资源。
3. Sample Application
3.申请书样本
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.
为了演示PUT和POST的区别,我们将使用Spring Boot创建一个简单的RESTful Web应用程序。该应用程序将存储人们的姓名和地址。
3.1. Maven Dependencies
3.1.Maven的依赖性
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:
首先,我们需要在pom.xml文件中包含Spring Web、Spring Data JPA和内存H2数据库的依赖。
<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
3.2.领域实体和存储库接口
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类,名为Address,我们将用它来存储个人的地址信息。为了简单起见,我们将为我们的Address实体使用三个字段:name、city、postalCode。
@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:
下一步是访问数据库中的数据。为了简单起见,我们将利用Spring Data JPA的 JpaRepository。这将使我们能够对数据执行CRUD功能,而无需编写任何额外的代码。
public interface AddressRepository extends JpaRepository<Address, Long> {
}
3.3. REST Controller
3.3.REST控制器
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.
最后,我们需要为我们的应用程序定义API端点。我们将创建一个RestController,它将接收来自客户端的HTTP请求,并送回适当的响应。
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:
在这里,我们将定义一个@PostMapping,用于创建新的地址并将其存储在数据库中,和一个@PutMapping,根据请求URI更新地址簿的内容。如果没有找到URI,它将创建一个新的地址并将其存储在数据库中。
@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
3.4. cURL请求
Now we can test our developed application by using cURL to send sample HTTP requests to our server.
现在我们可以通过使用cURL向我们的服务器发送HTTP请求样本来测试我们开发的应用程序。
For creating a new address, we’ll enclose the data in JSON format and send it through a POST request:
为了创建一个新的地址,我们将以JSON格式封装数据,并通过一个POST请求发送。
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:
现在让我们来更新我们创建的地址的内容。我们将使用URL中该地址的id发送一个PUT请求。在这个例子中,我们将更新我们刚刚创建的地址的city和postalCode部分。我们假设它被保存为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
4.总结
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.
在这篇文章中,我们讨论了HTTP方法PUT和POST在概念上的区别。此外,我们还了解了如何使用Spring Boot框架实现这些方法,以开发RESTful应用程序。
In conclusion, we should use the POST method to create a new resource, and the PUT method to update an existing resource.
总之,我们应该使用POST方法来创建一个新的资源,使用PUT方法来更新一个现有的资源。
As always, the code for this article is available over on GitHub.
一如既往,本文的代码可在GitHub上获得over。