WebAPIのRESTについてまとめる

# はじめに
### この記事について
この記事は[Webを支える技術](https://www.amazon.co.jp/Web%E3%82%92%E6%94%AF%E3%81%88%E3%82%8B%E6%8A%80%E8%A1%93-HTTP%EF%BC%8CURI%EF%BC%8CHTML%EF%BC%8C%E3%81%9D%E3%81%97%E3%81%A6REST-WEB-PRESS-plus-ebook/dp/B07JK7FZH2/ref=sr_1_1?adgrpid=52846719243&gclid=Cj0KCQjwxveXBhDDARIsAI0Q0x3q0IUHer_JfCyvGPed0xAk_iSNQ2jSg5wTZKzwBuksLlfpKn2nPjUaAmE3EALw_wcB&hvadid=553902346777&hvdev=c&hvlocphy=1009049&hvnetw=g&hvqmt=e&hvrand=13432912492664187203&hvtargid=kwd-333749887651&hydadcr=16039_13486741&jp-ad-ap=0&keywords=web%E3%82%92%E6%94%AF%E3%81%88%E3%82%8B%E6%8A%80%E8%A1%93&qid=1660817484&sr=8-1)
などの参考文献からWebの仕組みや設計について勉強した際のまとめである。

ポートフォリを作成するにあたって,せっかくなら自分が使いたくなるようなWebサービスを作りたいと思い,色々アイディアを練っていたのだが,それらをいざ作ろうと思うとあまりにもいろんな実装方法があり過ぎて何をどのように設計するのが好ましいのかわからなかった。

WebAPIの設計について色々調べていくと**REST**という概念について出会った。
この記事にはその概念を調べ上げた結果得られた知識の再整理を行う。
とはいえ、Web系は初心者なため**間違っているところがたくさんあるかも知れません。そこは注意してください。**

まだ書き途中のまま投稿するため、もしかしたら随時更新するかもしれないし、やらないかもしれない。


### この記事の目的

- Webとは何かについて知る.
- アーキテクチャスタイルのRESTとは何かについて理解する
- URIを設計する上で気を付けるべきことを知る.
- WebAPIの設計におけるベスト・バットプラクティスを知る

### 想定している読者
当時の自分は次のようなタイプだったので似たような人の助けになればと思う。

- なんらかの言語でコードを書くことができる.
- TCP/IPの知識はぼんやりと記憶にあるが,Webの仕組みについては疎い
- とりあえず動くアプリなら作れるけど, WebAPIとして何が良い・悪い設計なのかについて理解していない

ただし,自分なりの視点や疑問点を中心に記事を進めるので読みにくいところがあるかもしれません。そこはご了承ください。
また,サンプルコードとしてはJavaScriptかPython3を用いるのでそれらの言語が読めるとなお良いかもしれません。

### この記事で書かないこと

- インターネットやWebの詳しい歴史
- HTTPやURIの詳しい仕様
- ネットワークのコンポーネントに関する説明
- 通信の暗号化の方法などセキュリティに関する詳しい知識
- HTMLなどといった特定の言語の文法
- ハンズオン的なWebサービスの開発手法


ではさっそく本題に入る。

# 本題

## Webとは何か。
生まれた年代やコンピュータを本格的に触り始めた時期に依存するかもしれないが,10代から20代の一般的な消費者はネットといえば恐らくGoogle検索を使ったネットサーフィンを真っ先に思い浮かべると思う(自分はそうだった)。ましてや現代においてはWebという単語自体、日常でも頻繁に利用されるくらいに当たり前なものになってしまっている。それ故に通信の仕組みについて勉強するまでは「Web」の本来の意味を知らず「Web≒インターネット」という勝手な解釈をとっていたところがある。
まずはこれらの誤解を解消する目的でWebとは何かをざっくりと説明する。

### Webを構成するシステム
Webには技術的には二つの側面がある。
- **ハイパーメディア**
テキストや動画,写真,文書など(以降は総称してメディアという)をハイパーリンクによって相互に結びつけて得られたシステムのこと。HTMLやXMLなどがハイパーメディアに当たる。
- **分散システム**
メディアやデータを一つのコンピュータで管理したり処理するのではなく,ネットワーク上に分散された複数のコンピュータが管理・処理するシステムのこと

ハイパーメディアや分散システムの構想はWebが登場する前からもあったが,Webはそれをインターネット上で実現したのが以前の他のシステムと異なる部分である。

Webとは結局のところネットワークを利用したシステムの一つの形態に過ぎない。

### Webの簡単な歴史
すでにお気づきかもしれないが,Webが誕生する以前は時系列にすると
ハイパーメディアや分散システムの構想 $\longrightarrow$ インターネットの登場$\longrightarrow$ Webの誕生
という順を辿っている。詳しい歴史については割愛するが,Webが登場する前のインターネットには他の分散システムも存在してはいた(例えば分散オブジェクトなど)。だが,結果的にWebがあまりにも急速にインターネットを全体に広がった。
「Web≒インターネット」という勝手に解釈してしまっていた原因は,今の若者が物心着いてパソコンを触る頃にはすでにWebが普及していたからであろう。

なぜWebがここまで普及できたのかの詳しい説明に関しては参考文献を参照のこと。

### Webの通信プロトコル
ハイパーメディアや分散システム以外にもWebが通信をする際に利用する技術がある。
- **HTTP**
ハイパーテキストトランスポートプロトコルの略。TCP/IPにおけるアプリケーション層に位置するプロトコルでWebサービス(サーバー)と利用者のデバイス（クライアント）が通信する際に利用される。クライアントが**HTTPリクエスト**をサーバーに送信し,サーバーがそれを受け取ると適切な**HTTPレスポンス**をクライアントに返却する。
- **URI**
Uniform Resource Identifierの略。ネットワーク上のリソース(ここではデータのことだと考えれば良い)がどこにあるのかを一意的に識別するための文字列。HTTPで通信する際に**HTTPメソッド**と共にHTTPリクエストの初めの１行(**リクエストライン**)で必ず指定する必要がある。URLなら聞いたことある人は多いだろうが,それとほぼ同じだと考えて問題ない。

サーバー側がHTTPリクエストを受け取ると、指定されたURIに一致するリソースに対して,指定されたHTTPメソッドを適用することを試みる。そしてその結果をHTTPレスポンスとしてクライアントに返却する。

ざっくりとまとめると,Webはインターネット上にあるハイパーメディアをHTTPでつなげる分散システムといえる。

### さまざまなWebサービス
Webが使われているサービスには以下のようなものがある.

- Webサイト
- Webアプリケーション
人間がWebを通じて利用することを想定したアプリケーション。デスクトップのアプリとは違い,ChromeやSafariなどのWebブラウザさえあればどの端末でも利用可能。TwitterやYoutube,Amazonなどを想像するのが一番わかりやすいと思う。

- **WebAPI**
HTTP通信で呼び出すことができるプログラムや関数,あるいはその仕様のことを指す。自分でなにかプログラムや関数を組む場合,どのような入力値に対してどのような結果を返すのかといった仕様を決める必要がある.その仕様を**API**と呼んだりするのだが,実際にそのプログラムを実行する上では,そのAPIとプログラムはほぼ同じものであるといえる。このような意味でプログラム自体もまたAPIと呼ぶこともある。WebAPIはAPIのWeb版である。リクエスト内のURIで呼び出されたWebAPIは,そのリクエスト内のパラメータとメソッドに応じた返り値をレスポンスボディとして格納し,そのレスポンスをクライアントに返却する。この説明がわかりにくい方は下のWebAPIの例を見て欲しい。なお,Webアプリがクライアントとして人間を想定しているのとは対照的に,WebAPIはクライアントとしてはプログラムを想定している。したがってWebAPIが返すレスポンスボディは,JSON型のようにあらゆるプログラムでも利用しやすいデータ型になっていることが多い。いくつかのWebAPIを組み合わせて,HTML&CSSやJavaSctiptなどで見た目や動きをつけたものがWebアプリだと思えばいいだろう。

以降はこれらを総称してWebサービスと呼ぶことにする。


### WebAPIの例

**利用するとき**
WebAPIの例として郵便番号検索を提供する[ZipCloud](http://zipcloud.ibsnet.co.jp/doc/api)がある.ここではそれをPythonを使って利用する例を提示する。なおPythonでHTTP通信を行うライブラリとして[Requests](https://requests.readthedocs.io/en/latest/)を使用している。
ZipCloudのWebAPIをPythonから使う場合は次のようにすれば良い。
```{python}
import requests

response = requests.get("https://zipcloud.ibsnet.co.jp/api/search?zipcode=7830060")

```
たったこれだけでWebAPIへのHTTPリクエストの送信とレスポンスの受信が完了する。`request.get(uri)`でuriに指定されたリソース(WebAPI)に対してGETメソッドのHTTPリクエストを行い,それに対するWebAPIからのレスポンスを`response`に格納している。なおuriの https://zipcloud.ibsnet.co.jp/api/search までが郵便番号検索APIのURIである。試しにこのURIをクリックしてみると
```
{
	"message": "必須パラメータが指定されていません。",
	"results": null,
	"status": 400
}
```
と表示されると思う。必須パラメータとはZipCloudの場合は`zipcode`として指定されている。`uri`の`search`の後ろに`?zipcode=7830060`と指定すると,そのリクエストを受け取ったWebAPIは郵便番号が783-0060である住所のJSONデータをレスポンスボディとしたHTTPレスポンスを作成し,クライアントに送信する。試しに https://zipcloud.ibsnet.co.jp/api/search?zipcode=7830060 をクリックするとブラウザ上に次のように表示されると思う。
```
{
	"message": null,
	"results": [
		{
			"address1": "高知県",
			"address2": "南国市",
			"address3": "蛍が丘",
			"kana1": "ｺｳﾁｹﾝ",
			"kana2": "ﾅﾝｺｸｼ",
			"kana3": "ﾎﾀﾙｶﾞｵｶ",
			"prefcode": "39",
			"zipcode": "7830060"
		}
	],
	"status": 200
}
```
ブラウザで単純にクリックして表示する場合だと見た目があまりにも簡素であることがわかると思う。これは先ほど説明したようにWebAPIはプログラムが利用することを想定しているからである。郵便番号で検索して得られた住所のデータをPythonの他のプログラムで利用する場合は,先ほどのコードを実行した後
```
address = response.json()["results"][0]
```
などとすれば良い。こうして得られたaddressは
```
>>type(address)
<class 'dict'>
>>print(address)
{'address1': '高知県', 'address2': '南国市', 'address3': '蛍が丘', 'kana1': 'ｺｳﾁｹﾝ', 'kana2': 'ﾅﾝｺｸｼ', 'kana3': 'ﾎﾀﾙｶﾞｵｶ', 'prefcode': '39', 'zipcode': '7830060'}

```
のようにPythonのdictとして扱える。ここまでのPythonのコードを見てみると,WebAPIと通信するのにHTTPを利用しているというだけで通常の関数を呼び出す場合とそこまで変わらないことがわかると思う。

**作るとき**
PythonでWebAPIを作れるライブラリやフレームワークとしてはDjango REST framework,Flask, FastAPIがある。
コードの詳細は略すが,例えばFlaskで```http://ドメイン名/hello``` にアクセスしたとき`{"message": "hello world"}`というJSONを返すWebAPIを作成する場合は次のようなソースコードになる(サーバーをホストする方法とかはここでは省く)。
```
from flask import Flask

app = Flask(__name__)

@app.route("/hello", methods=["GET"])
def hello_world():
    return {
        "message": "hello world"
    }
```
なお`@app.route("/hello", methods=["GET"])`はデコレータとよばれるもので,`app.route("/hello", methods=["GET"])`は関数を引数にとる関数で返り値もまた関数になるのだが(ややこしい),次の二つのコードの結果はいずれも同じになる。
```
hello_world()
app.route("/hello", methods=["GET"])(hello_world)()
```
ここでは,FlaskによるWebAPI実際の挙動としてはユーザーが```http://ドメイン名/hello```にアクセスしたことをトリガーにして`hello_world`が実行される程度に考えておけばよい。

WebAPIの実装方法は言語やフレームワークなどによってさまざまだが,イメージしにくい場合は「結局のところWebAPIはリモートの関数みたいなもの(callable object)やプログラムのことだが,それらを実行するための引数を与えたり,その返り値を受信するためにHTTPを利用している」のだと考えれば良い。実際WebAPIは上記のようにJavaやRuby,Python,Go,PHPなどといったプログラム言語で書かれている。

どの言語でWebAPIを作るのかは作るサービスに依存するが,設計をする際に共通して守る必要のある設計方針がある。次のセクションではこれについて述べる。


## REST
実際に上記の仕組みで自分のWebサービスを作ろうと思うと,どのように設計するのかの方針が要になってくる。そこで登場するのが**REST**と呼ばれるアーキテクチャスタイルである。
### Webのアーキテクチャスタイル
Webシステムを設計する上での指針や流儀(**アーキテクチャスタイル**)としては色々なものが生まれたが、結果として**REST**と呼ばれるアーキテクチャスタイルが最も広く普及した。

<!--
iPhoneを例にとる。仮にあなたがApple社でiPhoneの開発を担当していたとしよう。iPhoneを作ろうとしたときに,あなたは守らなければならないことがある。それはiPhoneは携帯電話でなければならないということである。あなたは勝手にiPhoneという名前でMacBookのようなラップトップを作ってはならないし,iPhoneという名前でAirPodsのようなイヤフォンを作ってはならない。iPhoneは携帯電話であるからこそiPhoneなのである。では携帯電話であればなんでもいいかというとそうではない。iPhoneは携帯電話の中でも特にスマートフォンであるのだから。関係性としては
という包含関係が成り立つ。アーキテクチャスタイルの話に戻すと,この場合スマートフォンはiPhoneの"アーキテクチャ"であり,携帯電話はiPhoneの"アーキテクチャスタイル"である。注意点として,アーキテクチャとアーキテクチャスタイルは別物であるということ。アーキテクチャを設計する際の流儀のようなものがアーキテクチャスタイルである
-->

何故このRESTが最も普及したのかや他にどんなものがあったのかなどについて知りたい場合は実際に[Webを支える技術](https://www.amazon.co.jp/Web%E3%82%92%E6%94%AF%E3%81%88%E3%82%8B%E6%8A%80%E8%A1%93-HTTP%EF%BC%8CURI%EF%BC%8CHTML%EF%BC%8C%E3%81%9D%E3%81%97%E3%81%A6REST-WEB-PRESS-plus-ebook/dp/B07JK7FZH2/ref=sr_1_1?adgrpid=52846719243&gclid=Cj0KCQjwxveXBhDDARIsAI0Q0x3q0IUHer_JfCyvGPed0xAk_iSNQ2jSg5wTZKzwBuksLlfpKn2nPjUaAmE3EALw_wcB&hvadid=553902346777&hvdev=c&hvlocphy=1009049&hvnetw=g&hvqmt=e&hvrand=13432912492664187203&hvtargid=kwd-333749887651&hydadcr=16039_13486741&jp-ad-ap=0&keywords=web%E3%82%92%E6%94%AF%E3%81%88%E3%82%8B%E6%8A%80%E8%A1%93&qid=1660817484&sr=8-1)を手にとって読んで欲しい。

### RESTの詳細
RESTはアーキテクチャスタイルの一つだと述べたが、実はRESTは6つのアーキテクチャスタイルから構成されるものである.

- **クライアント/サーバー**
HTTPやURIのところで述べたが,リクエストを送信するクライアントと,リクエストを受け取りレスポンスを返すサーバーで処理が完全に分担されている。したがっていろいろなデバイスからもアクセスが可能であり,サーバー側はクライアントにデータを提供する機能を備えるだけで良い。

- **ステートレス[^2]サーバ**
サーバー側がクライアントのアプリケーションの状態を保存しないことを指す。アプリケーションの状態はサーバーから送られてきたハイパーメディア内のリンクをクリックすることによって遷移する。したがってそれをサーバーが保存しないということは,クライアントが同一アプリケーション内でたどったリンクの履歴をサーバー側が記憶しないということになる。これによってサーバー間でのクライアントに関するデータの同期が不要になり,実装が単純になる。ただしログインすることで利用することができるWebサービス(Twitterなど)はユーザのログイン状態をCookieやセッションなどを利用して[^3]サーバー側が保存する必要がある。このような場合はステートレス性を諦めざるを得ない。

[^2]: 対義語としてステートフルという言葉がある。<!-- 
例えば,あなたがステートフルなカフェにいったとすると店員はあなたがたった今来たばかりなのか,入店して商品を注文をしたばかりなのか,支払いを終えたのか否かなど,あなたが店内で行った手続きを記憶しているだろう。このように我々が日頃よく利用しているカフェはステートフルである。一方でステートレスなカフェはどうなるか。店員はあなたが入店を済ませた客なのかも,支払いを終えた客なのかも全く記憶していない。だからあなたがまるで支払いを済ませた客のように店員の前で堂々と店を後にすると,店側は正しく支払いが完了したものだと判断してしまう。なんてこった!!!!このように,実装するアプリケーションによってはステートレスよりステートフルな場合が良いこともある。
-->

[^3]: Cookieやセッションに関する説明は [こちらのサイト](https://blog.takanabe.tokyo/2014/12/%E3%82%BB%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3%E7%AE%A1%E7%90%86%E3%81%AE%E5%91%A8%E8%BE%BA%E7%9F%A5%E8%AD%98%E3%81%BE%E3%81%A8%E3%82%81/) や書籍[『プロになるためのWeb技術入門』――なぜ，あなたはWebシステムを開発できないのか](https://www.amazon.co.jp/%E3%80%8E%E3%83%97%E3%83%AD%E3%81%AB%E3%81%AA%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AEWeb%E6%8A%80%E8%A1%93%E5%85%A5%E9%96%80%E3%80%8F%E2%80%95%E2%80%95%E3%81%AA%E3%81%9C%EF%BC%8C%E3%81%82%E3%81%AA%E3%81%9F%E3%81%AFWeb%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%92%E9%96%8B%E7%99%BA%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84%E3%81%AE%E3%81%8B-%E5%B0%8F%E6%A3%AE-%E8%A3%95%E4%BB%8B-ebook/dp/B09MVGM99L/ref=sr_1_1?crid=3ND25XN32WB9M&keywords=%E3%83%97%E3%83%AD%E3%81%AB%E3%81%AA%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AEweb%E6%8A%80%E8%A1%93%E5%85%A5%E9%96%80&qid=1661091665&sprefix=%E3%83%97%E3%83%AD%E3%81%AB%E3%81%AA%E3%82%8B%2Caps%2C209&sr=8-1)などを参考にしてほしい。

- **キャッシュ**
サーバーから取得したデータをクライアント側のローカルストレージに一時的に格納し,再利用する仕組みのこと。キャッシュによって保存されたデータもキャッシュと呼ばれる。キャッシュによってネットワークの通信の負荷を下げることができる。デメリットとしてはキャッシュの鮮度が低下し,情報の信頼性が低下することである。

- **統一インターフェース**
限定的なインタフェースを用いて,URIで指定したリソースへの操作を行うこと。現在のHTTPではGET,HEAD,POST,PUT,DELETEなどを含む9つのメソッドのみが定義されている[^1]。インタフェースが統一されることにより,サーバーとクライアントの実装における独立性が向上する。
[^1]: こちらを参照https://developer.mozilla.org/ja/docs/Web/HTTP/Methods

- **階層化システム**
負荷分散やアクセス制限をする目的でロードバランサやプロキシなどのネットワークコンポーネントをサーバーの前に置いたりなどするように,システムをいくつかの階層に分離すること。

- **コードオンデマンド**
プログラムコードをサーバーからダウンロードし,クライアント側で実行できる仕組みのこと。HTMLのscriptタグ内で指定するJavaScriptコードなどが該当する。クライアントのアプリケーションを拡張することができるのがメリット。

RESTの制約は守るのが好ましいが絶対ではなく,いくつかを除外しても構わない。

## URIの設計

### URIの仕様
細かな仕様の説明についてはいろいろな文献があるのでそちらに譲る。ここではURIを構成する用語について簡単に解説する。
```
https://example.com/hoge/path_param?qery=param
```
上記のURIに対して,それぞれ
- URIスキーム: https
- ホスト名: example.jp
- パス: hoge/path_param
- クエリパラメータ: query=param
という呼び名がある。

URIで使用できる文字としてはASCII文字(大文字小文字のアルファベット,数字,記号-.~:@!$&'() )
ASCII文字以外の文字,例えば日本語をURIに含める場合は%エンコーディングが必要になる。

### Cool URI
変わりにくいURIのことをCool URIというが,ここではそれを実現するためのポイントを説明する。

- **実装や言語に依存した文字列を含めない**
たとえば```https://example.com/Flaskapp/login.py``` のようにメソッド名や言語の拡張子,使用しているライブラリ名などをURIに含めると,実装の仕方を変えたりリファクタリングしたりしたときにURIをその都度変えなければならない。

- **アクセスごとに変化する値を含めない**
例えば```https://example.com/home?sessionid=10024``` のようにセッションIDをURIに含めると,ログインしなおしたりしたときにはURIは変更になってしまう。

- **リソースを表現する適切な名詞にする**
例えば```https://example.com/home/tweet/112/update``` のようなURIで```https://example.com/home/tweet/112```のリソースを更新する処理を実装すると,HTTPメソッド以外のメソッドを適用したように見える。URIはあくまでリソースを特定するだけのものであるから,メソッドはURIではなくHTTPメソッドで指定するのがRESTが要請する統一インタフェースを実現する意味でも好ましい。

- **マトリクスURIを使う**
例えばGoogleマップのような地図アプリで使用する緯度と経度のように,階層構造では表現できないものはマトリクスURIをしようするとよい。
```http://example.com/map/lat=35.740;lng=139.751```

- **URIの不透明性を意識する**
クライアントアプリケーション側がURIを勝手に組み立てたり,推測できたりしないようなURIを不透明であるという.例えば```https://example.com/home.jp```で日本語のページを,```https://example.com/home.en```で英語のページを表示できたとすると,```https://example.com/home.fr```のページも推測可能であるが,そのページが存在するとは限らない。また,クライアント側のアプリケーションでURIを組み立てるプログラムが実装されているとすると,サーバー側がURIの構造を変更したときにシステムが動かなくなり修正作業も多くなる密結合状態になってしまう。
<!-- たとえばクライアント側のアプリケーションの言語設定が内部のプログラムでは```lang```という変数で管理されているとして,アプリ内からホームページを表示するときに
```
const home_url = `https://example.com/home.${lang}`
```
と組み立ててから```home_url```でアクセスするような仕様になっていたとする。それまでは何の問題もなくても後になってサーバー側が,対象のリソースを```https://example.com/home/jp```で管理するようにしたとたん,アプリケーション側のURIが無効になってしまうため,サーバー側だけでなくクライアント側の修正作業も必要になる。()
-->


# 参考文献
- 書籍
[Webを支える技術](https://www.amazon.co.jp/Web%E3%82%92%E6%94%AF%E3%81%88%E3%82%8B%E6%8A%80%E8%A1%93-HTTP%EF%BC%8CURI%EF%BC%8CHTML%EF%BC%8C%E3%81%9D%E3%81%97%E3%81%A6REST-WEB-PRESS-plus-ebook/dp/B07JK7FZH2/ref=sr_1_1?adgrpid=52846719243&gclid=Cj0KCQjwxveXBhDDARIsAI0Q0x3q0IUHer_JfCyvGPed0xAk_iSNQ2jSg5wTZKzwBuksLlfpKn2nPjUaAmE3EALw_wcB&hvadid=553902346777&hvdev=c&hvlocphy=1009049&hvnetw=g&hvqmt=e&hvrand=13432912492664187203&hvtargid=kwd-333749887651&hydadcr=16039_13486741&jp-ad-ap=0&keywords=web%E3%82%92%E6%94%AF%E3%81%88%E3%82%8B%E6%8A%80%E8%A1%93&qid=1660817484&sr=8-1)
[『プロになるためのWeb技術入門』――なぜ，あなたはWebシステムを開発できないのか](https://www.amazon.co.jp/%E3%80%8E%E3%83%97%E3%83%AD%E3%81%AB%E3%81%AA%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AEWeb%E6%8A%80%E8%A1%93%E5%85%A5%E9%96%80%E3%80%8F%E2%80%95%E2%80%95%E3%81%AA%E3%81%9C%EF%BC%8C%E3%81%82%E3%81%AA%E3%81%9F%E3%81%AFWeb%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%92%E9%96%8B%E7%99%BA%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84%E3%81%AE%E3%81%8B-%E5%B0%8F%E6%A3%AE-%E8%A3%95%E4%BB%8B-ebook/dp/B09MVGM99L/ref=sr_1_1?crid=3ND25XN32WB9M&keywords=%E3%83%97%E3%83%AD%E3%81%AB%E3%81%AA%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AEweb%E6%8A%80%E8%A1%93%E5%85%A5%E9%96%80&qid=1661091665&sprefix=%E3%83%97%E3%83%AD%E3%81%AB%E3%81%AA%E3%82%8B%2Caps%2C209&sr=8-1)

- Qita
[[RESTful API]パスパラメータ、クエリパラメータ、リクエストボディの違いと設計](https://qiita.com/Shokorep/items/b7697a146cbb1c3e9f0b#%E3%82%AF%E3%82%A8%E3%83%AA%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF)
[ステートレスとは](https://qiita.com/mtakehara21/items/efcbbc3ba58a62c10eb6)

- その他Webサイト
https://thinkit.co.jp/free/article/0609/8/4
https://developer.mozilla.org/ja/docs/Web/HTTP/Methods
[セッション管理の周辺知識まとめ](https://blog.takanabe.tokyo/2014/12/%E3%82%BB%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3%E7%AE%A1%E7%90%86%E3%81%AE%E5%91%A8%E8%BE%BA%E7%9F%A5%E8%AD%98%E3%81%BE%E3%81%A8%E3%82%81/)