8章 Webを支える技術

今回の記事では、HTTPステータスコードについて明記します。

HTTPステータスコードは、WebサービスやWeb API設計するにあたり、重要なPOINTです。

というのも、
ステータスコードは、エラーが起きた際に**どのステータスコード**を返すかによって、
開発者の実装やUserに対して、的確な表現できるからです。

設計するにあたり、ユーザビリティ向上や開発者がしやすい開発をするためにもとても重要な
役割を担っています。

<h2>HTTPステータスコード</h2>

```
| --- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | 
| 1xx | 処理中             | クライアントが処理を継続的に処理しているをことを示している。クライアントがそのままリクエストを送り続けるか、サーバの指示に従ってプロトコルをアップデートして送信するか。 
| 2xx | 成功               | リクエストが送信したことを示す。                                                                             
| 3xx | リダイレクト       | 他のリソースへのリダイレクトを示す。クライアントがステータスコードを見た時、<br>レスポンスメッセージのLocationヘッダを見て新しいリソースへ接続する。                    
| 4xx | クライアントエラー | クライアントエラーを示す。クライアントのリクエストに原因がある。原因解消されないことには、正常な結果が得られないので、同じリクエストを送信できない。                     
| 5xx | サーバエラー       | サーバエラーを示す。サーバ側の原因を解消すれば、同一のリクエストを送信しても、正常な結果が得られる。                                                                     
```

::: note warn
※ステータスコードは、**既に定められているステータスコード**であり、自身で定めたりすることができないです。
理由は、クライアントが処理しやすいからです。あらかじめ、どのステータスコードが返ったら、処理をすることが定めているので、クライアントは対応しやすい。
:::


<h3>4xxと5xxのステータスコードについて</h3>

ただ、その前提ではありますが、400系と５00系では、注意が必要です。
ただ、418のように(HTTP1.1では401~417しか定まっていない)のちに追加されたステータスコードも存在します。
そのステータスコードをクライアントが未知のステータスコードであるとみなした場合は、
400や500エラーを返すことが可能です。

また、4xxと5xxのステータスコードはHTTPで定められているが、
ボディに入るエラー文言自体は、定めていない。
自由に決めることができる。

:::note warn
※エラー文言は、ボディに入れた方が良い。
理由: 開発者やユーザに対して、どのようなエラーなのか、わかりやすく伝達できるからである。
:::

<h4>よく使われるステータスコード</h4>

**200ステータスコード**
```
リクエスト
GET /test HTTP1.1
Host: example.jp

```


```
レスポンス
HTTP1.1 200 OK
Content-Type: text/plain; charset=utf-8

Hello World
```

PUTやPOSTの場合はボディに処理結果が入ります。
```
リクエスト
PUT /test HTTP1.1
Host: example.js
Content-Type: text/plain; charset=utf-8

こんにちは
```


```
レスポンス
HTTP1.1 200 OK
Content-Type: text/plain; charset=utf-8

こんにちは!
```

**201 Created --リソースの作成成功**
201はリソースを新たに作成したことを指す。レスポンスボディには*慣習的に*新しく作成したリソース表現を入れることが多いが、特に何も入れなくても構いません。

※POSTの場合は新しく作成したリソースURIはレスポンスのLocationヘッダに絶対URIとして入ります。

```
リクエスト
POST /list HTTP1.1
Host: example.jp
Content-Type: text/plain; charset=utf-8

こんにちは
```



```
レスポンス
HTTP1.1 201 Created
Location: example.jp/list/item1
Content-Type: text/plain; charset=utf-8

こんにちは
```


PUTの場合は、クライアントが新しいリソースURIを知っているためLocationヘッダは入りません

```
リクエスト
PUT /newitem HTTP1.1
Host: example.jp
Content-Type: text/plain charset=utf-8

こんにちは
```

```
レスポンス
HTTP1.1 201 Created
Content-Type: text/plain charset=utf-8

こんにちは
```

301 Movd Permanently --リソースの恒久的な移動
301はリクエストで**指定したリソース**が新しいURIに移動したことを示す。
古いURIを保ちつつ、新しいURIに移行する際にこのスタータスコードを用いる。新しいURIは、Locationヘッダに*絶対URI*に入ります。

```
リクエスト
Get /oldfeed HTTP 1.1
Host: example.jp 
```

```
レスポンス
HTTP 1.1 301 Moved Permanently
Location: http://example.jp/newfeed
Content-Type: application/xhtml+xml; charset=utf-8

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>redirect</title>
  </head>
  <body>
    <p>このフィードは
      <a href="http://exaple.jp/newfeed">新しいURI</a>に移動しました
    </p>
  </body>
</html>

```

```
リクエスト
Get /newfeed HTTP 1.1
Host: exaple.jp
```

```
レスポンス
HTTP 1.1 200 OK
Conetnt-Type: application/xhtml+xml; charset=utf-8
<feed xmlns="http://www.w3.org/2005/Atom">
...........
</feed>
``````
::: note warn
301や303のようにべつのURIにクライアントが**自動的に**遷移することをリダイレクトと呼ぶ。
:::

303　See Otherは、リクエストに対する処理結果が別のURIで取得できることを示す。典型的にはブラウザからPOSTでリソースを操作した結果をGetで取得する際に使う。

```
リクエスト
Post /login/ HTTP/1.1
Host: example.jp
Content-Type: application/x-www-form-urlencoded

username=yohei&password=foobar
```

```
レスポンス
HTTP 1.1 303 See Other
Location: http://www.example.jp/home/yohei

Content-Type: application/xhtml+xml; charset=utf-8

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>redirect</title>
  </head>
  <body>
    <p>このフィードは
      <a href="http://exaple.jp/newfeed">新しいURI</a>に移動しました
    </p>
  </body>
</html>
```

```
リクエスト
Get Home/yohei HTTP 1.1
Host: /example.jp
```
```
レスポンス
HTTP 1.1 200 OK
Conetnt-Type: application/xhtml+xml; cahrset=utf-8

<html xmlns="http://www.w3.org/1999/xhtml>
.......
</html>
```

<h4>404 Bad Request --リクエストの間違い</h4>
400 Bad Requestは、リクエストの構文やパラメータが間違えていたことを示す。
以下は、ユーザ情報をPUTで変更しようとしたときに設定したPWが「単純すぎる」というERRが発生している例である。

```
リクエスト
PUT /user/yohei HTTP 1.1
Conetnt-Type: application/json

(
"name" : "YAMADA Yohei"
"password" : "foobar"
)
```

```
レスポンス
HTTP 1.1 400 Bad Request
Content-Type: application/json

(
 "message" : "パスワードが単純すぎます。数字や英字を入れてください"
)

```

400 Bad Requestは、他に適切なクライアントエラーを示すステータスコードがない場合にも用いる。
また、クライアントにとって未知の4xx系ステータスコードが返ってきた場合
400 Bad Requestと同じ扱いで処理する仕様で定める。


401 Unauthorized --アクセス権不正
 401 Unauthorizedは、適切な認証情報を与えずにリクエストを行ったことを示す。
レスポンスの「WWW-Authenticateヘッダ」で、クライアントに対して認証方式を伝える。


```
リクエスト
DELETE /test HTTP 1.1
Host: example.jp
```

```
レスポンス
HTTP 1.1 401 Unauthorized
WWW-Authenticate: Basic realm="Example.jp"

```

<h4>404 Not Found --リソースの正体</h4>
404 Not Foundは指定したリソースが見つからないことを示す。
レスポンスボディにはその理由が入る。


```
リクエスト
GET /test HTTP 1.1
Host: example.jp
```

```
レスポンス
HTTP 1.1 404 Not Found
Content-Type : text/plain charset=utf-8

http://www.example.jp/testが見つかりませんでした。
```

<h4>500 Internal Server Error --サーバー内部エラー</h4>

500 Internal Server Error はサーバ側に何かしらのエラーが生じて正しいレスポンスが返らないことを示す。レスポンスボディには異常の理由が入る。

```
リクエスト
Get /test HTTP 1.1
Host:example.jp
```

```
レスポンス
HTTP 1.1 500 Internal Server Error
Content-Type: text/plain; charset-utf-8

サーバに異常が起きています。しばらく経ってから再度アクセスしてください。

```
500 Internal Server Errorは、ほかに適切なサーバエラーを示すステータスコードがない場合にも用いる。また、クライアントにとって未知の5xx系ステータスコードが返ってきた場合
500 Internal Server Error と同じ扱いで処理する仕様で定める。


<h4>503　Service Unavailable ---サービス停止</h4>

503 Service Unavailableは　サーバがメンテナンスなどで一時的にアクセスできないことを示す。レスポンスボディには、その理由が入る。
レスポンスのRetry-Afterヘッダでサービスを再開時期がおよそ何秒後であるかを通知することができる。

```
リクエスト
Get /test HTTP1.1
Host: example.jp
```

```
レスポンス
HTTP 1.1 503 Service Unavailable
Content-Type: text/plain charset=utf-8

Retry-After: 3600

ただいま、メンテナンス中です。しばらく経ってから再度アクセスしてください。
```

以上が、普段使われる**ステータスコード**である。