REST API 中 HTTP PUT 與 POST 的區別

REST,Spring Boot
Remote
0
06:45 AM · Dec 01 ,2025

1. 概述

在本教程中,我們將研究兩個重要的 HTTP 方法,PUT 和 POST,這些方法在 REST 架構中被我們頻繁使用。毫無疑問,開發人員在設計 RESTful Web 服務時,有時會為選擇這兩種方法而苦惱。因此,我們將通過在 Spring Boot 中實現一個簡單的 RESTful 應用程序來解決這個問題。

2. PUT 與 POST 的困境

在典型的 REST 架構中,客户端通過 HTTP 方法向服務器發送請求,以創建、檢索、修改或刪除資源。雖然我們可以使用 PUT 和 POST 兩種方法來創建資源,但它們在用途上存在顯著差異。

根據 RFC 2616 標準,POST 方法應用於請求將包含的實體作為現有資源的子級接受。這意味着 POST 方法調用將創建一個子資源,位於資源集合下。

相反,PUT 方法應用於請求將包含的實體存儲在提供的 Request-URI 下。如果 Request-URI 指向服務器上的現有資源,則提供的實體將被視為現有資源的修改版本。因此,PUT 方法調用將要麼創建一個新資源,要麼更新一個現有資源

另一個重要的區別是,PUT 是一種冪等方法,而 POST 不是。例如,多次調用 PUT 方法將要麼創建一個新資源,要麼更新同一個資源。相反,多次 POST 請求將導致同一個資源被創建多次。

3. 樣本應用程序

為了演示 PUT 和 POST 之間的區別,我們將使用 Spring Boot 創建一個簡單的 RESTful Web 應用程序。該應用程序將存儲人們的姓名和地址。

3.1. Maven 依賴項

首先,我們需要包含 Spring Web、Spring Data JPA 和內存 H2 數據庫的依賴項,添加到我們的 pom.xml 文件中:


<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. 域實體和存儲接口

我們首先創建一個域對象。對於地址簿,我們將定義一個 EntityAddress,用於存儲個人的地址信息。為了簡化,我們將使用三個字段,namecitypostalCode,用於我們的 Address 實體:


@Entity
public class Address {

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

    // constructors, getters, and setters
}

下一步是訪問數據庫中的數據。為了簡化,我們將使用 Spring Data JPA 的 JpaRepository。這將允許我們執行 CRUD 功能,而無需編寫任何額外的代碼:


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

3.3. REST 控制器

最後,我們需要定義應用程序的 API 端點。我們將創建一個 RestController,該控制器將從客户端消耗 HTTP 請求並返回適當的響應。

在這裏,我們將 定義一個 @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 請求

現在我們可以使用 cURL 發送樣本 HTTP 請求來測試我們的應用程序。

要創建新地址,我們將數據放在 JSON 格式中,並通過 POST 請求發送:

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

現在讓我們更新我們創建的地址的內容。我們將通過 PUT 請求使用地址的 id 在 URL 中,在此示例中,我們將更新地址的 citypostalCode 部分。我們假設它已保存為 id=1:

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

4. 結論

在本文中,我們討論了 HTTP 方法 PUT 和 POST 的概念差異。此外,我們還學習瞭如何使用 Spring Boot 框架開發 RESTful 應用程序,並利用這些方法實現。

總之,我們應該使用 POST 方法創建新的資源,使用 PUT 方法更新現有資源。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.