0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

HTTPメソッドの活用とHTTP API 設計2(CollectionとStore)

Last updated at Posted at 2024-10-12

はじめに

こんにちは。
HTTP、その4つ目の記事です。

この記事では、今までの勉強した内容を活用してHTTP APIを実際に設計していきたいと思います。

クライアントからサーバーへのデータ転送方法

以前の記事ではHTTP通信を行うときに、サーバからクライアントへのレスポンスボディーにデータを入れて通信する例について調べました。

この記事では、逆にクライアントからサーバにリクエストを投げるときの例について調べていきます。

データ転送方法

①クエリパラメータ

1つ目はURIを定義するときに、URIの最後にkey-value形式でクエリパラメータを付けて、データを渡す方法です。
この方法は、主にGETメソッドで使われ、並び替え検索時のフィルター機能に使われます。

GET /search?q=hello&hl=jp HTTP/1.1
Host: www.google.com

上記のように、GETメソッドの後ろにクエリパラメータ?q=hello&hl=jp)を付けてサーバーに渡すことができます。
例ではhelloに関する日本語検索結果を参照するためのクエリパラメータです。

もちろん、GETメソッドもBodyにデータを付けて渡すこともできますが、サポートしていないサーバもあるため、推奨されません。

②Message Body

二つ目は、HTTP Message Bodyにデータを入れて渡す方法です。
主に、POST PUT PATCHメソッドで使われます。

POST /members HTTP/1.1
Content-Type: application/json

{
    "username": "young",
    "age": 20
}

上記のようにPOSTメソッドと一緒にBodyにデータを入れてサーバに渡すことで、
新しいリソースを登録するリクエストであることを推測できます。

リクエストの4つのケース

実際に上記の方法を通じて、クライアントからサーバにデータを渡すケースについて説明します。

📌クライアントからサーバへデータを渡す4つのケース

  • 静的データ参照
  • 動的データ参照
  • HTML Form
  • HTTP API

静的データ参照

1つ目は静的データを参照するケースです。

実際に、静的データを参照するときは、サーバにデータを渡す必要はないが、以降のケースの理解を深めるために追加しました。

静的データを参照は、主にイメージ静的テキストなどを求めるケースを意味します。
この時、GETメソッドを使い、静的データはクエリパラメータを使わずにリソースがある場所をURIで指定することで、簡単にリソースを取得することができます。

image.png

上記ではクライアントがクエリパラメータやBodyデータの指定しなくて、/static/start.jpgというリソースの場所を指定しています。
クライアントから受け取ったリクエストをもとにサーバーはイメージをBodyに入れて返してくらます。

この時、レスポンスのBodyの文字列はイメージファイルのバイナリーデータです。

動的データ参照

動的データ参照は、特定の条件や基準によってデータをフィルタリングしたり、並び替えしたりする過程で、ユーザーの入力によって動的に結果が変わる参照方法を言います。

この場合、指定したい条件をクエリパラメータBodyにデータを入れてサーバーに渡します。

image.png

上記のようにクライアントからサーバーへHTTPメッセージを渡すと、サーバーはクエリパラメータをもとに検索結果を作成してそのデータをクライアントに返すことになります。

HTML Form

次はHTML Formformタグを使ってサーバーにデータを渡す例です。

usernameとageにデータを入れて、そのデータをサーバーに渡せるボタンを持つformを作ってみました。

<form action="/save" method="post">
    <input type="text" name="username" />
    <input type="text" name="age" />
    <button type="submit">Submit</button>
</form>

上記のように作成すると、下記のように入力フォームが作成されます。

image.png

formタグのactionmethod属性でURIHTTPメソッドを定義します。
そして、name属性がusernameageのinputタグを作ります。

inputタグにデータを入力し、Submitボタンを押下すると、WEBブラウザがformのデータを読み込んで下記のようにHTTPメッセージを作ってくれます

image.png

formの場合、content-typeはapplication/x-www-form-urlencodedで設定され、メッセージBodyにクエリパラメータと同じkey-value形式でデータが渡されます。
この時keyはinputタグのname属性で設定されます。

✅ formの methodを GETに変更すると?

上記のようにformでもGETメソッドを使用することができます。

<form action="/save" method="get">
    <input type="text" name="username" />
    <input type="text" name="age" />
    <button type="submit">Submit</button>
</form>

この場合、HTTPメッセージは下記のように作成されます。

image.png

GETの場合は、データはクエリパラメータ形式でサーバーに渡されます。

HTML Formは GET, POSTのみサポートされます。

HTTP API

最後はHTTP APIを設計してデータを渡すケースです。

HTTP APIの場合、Androidやiosなどのモバイルアプリケーションや、HTMLが存在しないバックエンドシステム間通信で使用されます。

また、WEBクライアントのAJAXのようにJavaScriptを利用した非同期通信でもhtml formの代わりにHTTP APIが使用されます。

image.png

API通信のGET以外にもPOST PUT PATCHのようなメソッドを使えることができます。

  • GET: 参照、クエリパラメータでデータ転送
  • POST, PUT, PATCH: メッセージBodyでデータ転送

HTTP APIを使ってデータを渡す場合、Content-Typeはapplication/jsonを使います。

HTTP API 設計

HTTP API 設計 - Collection

会員管理システム - POST基盤リソース登録

まず、会員管理システムの5つの機能をHTTP APIで設計する例です。

良い設計をするため、各機能からリソースを把握したうえでURIを設計しなければならないし、そのリソースで行われたい行動によって適切なメソッドを使用して、次のように設計することができます。

✅ 会員リスト参照 /members GET
✅ 会員登録 /members POST
✅ 会員参照 /members/{id} GET
✅ 会員修正 /members/{id} PATCH PUT POST
✅ 会員削除 /members/{id} DELETE

上記の設計で重要な点は次のようです。

  • 各URIは'members' 'members/{id}'のようにリソースを抽出して設計
  • 'members/{id}'のように階層構造で設計
  • 登録POSTメソッドを使用
  • 修正PATCHメソッドを使用

まず、リソース抽出については前の記事で説明をしました。
URI設計で重要な点は各機能からリソースを抽出することです。

よって、会員参照 会員修正 会員削除機能で'会員'リソースとなり、参照 削除のような行為をHTTPメソッドで定義することが理想的な設計方法になります。

会員リスト参照の場合は'/members'で定義し、リストの中の1つの会員については{id}を通じてリソースの位置を指定するように設計をしました。

次は、会員修正PATCHメソッドで定義したところです。

修正の場合、PATCHまたはPUT POSTを使用できます。
しかし、PATCHメソッドを使用した理由は渡したデータに該当するカラムだけ部分的に修正できるメソッドであるためです。

PUTメソッドは既存データを削除したうえで、新しいデータで置き換えるため、部分的に修正したい場合にも、すべてのデータを渡さなければなりません。
もし、エンジニアのミスで一部のデータが抜けてしまうと、そのデータは削除されるため、PATCHメソッドで修正するのが、一番安全な方法といえます。

もちろん、場合によってはPUTメソッドでデータを修正することもできます。

最後に、POSTメソッドを使った会員登録機能について説明します。

会員登録機能はPOSTメソッドを使用するように設計されています。
しかし、URIを核にすると'/members'でリソースの識別子を指定していないことが確認できます。

では、登録される会員のidはどこで指定してくれるのでしょうか?
その答えは、以前の記事で説明下通り、POSTリソースを登録するときはリソースの識別子はサーバーが指定してくれます。

つまり、クライアント新規リソースのURIが分からないため、会員情報が管理されるコレクション(Collection)のURIのみ指定すれば、該当リソースの識別子はサーバーが作成してくれます。

コレクション(Collection)

このように、会員情報が管理されるリポジトリをコレクション(Collection)といいます。

コレクション(Collection)同じ種類のリソースが含まれた集合を意味します。
これを通じて、クライアントは特定種類のリソースリストを参照したり、新しいリソースを追加することができます。

一般的にコレクション(Collection)URIパターンで表現されます。

コレクション(Collection)の役割

  1. リソースの集合を提供
    コレクション(Collection)URIを通じて特定種類のリソースを参照できる
  2. リソース作成
    クライアントはコレクション(Collection)URIにPOSTリクエストを投げて新しいリソースが作成できます。作成されたリソースはサーバーによって唯一のURIを付与され、クライアントはこのURIで新しいリソースにアクセスできるようになります
  3. リソース参照
    個別のリソースはコレクション(Collection)の下位URIで識別されます。このURIで特定の会員情報を参照できます

URI パータン

  • コレクション URI:コレクションを表すURIは一般的に複数形名詞でリソースの集合を表現する
    • 例:/members, /orders, /comments
  • 個別リソース URI:個別リソースのURIコレクションURIにリソース識別子を付けて表現する
    • 例:/products/567 (IDが567の製品), /orders/890 (IDが890の注文)

上記の設計では'/members'が会員のコレクションを表現し、該当URIを通じて会員リストを参照することができます。

また、'/members/{id}'を通じて、個別リソースを参照することができ、コレクションURIにPOSTリクエストを投げて、新しいリソースを作成し、サーバーはそのリソースをlocationsヘッダーに入れてクライアントに渡します。

HTTP API 設計 - Store

ファイル管理システム - PUT基盤リソース登録

コレクションでAPIを設計する場合は、POSTメソッドでリソースを登録しました。
今回はPUTメソッドでリソースを登録するときの、API設計について調べていきます。

ファイル管理システムの5つ機能をHTTP APIで設計する例です。

✅ ファイルリスト参照 /files GET
✅ ファイル参照 /files/{filename} GET
✅ ファイル登録 /files/{filename} PUT
✅ ファイル削除 /files/{filename} DELETE
✅ ファイルBULK登録 /files POST

ファイル管理システムもリソースである'ファイル'をもとにURIを設計しました。

それでは、会員管理システムとの違いは何でしょうか?
最も大きい差は新規リソース登録PUTメソッドで行われることです。

新しいファイルを作成するときを考えてみましょう。
新しいファイルを作成するとき、同じ名前のファイルがあれば、置き換えで作成します。また、同じ名前のファイルがないと、新しいファイルで作成されます。

これは、PUTメソッドの特徴と同じです。
なお、ファイルを登録するときは、すでにファイルも持っている状態なので、クライアント'/files/{filename}'のようにURIを指定することができます。

そうすると、POSTメソッドはほかの機能で使うことが可能となります。

ストア(Store)

上記のようにPUTメソッドで新気リソースを登録するときは、作成されるリソースのURIをクライアント側でURIを指定してくれます。これをストア(Store)といいます。

ストア(Store)クライアント明示的にリソースのURIを指定してサーバーにリクエストを投げることを意味します。
このような方法はリソースの登録とアップデートを明確に処理することができます。

上記の例では、'/files'ストア(Store)となり、リソースを登録する場合にはクライアントからリソースのURIを'/files/{filename}'のように指定しています。

まとめ

📌 コレクション(Collection)

コレクション(Collection)は同じ種類の複数リソースが含まれている集合を意味します。
コレクション(Collection)を通じてクライアントは特定種類のリソースリストを参照したり、新しいリソースを登録します。一般的にコレクション(Collection)はURIパターンで表現します。

サーバーでリソースのURIを作成する(POSTでリソース登録)

📌 ストア(Store)

ストア(Store)はクライアントが明示的にリソースのURIを指定して、サーバーにリクエストを投げる方法を意味します。
この方法は、リソースの登録とアップデートを明確に処理することができます。

クライアントがリソースのURIを作成する(PUTでリソース登録)

HTML Form 設計

最後にHTML Formについて説明します。

HTML Formの場合、GETPOSTメソッドのみ使用できます。
もちろん、AJAXのように技術を使うと、他のメソッドも使用できますが、この記事ではHTML Formのみ説明します。

それでは、GETPOSTメソッドだけなのに、修正削除のような機能はどのように実装することができますでしょうか?

その答えは、POSTメソッドにあります。

次は、GETPOSTメソッドを使用してAPIを設計した例です。

✅ 会員理卒参照 /members GET
✅ 会員登録フォーム /members/new GET
✅ 会員登録 /members/new, /members POST
✅ 会員参照 /members/{id} GET
✅ 会員修正フォーム /members/{id}/edit GET
✅ 会員修正 /members/{id}, /members/{id}/edit POST
✅ 会員削除 /members/{id}/delete post

前の例に比べると、多少複雑ですがGETPOSTメソッドでAPIを設計しました。

まず、GETメソッドを使用した機能から確認してみましょう。

会員リスト参照会員登録フォーム 会員参照 会員修正フォームはデータやフォーム画面を要求する作業なので、GETメソッドでAPIを設計しました。

次は、POSTメソッドを使用した機能です。

会員登録 修正 削除の機能はPOSTメソッドで設計され、各機能を分けるために、URIに/new /edit /deleteを追加しました。

このようにメソッド使用に制約があったり、あいまいなケースPOSTメソッドを使って機能の実装ができます。

コントロール URI (Control URI)

しかし、ここで疑問がわくと思います。

確かに、URIを設計*するときは、リソースだけを抽出してAPIを設計し、遂行する行為についてはHTTPメソッドで表現と説明しましたが、HTML formを使った例では/new /edit /delete のように行為がURIに含まれていることが分かります。

HTML formのように、API設計するにある制約がある場合は、これを解決するために、動詞のリソースを使って設計されたURIコントロール URI (Control URI)といいます。

実際に、実務では色んな状況での制約事項が存在するため、このようなコントロール URI (Control URI)をよく使うらしいです。
これはHTTP APIを設計するときも同じです。

しかし、できる限り、`APIを設計``するときはリソースだけを使ってURIを設計知ることを推奨します。
リソースだけではURIが設計できない場合のみコントロール URI (Control URI)を使うことにしましょう。

良いAPI設計するための例

最後に、良いAPIを設計するための、色んな例があるので、
下記のページを参照してください。

参考サイト

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?