LaravelでAPIを作って簡単なCRUDを作成する

<br>

#LaravelでAPIを作って簡単なCRUDを作成する

LaravelでAPIを作って簡単なCRUD機能を作成。エンドポイントのテストはポストマンで行う。

##API resourcesを使ってAPIをつくる。
LaravelにはAPIを簡単に作れるようAPI resources機能があります。

すでにPostモデルとUserモデルは作成済み。Seederを使ってUserとPostのテストデータは作成済み

```Post.php
//データを入力できるようfillableを指定。
    protected $fillable = ['user_id', 'title', 'body', 'image'];
    
    public function user()
    {
        return $this->belongsTo(User::class);
    }
```
```User.php
    public function posts()
    {
        return $this->hasMany(Post::class);
    }
```
APIルートを作るために apiResource()をつかう。 routes/api.php に下記を追加。

```api.php
use App\Http\Controllers\PostController;

Route::apiResource('posts', PostController::class);
```
<br>
<br>
Postモデルにresourceクラスを作成する。resourceクラスをつくることでPostモデルからデータを取り出して、JSON形式でデータを返す。


```
php artisan make:resource PostResource
```

app/Http/Resources/PostResource.php が作成されるので修正。
toArray()メソッドがPostのリソースを配列に変換する。
JSON形式で返して欲しいものを記述。

```PostResource.php
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'title' => $this->title,
            'body' => $this->body,
            'image' => $this->image,
            'created_at' => (string) $this->created_at,
            'updated_at' => (string) $this->updated_at,
        ];
    }
```

resourceクラスができたのでPostControllerでPostResourceのインスタンスが使えるようになりました。

```php

   use App\Models\Post;
   use Illuminate\Http\Request;
   //PostResource
   use App\Http\Resources\PostResource;
   use Illuminate\Support\Str;

    //すべてのポストを取得
    public function index()
    {
        return PostResource::collection(Post::latest()->paginate(5));
    }

    public function store(Request $request)
    {
        //Validation
        $this->validate($request, [
            'title' => 'required',
            'body' => 'required',
            'user_id' => 'required',            
            'image' => 'required|mimes:jpeg,png,jpg,gif,svg',
        ]);

        $post = new Post;

        if ($request->hasFile('image')) {
            $image = $request->file('image');
            $name = Str::slug($request->title).'.'.$image->getClientOriginalExtension();
            $destinationPath = public_path('/uploads/posts');
            $imagePath = $destinationPath . "/" . $name;
            $image->move($destinationPath, $name);
            $post->image = $name;
        }
        //Postを作成
        $post->user_id = $request->user_id;
        $post->title = $request->title;
        $post->body = $request->body;
        $post->save();
        
        //PostをPostResourceとしてJSON形式で返す
        return new PostResource($post);
    }
```
　http://127.0.0.1:800/api/posts
　にアクセスするとindex()メソッドが呼び出される。apiなので/postsではなく/api/postsにアクセス。




<br>
showモデルで特定のポストを呼び出す。show(Post $post)はルートモデルバインディング。
ルートモデルバインディングについてはこちら。

https://laravel.com/docs/7.x/routing#route-model-binding

```php
//app/Http/Controllers/PostController.php

     public function show(Post $post)
    {
        return new PostResource($post);
    }
```
updateメソッドを追加

```php
//app/Http/Controllers/PostController.php

       public function update(Request $request, Post $post)
    {
        $this->validate($request, [
            'title' => 'required',
            'body' => 'required',
        ]);

        $post->update($request->only(['title', 'body']));

        return new PostResource($post);
    }
```

destroyメソッド。データの削除。そして204を返す。

https://developer.mozilla.org/ja/docs/Web/HTTP/Status/204

```php
//app/Http/Controllers/PostController.php

    public function destroy(Post $post)
    {
        $post->delete();

        return response()->json(null, 204);
    }
```

完成。ポストマンを使ってテストをする。

参考

https://morioh.com/p/715b2bc28221