Laravel5.5こと始め 〜6. ユーザ管理APIの追加〜

# 内容
以下の順番にまとめます。
[1. MacへのXAMPP+Laravelインストール](https://qiita.com/sonrisa/items/f08112fe0ec4f51e4bdf)
[2. ユーザログイン機能の追加](https://qiita.com/sonrisa/items/207fd53eced13fc88acf)
[3. MVCとルーティングの説明]
(https://qiita.com/sonrisa/items/809adf872e6fb3657f81)
[4. ユーザリストの表示]
(https://qiita.com/sonrisa/items/929486929ed8d851a24e)
[5. ユーザリストのペジネーション表示]
(https://qiita.com/sonrisa/items/86efb8caebe207ab8fa8)
[6. ユーザ管理APIの追加](https://qiita.com/sonrisa/items/bc4894e6803632089ceb) ←いまここ
[7. Vue.jsとAPIベースのユーザ管理アプリの追加準備](https://qiita.com/sonrisa/items/595f080c6ecf1ed61b93)
[8. Vue.jsとAPIベースのユーザ管理アプリの追加](https://qiita.com/sonrisa/items/48a9a8e73e757c81619a)
[9. Vue.jsとAPIベースのユーザ管理アプリへのペジネーション追加]
(https://qiita.com/sonrisa/items/d58c56b638924d8c6810)
[10. APIへのJWTAuth認証の追加]
(https://qiita.com/sonrisa/items/97c1f3e8491f76dc2ce2)
[11. Vue.jsとAPIベースのユーザ管理アプリへの認証の追加](https://qiita.com/sonrisa/items/1976cbd049cadfec1285)

# 6. ユーザ管理APIの追加
ここでは、Vue.jsというJavaScriptベースのシングルページアプリケーション構築ライブラリとREST APIの組み合わせのWebアプリケーションを開発します。そのためにまずはユーザ一覧表示、ユーザ情報詳細表示、ユーザ情報更新、ユーザ削除といったユーザ管理を行うAPIを作成します。

## 6.1 APIを実装したコントローラを作成

下記のとおり「app/Http/Controllers/UserController.php」を作成します。

```app/Http/Controllers/UserController.php
<?php 
namespace App\Http\Controllers; 
use Illuminate\Support\Facades\DB; 
use Illuminate\Http\Request; 
use App\Http\Controllers\Controller; 
use App\User; 

class UserController extends Controller 
{ 
    public function index() // ユーザ一覧を返します
    { 
        $users = User::all();
        return $users;
    } 
    public function show($id) // ユーザIDをキーにユーザ情報詳細を返します
    { 
        $user = User::findOrFail($id); 
        return $user; 
    } 
    public function update(Request $request, $id) // ユーザIDをキーにユーザ情報を更新します
    { 
        $user = User::findOrFail($id);
        $user->update($request->all()); 
        return $user; 
    } 
    public function store(Request $request) // ユーザを追加します
    { 
        $user = new User; 
        $user->name = $request['name']; 
        $user->email = $request['email']; 
        $user->password = bcrypt($request['password']); 
        $user->save(); 
        return $user; 
    } 
    public function destroy($id) // ユーザIDをキーにユーザ情報を削除します
    { 
        $user = User::findOrFail($id); 
        $user->delete(); 
        return ''; 
    } 
} 
```

## 6.2 APIのルーティングを設定

下記の通り「routes/api.php」にAPIのURIとコントローラの設定を行います。

```routes/api.php
<?php

use Illuminate\Http\Request;

/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/

Route::group([], function () {
    Route::resource('users', 'UserController');
});
```

「php artisan route:list」コマンドを実行して、APIのルーティングが追加されていることを確認します。

```
...
|        | GET|HEAD  | api/users              | users.index      | App\Http\Controllers\UserController@index                              | api        |
|        | POST      | api/users              | users.store      | App\Http\Controllers\UserController@store                              | api        |
|        | GET|HEAD  | api/users/create       | users.create     | App\Http\Controllers\UserController@create                             | api        |
|        | GET|HEAD  | api/users/{user}       | users.show       | App\Http\Controllers\UserController@show                               | api        |
|        | PUT|PATCH | api/users/{user}       | users.update     | App\Http\Controllers\UserController@update                             | api        |
|        | DELETE    | api/users/{user}       | users.destroy    | App\Http\Controllers\UserController@destroy                            | api        |
|        | GET|HEAD  | api/users/{user}/edit  | users.edit       | App\Http\Controllers\UserController@edit                               | api        |
...
```

「app/Http/Controllers/UserController.php」で実装されている関数は、「index/show/update/store/destroy」ですが、ルーティングには「create」や「edit」が定義されています。「create」は「store」とほぼ同義ですが、HTTPメソッドが異なります。「create」は「GET|HEAD」、「store」は「POST」に反応して実行されます。

## 6.3 APIのエラー処理を追加

ここまでで発生しそうなAPIのエラーを想像してみると、「ルーティングで認められていないHTTPメソッドが呼ばれ」たり、「ルーティングで定義されていないURIが呼ばれ」たり、「値のないIDが呼ばれ」たりするケースが考えられます。これらのエラー処理は「app/Exceptions/Handler.php」の「render」メソッドに記載します。

```app/Exceptions/Handler.php
... (中略)
    /**
     * Render an exception into an HTTP response.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Exception  $exception
     * @return \Illuminate\Http\Response
     */
    public function render($request, Exception $exception)
    {
      // ここから追記
      // ルーティングで認められていないHTTPメソッドが呼ばれたケース
      if(basename(str_replace('\\','/',get_class($exception)))=='MethodNotAllowedHttpException') {
        return response()->json(['error'=>'HTTP Method Not Allowed'],405);
      }
      // ルーティングで定義されていないURIが呼ばれたケース
      if(basename(str_replace('\\','/',get_class($exception)))=='NotFoundHttpException') {
        return response()->json(['error'=>'URI Not Found'],404);
      }
      // 値のないIDが呼ばれたケース
      if(basename(str_replace('\\','/',get_class($exception)))=='ModelNotFoundException') {
        return response()->json(['error'=>'Record Not Found'],404);
      }
      // ここまで追記
      return parent::render($request, $exception);
    }
}
```

## 6.4 APIの実行

作成したAPIがうまく動くか確認します。例のごとく「php artisan serve」を実行してuserauthを起動します。

ブラウザから http://localhost:8000/api/users にアクセスし、JSONのレスポンスが表示されることを確認します。

<img width="327" alt="スクリーンショット 2018-07-09 22.59.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/263562/d3d9c83e-cefb-3990-4280-9a70cb99621d.png">


ここではブラウザにChromeを使っており、JSONViewというプラグインを追加しているためJSONが整形されて表示されます。おすすめです。

以下、curlコマンド（HTTPメソッドを実行するコマンド）とjqコマンド（JSONデータをパースして人が見やすい形式でインデントしてくれるコマンド）を使って「index/show/update/store/destroy」を試します。curlコマンドやjqコマンドがない場合は「brew install curl」や「brew install jq」でインストールしてください。

### index(GET|HEAD):
ユーザ一覧を返します

```
$ curl -X GET http://localhost:8000/api/users 2>/dev/null | jq
[
  {
    "id": 1,
    "name": "test1",
    "email": "test1@test.com",
    "created_at": "2018-07-09 13:43:53",
    "updated_at": "2018-07-09 13:43:53"
  },
  {
    "id": 2,
    "name": "test2",
    "email": "test2@test.com",
    "created_at": "2018-07-09 13:43:53",
    "updated_at": "2018-07-09 13:43:53"
  },
  {
    "id": 3,
    "name": "test3",
    "email": "test3@test.com",
    "created_at": "2018-07-09 13:43:54",
    "updated_at": "2018-07-09 13:43:54"
  }
]
```

### show(GET|HEAD):
ユーザIDをキーにユーザ情報詳細を返します。以下はURI「api/users/2」で指定したとおりユーザIDが2のユーザ情報を取得しています。

```
$ curl -X GET http://localhost:8000/api/users/2 2>/dev/null | jq
{
  "id": 2,
  "name": "test2",
  "email": "test2@test.com",
  "created_at": "2018-07-09 13:43:53",
  "updated_at": "2018-07-09 13:43:53"
}
```

存在しないユーザIDを4に指定して実行してみます。

```
$ curl -X GET http://localhost:8000/api/users/4 2>/dev/null | jq
{
  "error": "Record Not Found"
}
```

### store(POST): ユーザを追加します
ヘッダーにコンテンツタイプがJSONであることを指定して（-H "Content-type: application/json")とJSON形式のデータをPOSTします。


```
$ curl -H "Content-type: application/json" -X POST -d '{"name":"test4","email":"test4@test.com","password":"(uhBnji9"}' http://localhost:8000/api/users | jq
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   181    0   118  100    63    704    376 --:--:-- --:--:-- --:--:--   706
{
  "name": "test4",
  "email": "test4@test.com",
  "updated_at": "2018-07-09 14:02:48",
  "created_at": "2018-07-09 14:02:48",
  "id": 4
}
```

### update(PUT|PATCH):
ユーザIDをキーにユーザ情報を更新します。以下は、ユーザIDが2のユーザ名を"test2"から"test02"に更新します。

```
$ curl -H "Content-type: application/json" -X PUT -d '{"name":"test02"}' http://localhost:8000/api/users/2 | jq
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   136    0   119  100    17    674     96 --:--:-- --:--:-- --:--:--   676
{
  "id": 2,
  "name": "test02",
  "email": "test2@test.com",
  "created_at": "2018-07-09 13:43:53",
  "updated_at": "2018-07-09 14:03:20"
}
```

### destroy(DELETE):
ユーザIDをキーにユーザ情報を削除します。以下は、ユーザIDが3のユーザを削除します。

```
$ curl -H "Content-type: application/json" -X DELETE http://localhost:8000/api/users/3
```

削除されたことを確認します。

```
$ curl -X GET http://localhost:8000/api/users 2>/dev/null | jq
[
  {
    "id": 1,
    "name": "test1",
    "email": "test1@test.com",
    "created_at": "2018-07-09 13:43:53",
    "updated_at": "2018-07-09 13:43:53"
  },
  {
    "id": 2,
    "name": "test02",
    "email": "test2@test.com",
    "created_at": "2018-07-09 13:43:53",
    "updated_at": "2018-07-09 14:03:20"
  },
  {
    "id": 4,
    "name": "test4",
    "email": "test4@test.com",
    "created_at": "2018-07-09 14:02:48",
    "updated_at": "2018-07-09 14:02:48"
  }
]
```

以上、ひととおりのAPIをcurlコマンドで試しました。APIのテストにはPOSTMANというChromeのプラグインも使いやすいです。興味のある方は試してみてください。

以上、「6. ユーザ管理APIの追加」が完了です。

次は、「[7. Vue.jsとAPIベースのユーザ管理アプリの追加準備](https://qiita.com/sonrisa/items/595f080c6ecf1ed61b93)」です。

## 参考URL

参考1.POSTMANの使い方 https://www.webprofessional.jp/master-api-workflow-postman/
参考2.JSONView https://chrome.google.com/webstore/detail/jsonview/chklaanhfefbnpoihckbnefhakgolnmc