DockerとLaravel10でAPI作成（Postmanで動作確認）

# はじめに

### DockerとLaravel10を使ってMySQLのCRUD処理を行うAPIを作成してみました。


# API作成
#### 1.使っている環境にあったDockerDesktop、Ubuntu、Postman、をインストールしておいてください。
#### 2.ターミナルを「Ubuntu（wsl）」で、以下のコマンドを実行するとLaravelのアプリケーションが作成されます。
```　
    curl -s https://laravel.build/ ここにアプリケーション名を入れます。 | bash
```
#### 3.sailコマンドを簡単に実行できるように以下を設定します。
:::note info
 .bashrcファイルの最終行に以下を追加します。
（ vi ~/.bashrc　　ESC モード切替　　o 改行　　:w セーブ　　:q 抜ける）
:::
```
alias sail='[-f sail] && bash sail || bash vendor/bin/sail'
```
その後、以下を実行します。
```
source ~/.bashrc
```
#### 4.開始
```
sail up -d
```
-dをつけるとバックグラウンドで実行します。

:::note alert
sailがエラー時、再起動および、実行しているディレクトリの場所を確認してみてください。
:::

開始してからブラウザで
http://localhost
にアクセスするとLaravelの初期画面が表示されます。

#### 5.停止
```
sail stop
```
#### 6.phpMyAdminを追加する方法

docker-compose.ymlファイルのMysql:の各種命令文の下に以下を追加します。
```docker-compose.yml
    phpmyadmin:
        image: phpmyadmin/phpmyadmin:latest
        ports:
            - 8080:80
        depends_on:
            - mysql
        environment:
            PMA_HOST: mysql
            PMA_USER: '${DB_USERNAME}'
            PMA_PASSWORD: '${DB_PASSWORD}'
        networks:
            - sail
```
:::note alert
追加の際、タブの位置がずれていると、うまくいかない場合があります。
:::

ブラウザからlocalhost:8080にアクセスするとphpMyAdminに接続することができます。

#### 7.日本対応
configフォルダ内のapp.phpファイルのtimezoneとlocaleを以下に書き換える。
```app.php
'timezone' => 'Asia/Tokyo',
'locale' => 'ja',
```

:::note alert
うまくいかない場合は
.envファイルのDB_DATABASE,DB_USERNAMEを書き換える
```.env
DB_DATABASE =　データベース名
DB_USERNAME =　ユーザー名（root等）
```
:::

#### 8.以下コマンドで、モデル、マイグレーション、コントローラーファイルをまとめて作成します。
```
sail artisan make:model ここにモデル名を入れる、頭文字は大文字で（例.Todo） -m -c
```
出来上がるファイル
モデルファイル（app→Models内）
Todo.php
マイグレーションファイル（database→migrations内）
日時_create_todos_table.php
コントローラーファイル（app→Http→Controllers内）
TodoController.php


各ファイル記入例

モデルファイル（例.Todo.php）
```php:Todo.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Todo extends Model
{
    use HasFactory;
    protected $fillable = [
        'text',
    ];
}
```

マイグレーションファイル（例.日時_create_todos_table.php）
```php:日時_create_todos_table.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('todos', function (Blueprint $table) {
            $table->id();
            $table->text('text');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('todos');
    }
};
```

コントローラーファイル（例.TodoController.php）
```php:TodoController.php
<?php
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Todo;
use App\Http\Controllers\Controller;

class TodoController extends Controller
{
       /**
     * ToDo作成.
     *
     * @param Request $request
     * @return void
     */
    public function create(Request $request) {
        $todo = Todo::create($request->all());

        return response()->json($todo);
    }
    /**
     * ToDo取得.
     *
     * @param Request $request
     * @return void
     */
    public function fetch(Request $request) {
        $todo = Todo::find($request->id);
        return response()->json($todo);
    }
    /**
     * ToDo更新.
     *
     * @param Request $request
     * @return void
     */
    public function update(Request $request) {
        $todo = Todo::find($request->id);
        $todo->update([
            'id' => $request->id,
            'text' => $request->text,
        ]);
        return response()->json($todo);
    }
    /**
     * ToDo削除.
     *
     * @param Request $request
     * @return void
     */
    public function delete(Request $request) {
        $todo = Todo::find($request->id);
        $todo->delete();
        return response()->json();
    }
}
```

ルーティング(routesフォルダ内)
今回APIとして使うため
api.phpファイルを以下に書き換える。
```php:api.php
<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\TodoController;

/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider and all of them will
| be assigned to the "api" middleware group. Make something great!
|
*/
// ToDoのCRUD
Route::post('todo', [TodoController::class, 'create']);
Route::get('todo', [TodoController::class, 'fetch']);
Route::put('todo', [TodoController::class, 'update']);
Route::delete('todo', [TodoController::class, 'delete']);
});
```

これでAPIは完成になります。

# 作成したAPIの動作確認

#### 1.Postmanでの確認方法

　　私が使用しているPostmanのタイムゾーン変更方法が不明の為、phpMyAdminの画面と
　　Postmanに表示されている時間に差異があります。
　　調べたところ
　　Settings→GeneralにあるTimezone項目で使用するタイムゾーンに設定とありましたが
　　使用しているバージョン（10.13.5）のPostmanには
　　上記の場所にTimezone項目がありませんでした。


:::note info
PostmanでSendまでの手順

![Postman01加工済み.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3353594/062d34bc-ec39-1266-e0b1-c02feccaf7a0.png)

**①　WorkspacesからMyWorkspaceを選択**
**②　Collections選択、＋をクリック**
**③　New Collectionクリック後、表示されるAdd a request部をクリック、New Requestをクリック**
**④　POST,GET,PUT,DELETE使いたいものを選択後、右スペースにlocalhost/api/todo と入力**
**⑤　Body選択**
**⑥　raw選択**
**⑦　JSON選択**
**⑧　送りたいJSONコードを入力（下記、入力例参考）**
**⑨　Sendをクリック**
:::

#### 2.入力例

:::note info
**Post(Create)**

Send前（Post）
Postman
![Postman03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3353594/016354f7-1ecc-4656-99e0-f40e806b1ca8.png)
phpMyAdmin（確認）
![Postman02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3353594/a142f367-77c4-d0d1-a8de-1c5efc3b5d9b.png)

Send後（Post）
Postman（結果）
![Postman04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3353594/eb1d5c3e-398b-bac9-61b1-f88abe482bf5.png)
phpMyadmin（結果）
![Postman05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3353594/3e74f69a-6d48-b1bd-9af7-6127ea29e5a0.png)
:::

:::note info
**Get(Read)**
Send前（Get）
Postman
![Postman06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3353594/ade5dcb4-5387-3549-960a-0ad29aff3650.png)
Send後（Get）
phpMyAdmin（確認）
![Postman07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3353594/8250bfc2-6f41-a90a-e9da-5cd2de212dfa.png)
Postman（結果）
![Postman08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3353594/5313d6fc-c1f2-851a-cd1f-0209b5e7fe54.png)
:::

:::note info
**Put(Update)**
Send前（Update）
Postman
![Postman10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3353594/5dc6755b-cf0c-0db6-5e05-ec95f2ff0f6d.png)
phpMyAdmin（確認）
![Postman09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3353594/c0686980-99bb-21f3-488e-249eac5631c1.png)
Send後（Update）
Postman（結果）
![Postman12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3353594/553154bf-a6ce-cfb0-072c-37d667eda466.png)
phpMyAdmin（結果）
![Postman11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3353594/515f6e94-868b-f976-af31-ef6918625926.png)
:::

:::note info
**Delete(Delete)**
Send前（Delete）
Postman
![Postman14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3353594/7b65318d-1875-1703-d479-ba4b8fc6a1d2.png)
phpMyAdmin（確認）
![Postman13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3353594/783701c6-eb0b-2175-71ba-8bc0f36cc693.png)
Send後（Delete）
Postman（結果）
![Postman16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3353594/ea7bffa5-f149-4e73-ebfc-09bc8fd09c0c.png)
phpMyAdmin（結果）
![Postman15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3353594/822fad19-4ca0-0fa2-202f-c66b579537a1.png)
:::

以上になります。

# 最後に

最後まで読んでいただきまして、ありがとうございました。