使用環境
Laravel 5.7
jwt-auth 1.0.0-rc3
この記事は下記の続きです。
Laravel + JWTAuth + Vue.js でAPIログイン認証の実装
Laravel + Vue.js にVuexを導入する
データベースの作成
データベースを作成するためマイグレーションファイルを作成します。
artisanで雛形を作成して、
$ php artisan make:migration create_tasks_tableスキーマは下記のようにします。
<?phpuse Illuminate\Support\Facades\Schema;use Illuminate\Database\Schema\Blueprint;use Illuminate\Database\Migrations\Migration;
class CreateTasksTable extends Migration{ public function up() { Schema::create('tasks', function (Blueprint $table) { $table->increments('id'); $table->string('title'); $table->integer('state_id')->unsigned()->default(1); $table->integer('user_id')->references('id')->on('users')->unsigned()->index()->nullable(); $table->timestamp('due_at')->nullable()->comment('期日'); $table->timestamps(); }); }
public function down() { Schema::dropIfExists('tasks'); }}シーダーもartisanで雛形を作成して、
$ php artisan make:seeder TasksTableSeederダミーデータを適当に作成します。
<?phpuse Illuminate\Database\Seeder;
class TasksTableSeeder extends Seeder{ public function run() { DB::table('tasks')->insert([ [ 'title' => 'はじめてのタスク', 'state_id' => 1, 'user_id' => 1, 'due_at' => '2018-10-02 14:28:19', 'created_at' => '2018-10-02 14:28:19', 'updated_at' => '2018-10-02 14:28:19' ],[ 'title' => '2番目のタスク', 'state_id' => 2, 'user_id' => 1, 'due_at' => '', 'created_at' => '2018-10-04 14:28:19', 'updated_at' => '2018-10-04 14:28:19' ] ]); }}DatabaseSeeder.phpに作成したシーダーを追記します。
public function run(){ $this->call(UsersTableSeeder::class); $this->call(TasksTableSeeder::class);}artisanでデータベーステーブルを作成しましょう。
$ php artisan migrate$ php artisan db:seed --class=TaskTableSeederモデルの作成
Taskモデルを作成します。
$ php artisan make:model Models\Task<?phpnamespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Task extends Model{ /** * @var array */ protected $fillable = [ 'title', 'state_id', 'user_id', 'due_at' ];}リポジトリの作成
モデルとコントローラーの間にリポジトリを挟んでみます。
あとで変えるかもですが、とりあえずこんな感じ。
<?phpnamespace App\Repositories;
use Illuminate\Database\Eloquent\Model;
class Repository{ /** * @var Model */ protected $model;
/** * @param Model $model */ public function __construct(Model $model) { $this->model = $model; }
/** * @return \Illuminate\Database\Eloquent\Collection */ public function all() { return $this->model->all(); }
/** * @param array $data * @return mixed */ public function store(array $data) { return $this->model->create($data); }
/** * @param array $data * @param int $id * @return mixed */ public function update(array $data, int $id) { $record = $this->model->find($id); return $record->update($data); }
/** * @param int $id * @return int */ public function delete(int $id) { return $this->model->destroy($id); }
/** * @param int $id * @return mixed */ public function findById(int $id) { return $this->model->findOrFail($id); }}リクエストの作成
バリデーションの設定とかをここで書きます。
とりあえずタイトルを必須に。
<?phpnamespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class TaskRequest extends FormRequest{ /** * @return bool */ public function authorize() { return true; }
/** * @return array */ public function rules() { return [ 'title' => 'required' ]; }
/** * @return array */ public function messages() { return [ 'title.required' => 'タイトルは必ず入力してください。', ]; }}コントローラーの作成
コントローラーは基本response()->json()で返します。
LaravelでViewを持つ必要がないので、CreateとEditはいらないですね。
<?phpnamespace App\Http\Controllers;
use App\Models\Task;use App\Repositories\Repository;use App\Http\Requests\TaskRequest;
class TasksController extends Controller{ /** @var Repository */ protected $repository;
/** * TasksController constructor. * @param Task $task */ public function __construct(Task $task) { $this->repository = new Repository($task); }
/** * @return \Illuminate\Http\JsonResponse */ public function index() { $tasks = $this->repository->all(); return response()->json($tasks); }
/** * @param $id * @return \Illuminate\Http\JsonResponse */ public function show($id) { return response()->json($this->repository->findById($id)); }
/** * @param TaskRequest $request * @return \Illuminate\Http\JsonResponse */ public function store(TaskRequest $request) { $response = $this->repository->store($request->all()); return response()->json($response, 201); }
/** * @return \Illuminate\Http\JsonResponse */ public function update(TaskRequest $request, int $id) { $response = $this->repository->update($request->all(), $id); return response()->json($response, 200); }
/** * @param $id * @return int */ public function destroy($id) { return $this->repository->delete($id); }}ルーターの追記
作成したコントーラーにアクセスする為にルーターに追記します。
ログインしないとアクセスできないようにする為、auth:apiの中に書きます。
<?phpRoute::group(['middleware' => 'auth:api'], function () { Route::get('/me', 'AuthController@me'); Route::post('/logout', 'AuthController@logout');
// Task Route::resource('tasks', 'TasksController', ['only' => ['index', 'show', 'store', 'update', 'destroy']] );});テストファイルの作成
最後に作成したAPIが問題なく動くか簡単にテストしてみます。
Laravelのテスト環境の構築は下記を参考にしてください。
このAPIはすべてログインしないと使用できないので、setUpのactingAsでログイン状態になるように指定します。
あとはシーダーも実行しておきましょう。
<?phpnamespace Tests\Feature;
use Tests\TestCase;use Illuminate\Foundation\Testing\RefreshDatabase;use App\User;
class TaskTest extends TestCase{ use RefreshDatabase;
public function setUp() { parent::setUp(); $this->artisan('db:seed');
// ログイン認証 $user = factory(User::class)->create(); $this->actingAs($user, 'api'); }
/** * @test */ public function GETでアクセスするとjsonが返却() { $response = $this->get('api/tasks'); $this->assertThat($response->content(), $this->isJson()); }
/** * @test */ public function SHOWで取得情報は正しいか() { $response = $this->get('api/tasks/1'); $response->assertJson([ 'title' => 'はじめてのタスク' ])->assertStatus(200); }
/** * @test */ public function GETで取得できるjsonは要件通りである() { $response = $this->get('api/tasks'); $tasks = $response->json(); $task = $tasks[0]; $this->assertSame(['id', 'title', 'state_id', 'user_id', 'due_at', 'created_at', 'updated_at'], array_keys($task)); }
/** * @test */ public function GETの取得件数は2件である() { $response = $this->get('api/tasks'); $response->assertJsonCount(2); }
/** * @test */ public function POSTでデータが追加される() { $params = [ 'title' => 'テストタイトル', 'state_id' => '1', 'user_id' => '1' ]; $this->postJson('api/tasks', $params); $this->assertDatabaseHas('tasks', $params); }
/** * @test */ public function POSTでtitleが未入力のエラー() { $params = [ 'state_id' => '2', 'user_id' => '2' ]; $response = $this->postJson('api/tasks', $params); $response->assertJsonFragment(['title' => ['タイトルは必ず入力してください。']]); }
/** * @test */ public function UPDATEで情報は更新されるか() { $params = [ 'title' => '書き換えたタイトル' ]; $respose = $this->putJson('api/tasks/1', $params);
$this->assertTrue($respose->json()); $this->assertDatabaseHas('tasks', $params); }
/** * @test */ public function DALETEで情報は削除されるか() { $params = [ 'id' => 1 ]; $this->deleteJson('api/tasks/1'); $this->assertDatabaseMissing('tasks', $params); }}以上でAPIの実装は終わりです。
次回はVue.jsで実際に操作できるようにしていきたいと思います。
ここまでのソースコードはGithubに載せてあります。
LaravelTodoSPA

