RESTful APIについて

## RESTとは
「REpresentational State Transfer」の略で分散型システムを構築するための考え方
 RESTの考え方に従って設計されたAPIをREST APIと言う
####　”RESTful APIはただのルール”　と考えると良い！
###イメージ図↓

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620608/ddd0fc34-52ef-9de1-727f-530d3fbfb824.png)
　
Q.RESTとRESTful APIの違いは何？
　A.RESTの原則に従って作られたAPIと言う意味でRESTとRESTfulは同じ意味で使われている。

ファイルのイメージ↓
#####Model→リソース
#####Controller→Modelを動かす（GET,PUTなどで）
## 1.RESTの特徴
#####1）Uniform（ユニフォーム・インターフェース）
情報の操作(取得、作成、更新、削除)は全てHTTPメソッド(GET、POST、PUT、DELETE)を利用すること

#####2）Stateless（ステートレス）
HTTPをベースにしたステートレスなクライアント/サーバプロトコルであること。セッション等の状態管理はせず、やり取りされる情報はそれ自体で完結して解釈できること
#####3）Cacheable（キャッシュ可能）
#####4）Self-descriptiveness（自己表現構造）
REST APIメッセージだけ見ても簡単に理解できる独自の表現構造になっている
 
#####5）Client – Server構造
RESTサーバーはAPIを提供し、クライアントはユーザー認証やコンテキスト（セッション、ログイン情報）などを直接管理する構造になっている。それぞれの役割が確実に区別されており、クライアントとサーバーで開発すべき内容が明確になり、相互依存関係が低減される
#####6）階層型構造
 
## 2.REST APIの規則

#####1）URLはリソースを表現しなければならない（リソース名は動詞ではなく、名詞を使用）
```
✖️　PUT /boards/create/1
```

上記のような方式は、RESTを正しく適用していないURIで、URLはリソースを表現することに重点を置かないといけない。createのような操作の表現が入らないようにする。
#####2）リソースの操作は、HTTPメソッド（GET、POST、PUT、DELETEなど）で表現する
1)の例を、HTTPメソッドで変更すると下記のようになる。

```
PUT /boards/1
```
会員情報を読み込む際はGET、会員情報を追加したい場合はPOSTメソッドを使って表現する。

```
//会員情報の取得
✖️　GET /members/show/1     
○　GET /members/1     
     
//会員情報の追加
✖️　GET /members/insert/2   　　　　　　- GETメソッドはリソースの生成に適さない
○　POST /members/2  
```
     
## 3.HTTPメソッドの適切な役割（ここが重要！）
POST、GET、PUT、DELETE、4つのメソッドを使ってCRUD（Create,Read,Update,Delete)できる。

| メソッド | 内容 |
|-----------|------------|
| POST | 対応するURLをリクエストし、リソースを作成する |
| GET | リソースを照会して、当該ドキュメントの詳細情報を取得する |
|PUT|当該リソースを変更する|
|DELETE|リソースを削除する|

URIはリソースの表現に集中して、操作の定義はHTTPメソッドを使って処理する
## 4.URI設計時の注意点
##### 1）スラッシュ区切り記号（/）は、階層関係を表すのに使用する
```
http://example.com/boards/name
```
↑上記で言えば、boardsの下の階層にあるname 
##### 2）URIの最後の文字にスラッシュ（/）を含めない
URLに含まれるすべての文字は、リソースの唯一の識別子として使用する。
REST APIは、明確なURLを作成して通信する必要があるため、混同しないようにURLパスの最後にスラッシュ（/）を使用してはいけない。

``` 
✖️ http://example.com/boards/name/ 
○ http://example.com/boards/name 
```

##### 3）ハイフン（ – ）は、URI可読性を高めるために使用
URIを簡単に読み取って解釈できるように、止むを得ず長いURIパスを使用する場合は、ハイフンを使って可読性を高める。
##### 4）アンダースコア（_）は、URIに使用しない
下線は表示が難しかったり、下線によって文字が隠れたりすることがあったりするため、このような問題を回避するために、アンダースコアの代わりにハイフン（ – ）の使用が推奨される。
##### 5）URIパスは小文字が適している
大文字と小文字に基づいて別のリソースとして認識してしまうため、URIパスに大文字を使うのは避ける。RFC 3986（URI文法形式）は、URIスキームとホストを除き、大文字と小文字を区別するように規定している。

``RFC 3986 is the URI (Unified Resource Identifier) Syntax document``
##### 6）ファイルの拡張子は、URLに含めない
```
✖️ http://restapi.example.com/members/soccer/345/photo.jpg 
```
REST APIは、メッセージ内容のフォーマットを表すファイルの拡張子をURLの中に含めない。
``` GET / members/soccer/345/photo HTTP/1.1 Host: restapi.example.com Accept: image/jpg ```
## 5.HTTPステータスコード

| ステータスコード | 内容 |
|-----------|------------|
|200|クライアントのリクエストを正常に遂行
201|



| ステータスコード | 内容 |
|-----------|------------|
|400|クライアントのリクエストが不十分な場合に使用するコード|
|401|クライアントが認証されていない状態で保護されたリソースをリクエストしたときに使用するコード|
|403|ユーザー認証の状態に関わらず、応答したくないリソースをクライアントがリクエストしたときに使用するコード（403より400や404の使用を推奨)|
|405|クライアントがリクエストしたリソースが、使用できないメソッドを用いた場合に使用するコード|


| ステータスコード | 内容 |
|-----------|------------|
|301|クライアントがリクエストしたリソースのURIが変更されたときに使用するコード（応答時、Location headerに変更されたURIを書かなければならない）|
|500|サーバーに問題がある場合に使用するコード|

 
##[参考] RESTなAPIを作る上でのルール
##### ①ひと目でAPIと分かるようなURLにする
##### ②URLにAPIのバージョンを含める
##### ③URLに動詞を含めず、複数形の名詞のみで構成する→下で説明
##### ④アプリケーションや言語に依存する拡張子は含めない
##### ⑤リソースの関係性がひと目で分かるようにする
##### ⑥長くしすぎない 
###ルール③　URLに動詞を含めず、複数形の名詞のみで構成する
REST APIにおいてはリソースに対し一つのURLを割り当てていくことがポイント

```
//好ましくないURL
http://api.example.com/v1/createArticle
http://api.example.com/v1/article/create
http://api.example.com/v1/article/126/create
http://api.example.com/v1/article/createComment
http://api.example.com/v1/article/126/comment/10/create 
```
 
##### 上記の問題点
`1.リソースに対して一意ではない
2.一つのリソースに対してCRUDの操作が必要になった場合にその操作の分だけURLが増え
てしまう
3.URLが長くなりがち`
 
```
//複数形の名詞のみの場合（好ましいURLの例）
http://api.example.com/v1/articles　　　　　　　　　　　　　　　　　article全てを指す
http://api.example.com/v1/articles/126　　　           articlesの中のID：126を指す
http://api.example.com/v1/articles/126/comments　
　　　　　　　　　　　　　　　　　　        articlesの中のID:126についたcomment全てを指す
http://api.example.com/v1/articles/126/comments/10　
　　　　　　　　　　　　     　　  articlesの中のID:126についたcommentsの中のID:10を指す
```
このURLを見ただけで何のリソースなのかが分かり、IDをURLに含めることでリソースごとに一意のURLを割り当てることができている。
名詞を複数形にすることで全てのリソース(複数)を指す場合と、全てのリソース(複数)の中からIDを指定している場合を表現することができ、表現に一貫性を持たせることができる。
 
 
 
##REST APIの例
ユーザーを管理するAPIを例に上げると、、、

| やりたいこと  | URL | HTTPのメソッド |
|------------ |-------------|-------------|
|ユーザ一覧確認 |https://APIサーバのホスト名/users|GET|
|ユーザ新規登録|https://APIサーバのホスト名/users|POST|
|ユーザ変更|https://APIサーバのホスト名/users/ユーザID|PUT|
|ユーザ削除|https://APIサーバのホスト名/users/ユーザID|DELETE|
##RESTではないAPIの例

| やりたいこと | URL | HTTPのメソッド |
|-----------|------------|------------|
|ユーザ一覧確認|https://APIサーバのホスト名/get_users|GET|
|ユーザ新規登録|https://APIサーバのホスト名/create_user|GET|
|ユーザ変更|https://APIサーバのホスト名/modify_users|GET|
|ユーザ削除|https://APIサーバのホスト名/delete_users|GET|

##参考資料
RestfulなWebAPIの設計(Qiita)
https://qiita.com/kawasukeeee/items/70403129f5a5338cd4ad
RESTful APIとは何なのか(Qiita)
https://qiita.com/NagaokaKenichi/items/0647c30ef596cedf4bf2