1. 概要

このチュートリアルでは、RESTアーキテクチャ内で頻繁に使用される2つの重要なHTTPメソッド(PUTとPOST)について簡単に説明します。 開発者がRESTfulWebサービスを設計する際に、これら2つの方法のどちらかを選択するのに苦労することがあることは周知の事実です。 したがって、Spring BootのRESTfulアプリケーションの簡単な実装でこの問題に対処します。

2. PUTとPOSTのジレンマ

典型的なRESTアーキテクチャでは、クライアントはHTTPメソッドの形式でサーバーにリクエストを送信し、リソースを作成、取得、変更、または破棄します。 PUTとPOSTの両方を使用してリソースを作成できますが、目的のアプリケーションに関しては、それらの間に大きな違いがあります。

RFC 2616 標準によれば、POSTメソッドを使用して、Request-URIで識別される既存のリソースの従属として囲まれたエンティティを受け入れるようにサーバーに要求する必要があります。 これは、 POSTメソッド呼び出しが、リソースのコレクションの下に子リソースを作成することを意味します。

一方、PUTメソッドを使用して、提供されたRequest-URIの下に囲まれたエンティティを格納するようにサーバーに要求する必要があります。 Request-URIがサーバー上の既存のリソースを指している場合、提供されたエンティティは既存のリソースの変更されたバージョンと見なされます。 したがって、 PUTメソッド呼び出しは、新しいリソースを作成するか、既存のリソースを更新します

メソッド間のもう1つの重要な違いは、 PUTはべき等メソッドであり、POSTはではないことです。 たとえば、PUTメソッドを複数回呼び出すと、同じリソースが作成または更新されます。 逆に、POSTリクエストが複数あると、同じリソースが複数回作成されます。

3. サンプルアプリケーション

PUTとPOSTの違いを示すために、Spring Bootを使用して単純なRESTfulWebアプリケーションを作成します。 アプリケーションは、人々の名前と住所を保存します。

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. ドメインエンティティとリポジトリインターフェイス

まず、ドメインオブジェクトを作成することから始めましょう。 アドレス帳については、個人の住所情報を格納するために使用するAddressというEntityクラスを定義しましょう。 わかりやすくするために、 Address エンティティには、 name city postalCodeの3つのフィールドを使用します。 :

@Entity
public class Address {

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

    // constructors, getters, and setters
}

次のステップは、データベースのデータにアクセスすることです。 簡単にするために、 SpringDataJPAの JpaRepository。 これにより、追加のコードを記述せずに、データに対してCRUD機能を実行できるようになります。

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

3.3. RESTコントローラー

最後に、アプリケーションのAPIエンドポイントを定義する必要があります。 クライアントからのHTTPリクエストを消費し、適切な応答を返すRestControllerを作成します。

ここでは、新しいアドレスを作成するための@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

それでは、作成したアドレスの内容を更新しましょう。 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. 結論

このチュートリアルでは、HTTPメソッドPUTとPOSTの概念的な違いについて学びました。 さらに、RESTfulアプリケーションを開発するためのSpringBootフレームワークを使用してメソッドを実装する方法も学びました。

結論として、POSTメソッドを使用して新しいリソースを作成し、PUTメソッドを使用して既存のリソースを更新する必要があります。 いつものように、このチュートリアルのコードはGitHubから入手できます。