【入門】Web APIでの基礎知識

勉強用と忘れないようにメモ:writing_hand:

#１．Web APIをなぜ学ぶのか
* マイクロサービスの流行
* 便利なSaaSが増え、API開発が主流のため
* フロントエンドの役割が広がった（フロントエンドでも実装する機会がある）、jaｍ（JAVASCRIPT、API、マークダウン）での開発が多いため

#２．webの用途
* webサイト　情報の閲覧をする（企業のコーポレートサイト）
* webアプリケーション　投稿、検索、編集機能など機能が搭載されているユーザーとの対話型のこと（ツイッターやYOUTUBE） 
* ユーザーインターフェースとしてのweb 商品などの説明書や設定画面
* web API　プログラムが使うためのweb（データの送受信や編集などをプログラムを使って通信する）

#３．webを支える技術
* HTTP ：通信のためのルール（プロトコル）
* URI ：リソースを識別するID　（URIの中にURLが含まれているイメージ）
* HTML　：webで表示するための文書フォーマット

#４.集中システムと分散システム
* 集中システム　メインフレームのこと　１つのでっかいサーバーに対して処理を一挙におこないシステムを動かすこと　１９８０年まで主流だった
* 分散システム　Webのこと　複数のコンピュータが相互に処理をして１つのシステムを作っていくこと

#５.RESTとは
**RESTとはアーキテクチャスタイル（設計、思想、作法）のこと**
アーキテクチャスタイルは　REST
アーキテクチャは　      サーバー、ブラウザ、etc
実装は　             Apache、Chrome、etc なイメージ

リソースもRESTの一部。
webにおけるリソースとはweb上に存在する名前を持ったあらゆる情報（URIもリソースの一部）

**RESTを構成する６つのアーキテクチャスタイル（ルールみたいなもの）**
1.クライアント・サーバー　:UIと処理を分離する
2.ステートレスサーバー　:クライアント状態をサーバーが管理しない
3.キャッシュ :サーバーから取得したリソースの再利用。クライアントにキャッシュ情報は保存されている。情報の鮮度は失われる
4.統一インターフェース　:操作可能なインターフェースを制限（get,put,deleteとメソッドを制限）
5.階層化システム　:システムを階層に分離
6.コードオンデマンド　: クライアントでDL&実行（JAVASCRIPTのように必要なときにダウンロードして実行すること）

**通信の流れ**
クライアント　⇔　プロキシサーバー　⇔　ステートレスサーバー　
クライアント（プログラムをDL）　⇔　ステートレスサーバー　⇔　DB　

#６.URI
* URIスキーム :通信プロトコルを指す（http or httpsがほとんど）
* ユーザー情報　:＜username＞:＜password＞形式
* ホスト名 :DNSで名前解決できるドメイン名　or IP　アドレス
* ポート番号　:プロトコルで用いるTCPポート番号
* パス　:階層を表す、一意なリソース
* クエリパラメータ :？の後がクエリパラメータ。名前=値形式の追加情報
* URIフラグメント　：Webページ内部の位置を指す

**URIパスの指定方法**

* 絶対URI　：先頭からのフルパス
* 相対URI　：起点からの相対的なパス
* ベースURI　：相対URIの起点を決めるためのURI

**URIと文字**
URIではASCII文字が使える
日本語などの文字をURIで使うには％エンコーディングが必要

#７.クールなURIの設計方法
クールなURIとは変わらない、普遍的なURIのこと
URIはリソースであり、リソースが変わらないということはアクセスが永続的にできるということなので、クールだねとのこと

* プログラミング言語に依存した情報を含めない　ファイル拡張子、開発用ディレクトリ、大文字、、etc
* メソッド名やセッションIDを含めない
* URIにはリソースを指し示す名詞を使う　動詞はHTTPメソッドで使うので使わない
* なるべくシンプルかつ人間が読んで理解できる 

**URIの変更方法**
301 Redirectを使ってURIの変更を知らせるとページランクを引き継げる（SEO的に○）

301 Redirect　：恒常的なURIの変更
302 Redirect　：一時的なURIの変更

**URIの設計テクニック**

* バージョン番号を含める。管理しやすくなる
* 拡張子を用いて多言語対応のリソースを切り替える。

     https://qiita.com/drafts.js　 →　　.jsで日本語
     https://qiita.com/drafts.en　　→　.enで英語

**URIの不透明性を保つためにクライアント側でURIを構築しない**

* URIからリソースの構造を推測できないようにする
* URIに拡張子を含めるとその言語で操作されるため避ける
* API経由以外でサーバーから情報を抜き出される


#８.HTTP　TCP/IPの４階層モデル
HTTPはTCP/IPというネットワークプロトコルがベースになっており、以下の層のようになっている

**HTTP　アプリケーション層**　アプリケーション毎の通信プロトコルを決定する層　：WEBページであればhttpプロトコル、メールの送信であればSMTPプロトコル

**TCP　トランスポート層**　データ転送の抜け漏れをチェックする層

**IP　インターネット層**　データを送るための層　：IPアドレス、パケット（データを小分けにしたもの）などの技術が関連

**Ethernet　ネットワーク・インターフェース層**　：LANケーブルなどの物理的な層


**HTTPのバージョン**
HTTP０．９　：GETメソッドのみ
HTTP１．０　：レスポンスの追加（ステータスコードなど）、POSTメソッドの追加
HTTP１．１　：原則、１通信＝　１リクエスト　＝１レスポンス
HTTP２．０ ：ストリームの多重化による複数リクエストの同時通信

#９.リクエストとレスポンスの流れ
１，【クライアント】リクエストMSGの構築　【サーバー】待機
２，【クライアント】リクエストMSGの送信　【サーバー】リクエストMSGの受信
３，【クライアント】待機　　　　　　　　【サーバー】リクエストMSGの解析
４，【クライアント】レスポンスMSGの受信　【サーバー】HTML取得
５，【クライアント】レスポンスMSGの解析　【サーバー】レスポンスMSGの受信
６，【クライアント】レンダリング処理　【サーバー】レスポンスMSGの送信


**HTTP１．１とHTTP２．０の違い**
上記のリクエストとレスポンスの処理を複数同時におこなえるのがHTTP２．０

#１０.HTTPメッセージ
||リクエスト|レスポンス|
|---|---|---|
|リクエストライン  |メソッド：GET<br>パス：/posts/123<br>プロトコルバージョン：HTTP/2  |プロトコルバージョン：HTTP/2<br>ステータスコード：200<br>テキストフレーズ：OK  |
|ヘッダー（メタデータ）  　　　|accept:要求するデータ形式<br>Host：リクエスト先のホスト名<br>User-Agent：リクエスト元情報  |content-type：帰ってくるデータ形式  |
|ボディ（表データ） |POSTやPUTのときに使う作成したいリソース情報  |サーバーが返す実際のデータ　HTMLやJSONなど  |

>[参考　APIを叩けるサイト httpsbin](https://httpbin.org/#/Response_formats/get_json)

**HTTPはステートレス通信で行うのが良いとされている**
ステートレスはクライアントの情報をサーバーが管理しない
ステートフルはクライアントの情報をサーバーが管理する　
違いがある

* サーバーがクライアントの状態を管理せずに通信する
* ステートフルは簡潔　接続先が多くなると管理しきれない（）
* ステートレスは冗長でデータ量が多いがシンプル
* ステートレスで通信エラーが起きると重複する可能性あり


#１１.HTTPメソッド
|メソッド|CRUD|役割|
|---|---|---|
|GET|Read|リソースの役割|
|POST|Create|子リソースの作成、リソースへのデータ追加,etc|
|PUT|Create/Update|リソースの更新（存在しなければ作成）|
|DELETE|Delete|リソースの削除|
|HEAD|ー|リソースのヘッダ取得|
|OPTION|ー|リソースがサポートしているメソッドの取得|

HEAD、OPTION以外の４つのメソッドでCRUDを実装することが多い

#１２．べき等性と安全性
べき等性：ある操作を何回行っても結果が同じこと
安全性：捜査対象のリソースの状態を変化させないこと

|メソッド|べき等性|安全性|
|---|---|---|
|GET|○|○
|POST|✕|✕
|PUT|○|✕
|DELETE|○|✕
|HEAD|○|○
|OPTION|○|○

#１3．ステータスコードの大分類
ステータスコード　：レスポンスの意味を示すコード

|ステータスコード|意味|詳細|
|---|---|---|
|1xx|処理中|処理が継続していることを示す<br>クライアントがそのままリクエストを継続するか再送信するかなど判定
|2xx|成功|リクエストの成功を示す
|3xx|リダイレクト|他のリソースへのリダイレクトを示す<br>Locationヘッダーを見て新しいリソースへ接続する
|4xx|クライアントエラー|クライアントのリクエストが原因でエラーが発生したことを示す
|5xx|サーバーエラー|サーバー側で何らかのエラーが発生したことを示す

*先頭の数字でどのようなレスポンスか把握できる
*未知のステータスコードは先頭の数字で判断

**よく使うステータスコード**

|ステータスコード|テキストフレーズ|意味|
|---|---|---|
|200|OK|GET：取得したリソースがメッセージ本文で送信される<br>HEAD：ヘッダー情報がメッセージ本文で送信される<br>PUT or POST：操作の対象がメッセージ本文で送信される
|201|Created|新たなリソースが作成された、PUTまたはPOSTのレスポンス
|204|No Content|リクエストのレスポンスとして送信するコンテンツはないがリクエストは成功
|301|Moved Permanently|リソースの恒久的な移動
|400|Bad Request|クライアントエラー。リクエストの構文やパラメータが間違っている
|403|Forbidden|認証されてないなどコンテンツのアクセス権がない（ログイン認証が必要なページにアクセスしたりで発生する）
|404|Not Found|リソースが存在しない、URLを解釈できなかったなど
|500|Internal Sever Error|サーバー側で処理できないエラーが発生。相手側に問題がある事が多い。
|502|Bad Gateway|ゲートウェイとなるサーバーが正常に作動しなかった
|503|Service Unavalliable|サーバーがメンテナンスや過負荷などでダウンしている

>[参考　HTTPステータスコード｜MDN](https://developer.mozilla.org/ja/docs/Web/HTTP/Status)

**ステータスコードによるエラー処理**

* Accceptヘッダに応じたフォーマットでエラーを返す
<br>type/html：HTMLでエラーを返すページを作成して返す
<br>application/json :JSONでresponse.error.messageなどを表示する
* SPAのバックエンドとしてJSON形式のAPIを利用しているときはステータスコードに応じでコンポーネントを作成する場合もある↓

```javascript:app.js
const fetchData = async () => {
 const res = await fetch('http://localhost:3000/URI')
 if (res.status === 400){
 //クライアントのエラー処理
 }
}
```

#１4．リクエストの付加情報を表すHTTPヘッダについて
**MINEメディアタイプの指定**

* MINEはMultipurpose Internet Mail Extensions
* Content-Typeヘッダでメディアタイプを指定（type／subtype形式）
* charsetパラメータは文字エンコーディングを指定
Content-Type：　application /json; charset=utf-8

|主要なType|意味|Type/subtype例|
|---|---|---|
|text|人が読んで理解できる|text/plain
|image|画像データ|image/jpeg
|audio|音声データ|audio/mpeg
|video|動画データ|video/mp4
|Application|その他データ|application/json

**様々なヘッダ情報**

|ヘッダ個別|例|意味|
|---|---|---|
|言語タグ|Conttent-Language.ja-jp|リソースを表現する言語
|コンテントネゴシエーション|Accept text/html,application/xml|クライアントが処理可能なメディアタイプ
|ボディの長さ|content-length:47|レスポンスボディのサイズ
|チャンク転送|Transfer-Encoding:chunked|大きなデータをチャンク（分けて転送する）

**HTTP認証のためのヘッダ**

* リソースのアクセスに制限がかかっている場合認証が必要
* Authorizatiounヘッダに認証情報を付与する
Authorizatioun：　Basic　asdughawudfahjh==
(asdughawudfahjh==はbase64エンコードで人には読めないが簡単にデコードできる)

|認証方法|仕様|特徴|
|---|---|---|
|Basic認証|base64でエンコードされたユーザーIDとパスワードを使用|簡単にデコードできる。HTTPSによる通信暗号化が必須
|Digest認証|デコードできないハッシュ化されらパスワードを使用|メッセージは暗号化されないので通信暗号化が必須
|Bearer認証|権限付きのトークンを取得して使用する|OAuthで保護されたリソースなどの認証に使う

#１4．キャッシュ
* リソースを再利用できる仕組み
* 現在の使用ではCache-Controlヘッダを使うことがほとんど
* 検証と再取得の条件を設定する

|指定方法|目的
|---|---|
|Cache-Control：no-store|キャッシュしない
|Cache-Control：no-cache|キャッシュするが再検証する
|Cache-Control：max-age=86400|相対的な有効期限を設定。単位は秒（86400秒=24時間）
|Cache-Control：must-revalidate|必ず検証する