web API(学習メモ）ユーチューブにのってたのでまとめた

#web APIについて
・マイクロサービスの流行
→連携するのに必要になってきました。
・便利なSaaSが増えました。
→APIをつかってそのサービスにアクセスして使用することができる。

Node.jsで最小限のAPIを作成することができる。
ExpressでAPI用のサーバーを立てることができる。（ExpressはNode.jsのパッケージの1つである）

#webの概論
・webサイト→情報を閲覧を目的としている。
ユーザーがそのページを訪れることで、情報を見ることができる。

・webアプリ→対話型
情報の閲覧だけでなく、ユーザーが動くことができる。
口コミを投稿するとか、高評価するとか・・・
webとユーザーで行き来する感じ？
※ネイティブアプリ→マックとかアイフォンにインストールされているアプリを指す。
webアプリは、webブラウザ上で動くものです。

・ユーザーインターフェースとしてのweb

・web API
→プログラムによって、プログラムが動かすwebのこと。
プログラムがなにかの情報を持ってきてくれたり、削除したり更新したりしてくれるやつ。
→webAPIのフォーマットとして使用されるのがjson。
ほとんどがjsonで使われている。

:sunny:webを支える技術は3つほど。
http：通信するためのルール（プロトコル）

URI：リソースを識別するIDのこと。
URLのほうが有名ちゃうか
→URI自体は、そのでデータの存在場所とかがしっかりわかっているし、名前もわかっている感じ。
URLはそのデータの存在場所まではわかるんだけど名前はわからないみたいな感じ。
URIの中にURLが含まれている感じ。（サーバー）

HTML：webで表示するための文書のフォーマット（webブラウザ）
ユーザーはクライアント側。

★htmlとURIの通信手段がhttpみたいな感じか。★

:sunny:分散システム
複数のコンピューターで1つのシステムを作っている感じ。AWSもこんな感じだよね。

:sunny:集中システム
メインフレームがやっている（昔に主流だったやつ）

##REST API
REST APIとかで使われる。
RESTとは設計思想、設計モデル
設計思想で作成されたAPIをREST APIと呼ばれる。

webのアーキテクチャスタイルと呼ばれる。アーキテクチャスタイルとは、設計様式。
アーキテクチャスタイル　REST
アーキテクチャ＝サーバー、ブラウザ
実装＝アパッチ、クローム

★webにおけるリソース
web上に存在する名前をもったあらゆる情報のこと。
URIはリソースの名前＋住所のこと
複数のURIを持つリソースも存在する
URIにアクセスして、URLを確認してブラウザで検索し、サイトを訪れる感じ。

#RESTを構成する6つのアーキテクチャスタイル
①クライアント/サーバー
→UIと処理を分離する。通信はhttpで行っている。
うちらで持っているスマホとかがクライアントで、なにかのサービスを行ってくれるのがサーバーみたいな感じ。

②ステートレスサーバー⇔ステートフル(クッキーを使ってセッションを行う、サーバーで情報を持つのね）
→状態をもたないのが基本。（RESTは）
クライアントとサーバーってゆう関係性で、うちらが使っているスマホとかで何をしたかとかはいちいちサーバーには落とさないよね？そのこと。サーバーは感知しない。
クライアントでリクエストがきたらそれに対して、サーバーはレスポンスを返す。それだけ。

③キャッシュ
→サーバーからしゅとくしたリソースの再利用
リソースは、web上で存在する名前をもった情報（サイト）のことです。


④統一インターフェース
→操作可能なインターフェースを限定
getメソッド、postメソッドなど限られたことしかできないように限られていること。

⑤階層化システム
システムがいくつかに分かれていること
大きなシステムだといくつかサーバーがある。そうすると振り分けをするために、ロードバランサーとかプロキシが必要となってくる。
それらもすべてhttpという限定されたプロトコルで通信することができ、階層化されていても通信をきちんとすることができるらしい。
→システムを改装に分離
ロードバランサーやプロキシサーバーみたいなのいるでしょ。

⑥コードオンデマンド
→クライアントでダウンロードを実行する。
じゃバスクリプトとかをクライアントで動かしているけど、サーバー側においてあるジャバスクリプトのデータをクライアントでDLしてくれるおかげでクライアントのブラウザでみることができるかんじ。

★これらすべて6つがないとRESTにならないわけではない。1つくらいかけてもOK
RESTに基づいて設計されていますみたいに言える。

##URI
URIはユニークでないとだめ（世界で１つしかないようにしないとダメ）
https://www.yahoo.co.jp/

URIスキーム：通信プロトコルを指す（http or https)
ユーザー情報：ユーザーネームとパスワードでの形式
ホスト名：DNSで名前解決できるドメイン名　or IPアドレス
ポート番号：プロトコルで用いるTCPポート番号
パス：階層を表す、いちいのリソースを指す
クエリパラメーター：名前＝値形式の追加情報
URIフラグメント：webページ内部の位置情報を指す

絶対URI　絶対にてっぺんからの移動
相対URI 今いる場所からどこに移動するのかみたいな感じ
ベースURI：相対URIの起点を決めるためのURI
URIはURLとURNの合体版
URLがサイトの住所、URNがいちいの名前

##URIをどんなふうに設計していけばいいのか？
①プログラミング言語に依存した情報は含めない
→ファイルの拡張子を入れない。.phpとか。
ディレクトリの構造とかも。更新したときに合わなくなるから。

②メソッド名や、セクションのIDは入れない。
action=とか入れない。
毎回URI変わってしまうので

③URIには、リソースを指し示す名詞を使うこと。
動詞は使わない
※動詞は、HTTPメソッドで表現することができる。

④なるべくシンプルで人間が読んで理解できるようにする。
https://kinako.com/posts/123みたいな感じ。

##URIの変更方法
３０１リダイレクトを使ってURIの変更を知らせる（永遠に変更してますよーってアナウンスしてくれている）
３０２の一時的なURIの変更もOK
ページは引越ししました〜みたいな感じで新しいページへ
リダイレクトされる。

下記も合わせて設計するとなおよし！！！:frowning2:
☆ver番号を含めてURI設計をすると良い。
☆拡張子を用いて、多言語対応のリソースの切り替えを行う。
英語用と日本語用で変える。
https://kinako.com/posts/123.jp  日本語バージョン
https://kinako.com/posts/123.en　英語バージョン


＃＃＃URIの不透明性を保つ
URIのリソースの構造を推測できないようにする。
APIを経由せずにサーバーからデータを取得することもできてしまうので。

URIに拡張子を含めると（プログラミング言語）その言語で操作されてしまう可能性あり
クライアント側でURI構築を行わない。

##httpでリクエストを投げて、レスポンスを受け取る。

###TCP/IP4階層のモデル。
httpはアプリケーション層だよね。
アプリケーションごとの通信プロトコルを決定する層。

TCPはトランスポート層→データの転送の抜け漏れを防ぐ
IP→インターネット層でデータを送るための層
イーサネット＝LANケーブルなどの物理的な層

:sunny:HTTPのバージョン
長年1.1が主流であったが、最近はHTTP2.0が使われ始める。

HTTP 0.9 GETメソッドのみ（情報取得のみ）
　　　1.0 POST,レスポンスヘッダの追加（ステータスコードなどの付加情報）
　　　1.1 原則1通信＝1リクエスト＝1レスポンス
　　　2.0 ストリーム多重化による複数リクエストの同時通信

リクエストとレスポンスの流れ
リクエストするのがクライアント（うちらが使ってる側）
レスポンスを返してくれるのが、サーバー待機したりしてる
htmlを取得して、リソースはどこにあるのかしらべてクライアントにレスポンスとして返す。
リクエストでjsonのデータが欲しいとかいうときでも同じような動きをしますので！

http2.0ならこのリクエストとレスポンスが1個以上でもOkってこと。
（ストリーム）
1.0の時は、レスポンスが帰ってくれくるまで、次のリクエストはできなかった。

##HTTPメッセージ
①リクエストライン/ステータスライン
どんなメソッドに対して、リクエストがあるのかみたいな。
(リクエスト）
メソッド：GET
パス：/kinako/123
プロトコルバージョン：HTTP/2

（レスポンス）
プロトコルバージョン：HTTP/2
ステータスコード：200
テキストフレーズ：OK

②ヘッダー（メタデータ）
メタデータ（データのためのデータ）
→実際に欲しいデータはボディにあるので。
ボディの付加情報（プラスαてきな）
(リクエスト）
accept:要求するデータの形式
Host:リクエスト先のホスト名
User-Agent:リクエスト元情報

（レスポンス）
content-type:帰ってくるデータ形式
（例えばJSONとかで返す）

③ぼでぃ（実データ）
POSTはなにか新しくページをつくりたいですよーって時につかう。
そーゆーときにサーバーへリクエストする。
（リクエスト）
POSTやPUTの際に使用する
作成したいリソースの情報など

（レスポンス）
サーバーが返す実際のデータ
HTMLやJSONなど

##CRUDのためのHTTPメソッドについて
HTTPメソッドは全部で８個だけど主要なメソッドは全部で６つ。
４つのメソッドでCRUDをすることが多い。

:sunny:クラッド (CRUD)とは
システムに必要な4つの主要機能である「Create（生成）」「Read（読み取り）」「Update（更新）」「Delete（削除）」の頭文字を並べた用語です。

①GETメソッド　Read
リソースの取得
情報をとってくる

②POSTメソッド　Create
子リソースの作成、リソースへのデータの追加
リソースの作成と追加

③PUTメソッド　Create Update
リソースの更新、存在しなければ作成をする。
リソースの更新、なければ更新

④DELETE　Delete
リソースの削除

⑤HEAD　-
リソースのヘッダを取得する
リソースのヘッダ情報、メタデータを取得する

⑥OPTIONS -
リソースがサポートしているメソッドの取得
そのリソースで対応（サポートしている）メソッドとOPTIONSで返してくれる。

:sunny:べき等性と安全性
・べき等性＝ある操作を何回も行っても結果が同じであること
GETが代表だが、リソースの情報を取得する操作をするけど、そのGETを何回もやっても同じリソースが帰ってくるのでべき等性（同じ操作を何回やっても結果が同じである）といえる。

逆にべき等性でないやつの代表が、POST
新しくリソースを作成する、作るたびにリソースを作成されてけっかが変わっていくので、べき等性ではないといえるのだ

・安全性＝操作対象のリソースの状態を変化させないこと
ＧＥＴも情報を取得するだけで、なにも変わらないので安全性といえるのだ
POSTもべき等性と同じようにリソースの変化があるので安全性ではないといえないのだ

GET　べき等かつ安全
POST　べき等でもなく、安全でもない
一番危険なメソッドらしい。
どんどん変わっていくので

PUT　べき等だが、安全ではない
更新するだけなのでべき等性
リソースの状態はリソースＡ→Ｂに変化しているので安全性はないといえる。
中身が変わっていなければ、べき等性といえるのかな？

DELETE　べき等だが安全ではない
HEAD　べき等かつ安全　
OPTIONS　べき等かつ安全

jsonサーバー立ち上げたら出た。
コマンドプロンプトで、npmとnode入ってること確認した
その後に、gitからjsonファイル入ってるやつをクローンして自分のローカルに作成した。
その後に、そのディレクトリに移動して、json-server --watch db.jsonをコマンドで打ったら
サーバーが立ち上がったのか、以下の写真のような画像出てきた。

![スクリーンショット 2021-05-31 20.52.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620109/637b4924-2ebc-9070-781d-f718640a86b7.png)

これでGETメソッドを開く
curl -i GET "http://localhost:3000/episodes" -v
そうすると、

```
 Could not resolve host: GET
* Closing connection 0
curl: (6) Could not resolve host: GET
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 3000 (#1)
> GET /episodes HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.64.1
> Accept: */*
> 
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< X-Powered-By: Express
X-Powered-By: Express
< Vary: Origin, Accept-Encoding
Vary: Origin, Accept-Encoding
< Access-Control-Allow-Credentials: true
Access-Control-Allow-Credentials: true
< Cache-Control: no-cache
Cache-Control: no-cache
< Pragma: no-cache
Pragma: no-cache
< Expires: -1
Expires: -1
< X-Content-Type-Options: nosniff
X-Content-Type-Options: nosniff
< Content-Type: application/json; charset=utf-8
Content-Type: application/json; charset=utf-8
< Content-Length: 212
Content-Length: 212
< ETag: W/"d4-ZwVtVHqgX7GuvWLVK/T1C5bx4l8"
ETag: W/"d4-ZwVtVHqgX7GuvWLVK/T1C5bx4l8"
< Date: Mon, 31 May 2021 11:50:14 GMT
Date: Mon, 31 May 2021 11:50:14 GMT
< Connection: keep-alive
Connection: keep-alive

< 
[
  {
    "id": 1,
    "title": "開始"
  },
  {
    "id": 2,
    "title": "ぼくドラえもん"
  },
  {
    "id": 3,
    "title": "のび太とドラえもん"
  }
* Connection #1 to host localhost left intact
]* Closing connection 1

```
GETメソッドを引っ張ってきてくれました。

##メソッドの間違え
べき等性を失ってしまわないように。
①リソースの取得以外でGETメソッドを用いる。
→URIをGETメソッドで取得してしまう。

②他のメソッドをPOSTで代用する
応用できてしまうメソッド
GET、PUTやDELETEでできることもPUTでできてしまう。
それぞれの良さを失ってしまう。
GET→べき等でも安全でもなくなる
PUTとかDELETE→ベキ等でなくなる

③PUTで相対的な値を用いる
元の数値に５０を加えるみたいなPUTメソッド
実行のたびに、結果は異なるので、ベき等とは言えないのだ。
PUTメソッドをするときは、絶対的な数値を与える。

##ステータスコードについて
リクエストすると必ずレスポンスは帰ってくる、そのレスポンスがどんなものなのかがすぐに簡潔にわかるようにするために3桁の数字で完結的にクライアントに教えてくれる。

200ならリクエストの成功を出すみたいな感じになる。
処理が成功した場合、処理が失敗した場合の条件分岐に進んでいくみたいなプログラムを記載することができる。

※ステータスコードの表示の仕方
Google chromeの場合
①確認したいWebサイトを開きます。
②開発者モードを開きます、F12を押します。
③Networkタブを押します。
④F5(MacはCommand+r)で更新します。


:sunny:ステータスコードの大分類
★１XX
処理中
処理が継続していることを示す。クライアントがそのままリクエストを継続するか再送信するかなどを判定する。
処理中である。

★２XX
成功
リクエストへの成功を示す。なのでレスポンスも成功してるわけ。

★３XX
リダイレクト
他のリソースへのリダイレクトを示す。
locationヘッダーを見て新しいリソースへ接続する。
他のURIに変わったりしていることを示す。

★４XX
クライアントエラー
クライアントのリクエストが原因でエラーが発生したことを示す。

★５XX
サーバーエラー
サーバー側で何かしらのエラーが出たことを示す。

未知のステータスコードは。とりあえず先頭の数字で大枠を判定する。

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

☆２００　OK
GET：取得したリソースがメッセージ本文で送信される。
HEAD：ヘッダー情報がメッセージ本文で送信される
PUTかPOST：捜査の結果がメッセージ本文で送信される

☆２０１　Created
新たなリソースが作られた
PUTまたはPOSTのレスポンス

☆２０４　No Content
リクエストのレスポンスとして送信するコンテンツはないが、リクエストは成功

☆３０１　Moved Permanently
リソースの恒久的な移動
古いURLから新しいURLに移動してくださいって意味。


#HTTPヘッダはたくさん！

##MIMEメディアタイプの指定
（Multipurpose Internet Mail Extensions）
インターネット上のメールの拡張
Content-typeヘッダで、メディアタイプを指定（type/subtype形式）
→これはお決まり。

charsetパラメータは文字エンコーディングを指定
utf-8でエンコーディングしてくれたものを出してくれるみたいな感じ。
utf-8は日本語にも対応してるし、どれでも対応してくれてる感じ〜

Content -Type：application/json; charset=utf-8

主要なタイプ
:relaxed:text
人が読んで理解することができる。
text/plain

:relaxed:image
画像データ
image/jpeg

:relaxed:audio
音声データ
audio/mpeg

:relaxed:video
動画データ　video/mp4

:relaxed:Application
その他のデータ　application/json

##HTTP認証のためのヘッダ
リソースのアクセスに制限がかかっている時に認証が必要
認証情報はヘッダで送って、返してもらう。
Authorizationヘッダに認証情報を付与する

Authorization：Basic asdughawudfahkh==
みたいな感じ！
base６４は人に読めない！！！簡単に解読はできるみたい
なので、安全ではない。

base６４エンコードで人には読めないけど、簡単にデコードできる
エンコードとは、暗号化のこと
デコードは、エンコードされたデータをもとに戻すこと

:relaxed:Basic認証
base６４でエンコードされたユーザーIDとパスを使用
簡単にデコードすることができる。
他の人にバレないように、HTTPSよる通信暗号化が必要。

:relaxed:Dlgest認証
デコードできないハッシュ化されたパスワードを使用する
メッセージは暗号化されないので、HTTPSによる通信暗号化が必要。
メッセの本体は、暗号化されない。
ハッシュ化＝ルールに基づき、別の値に置き換えること

:relaxed:Bearer認証
最近多く使われるようになった。
権限付きのトークンを取得して使用する
０Auth2.０で保護されたリソースなどの認証に使う。