【初心者】Laravel+Vue.jsでREST APIをやってみた

## はじめに
LaravelとVue.jsを使ってREST APIを作って叩いてみました。
※LaravelとVue.jsの環境は既にできている前提で書いています。

- 第1弾 LaravelのコントローラーとルーティングのみでAPI
- 第2弾 Laravelのみでデータベースから値を取得して返すAPI
- 第3弾 Laravelに加えてVue.jsを使ってAPI
という流れで進めています。


## 環境
- Mac(docker環境)
- Laravel 6系
- Vue.js 2系

## 第1弾 LaravelのコントローラーとルーティングのみでAPI
手始めにLaravelのコントローラーとルーティングだけでAPIを叩いてみます。



### ①コントローラー(testController)の作成
```
$ php artisan make:controller Api/testController
```

### ②JSONで返す値をコントローラーに準備

```Api/testController.php
class testController extends Controller
{
 public function index() {
  $memberList = [
    ['id' => 1, 'name' => 'hoge'],
    ['id' => 2, 'name' => 'fuga'],
    ['id' => 3, 'name' => 'piyo'],
  ];
  return $memberList;
 }
}
```
JSONで$memberListの値を返すAPIにしています。


### ③ルーティングの処理を追加
api.phpに下記を追加。(web.phpではないので注意)

```api.php
Route::resource('members', 'Api\testController');
```

### ④/localhost/Api/membersへアクセス
![controller, rooting.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/969534/5fcfb4d1-01a2-f1f1-0763-e3b11802a9cf.png)
無事APIを叩いてレスポンスが返ってきました！


## 第2弾 Laravelのみでデータベースから値を取得して返すAPI

次にMemberというテーブルを作成して、その中に登録されているデータを返却するAPIを作成します。
### ①モデルを作成
```
$ php artisan make:model Models/Member -m
```
mオプションをつけてマイグレーションのファイルも同時に準備しておきます。モデルは/app/Models/Member.phpが作られていればOKです。

### ②マイグレーションファイル修正
マイグレーションファイルはidとnameのカラムが欲しいので下記のように修正しておきます。
```2022_XX_XX_XXXXXX_create_members_table.php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateMembersTable extends Migration
{
 public function up()
 {
  Schema::create('members', function (Blueprint $table) {
  $table->bigIncrements('id');
  $table->string('name');
  $table->timestamps();
  });
 }
 public function down() {
  Schema::dropIfExists('members');
 }
}
```

### ③テーブルの作成
マイグレーションファイルを修正したらmigrateを実行します。
```
$ php artisan migrate;
```
これによりデータベースにmembersテーブルが作成されます。

### ④データの流し込み
テーブルを作成できたら、表示させるためのデータを予め登録しておきます。私はdockerを使っているのでmysqlのコンテナに入って直接SQLを叩いてインサートしています。
![show columns from members.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/969534/9dabdab7-8aa4-1bec-6029-7f5f541ccfef.png)
上記のようなコラムがあるので、下記のようにINSERT文を流し込みました。
```.sql
INSERT INTO members values(1,'hoge',NOW(),NOW()),(2, 'fuga',NOW(),NOW()),(3, 'piyo',NOW(),NOW());
```

### ⑤コントローラーの修正
第１弾で使った部分をコメントアウトしつつ、useを使ってモデルを使えるようにしておきます。

```testController.php
use App\Models\Member; //←モデルを呼び出すために追加
class testController extends Controller
{
    public function index()
    {
        //　第1弾で呼び出した部分はコメントアウト
        // $memberList = [
        //     ['id' => 1, 'name' => 'hoge'],
        //     ['id' => 2, 'name' => 'fuga'],
        //     ['id' => 3, 'name' => 'piyo'],
        // ]; 

        // 第2弾では下記を追加
        $members = new Member();
        $memberList = $members->get();
        return $memberList;
    }
```
### ⑥/localhost/Api/membersへアクセス
第1弾ではidとnameだけでしたが、今回はデータベースに入っている全てのカラムを取り出したのでcreated_atとupdate_atのカラムも取得されています。
![スクリーンショット 2022-02-26 13.22.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/969534/174e1e90-0d31-b196-171a-08e6479c7eaa.png)


## 第3弾 Laravelに加えてVue.jsを使ってAPI

### ①web.phpにルーティング追加
httpでアクセスがあった時のルーティングを追加します。
```routes.web.php
Route::get('/testApi', 'testApiController@index');
```

### ②Laravelのbladeを表示するためのコントローラーを追加

```/Http/Controllers/testApiController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class testApiController extends Controller
{
    public function index()
    {
        return view('testApi');
    }
}
```
### ③Laravelのbladeを準備
LaravelのbladeからVueテンプレートを呼び出します。
```resources/views/testApi.blade.php
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        // 略
        <title>Laravel</title>
    </head>
    <body>
        <div class="flex-center position-ref full-height">
            <div class="content">
                <div class="title m-b-md">
                    testAPI
                </div>
                <div id="app">
                    <api-retturn></api-retturn>  //Vueのtemplate呼び出し
                </div>
            </div>
        </div>
    </body>
</html>
```


### ④APIの処理をVueテンプレートに準備
APIリクエストを送って、レスポンスを受け取る処理をVueテンプレートに書きます。
```/resources/js/components/ApiRetturn.vue
<template>
    <div>
        <table class="table table-striped">
            <tr>
                <th>id</th>
                <th>name</th>
            </tr>
            <tr v-for="(item, index) in responseData" :key="index">
                <td>{{ item.id }}</td>
                <td>{{ item.name }}</td>
            </tr>
        </table>
    </div>
</template>

<script>
import axios from "axios";

export default {
    data() {
        return {
            responseData: [],
        }
    },
    methods: {
        getData() {
            axios.get('/api/members', {})
            .then(response => {
                this.responseData = response.data;
            })
            .catch(error => {
                alert('API ERROR');
            })
            .finally()
        }
    },
    mounted() {
        this.getData();
    },
}
</script>
```
axiosというJavaScriptのライブラリを使えばAPIにて対して、データの送受信をすることができます。


### ④APIのルーティングを追加

APIリクエストを受け受け取るためのルーティングを追加します。
```resources/api.php
Route::resource('members', 'Api\testController');
```

### ⑤API側のコントローラーの修正
api.phpから受け取ったリクエストはコントローラーへ送られ、データベースから取得したmemberのデータをレスポンスとして返します。
(第2弾でコントローラーを修正した場合、第2弾のまま修正不要です。)
```Http/Controllers/Api/testController.php
use App\Models\Member; //←モデルを呼び出すために追加
class testController extends Controller
{
    public function index()
    {
        $members = new Member();
        $memberList = $members->get();
        return $memberList;
    }
}
```
### ⑤/localhost/testApiにてアクセス
![スクリーンショット 2022-03-05 14.31.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/969534/7f655f6b-db51-06d7-a749-10b4588a9ac7.png)


DBの情報を表示するだけだと簡単ですね！！