LaravelでAPIを作るの最終回です。MySQLとの接続を行っていきます。
Modelの作成
LaravelのORM、Eloquent(エロクアント)を使っていきます。
PHPが動いているDockerコンテナに入って artisan
コマンドでModelを作ります。
$ docker-compose exec php bash
$ php artisan make:model Todos -f
App/Models
配下に Todos.php
が作られます。
class Todos extends Model
{
use HasFactory;
}
class TodosFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = Todos::class;
/**
* Define the model's default state.
*
* @return array
*/
public function definition()
{
return [
//
];
}
}
調べていて気がついたのですが -c
や -r
、 -api
をつけることで Controllerも作ってくれるようです。
今回は -f
オプションでモデルとファクトリを作成します。
Todosに追記
カラム情報とtimestampeがないことを定義します。
protected $fillable = [
'task',
];
public $timestamps = false;
準備はこれで終わり。ControllerからModelを使ってDBアクセスをしてみます。
検索
Todos::all
で全件を取得し、 Todos::find
でプライマーキーで検索を行います。検索した結果をそのままレスポンスに返しています。
JSON_UNESCAPED_UNICODE
はマルチバイト文字が文字化けを起こさないように設定しています。
public function getTodos(Request $request): JsonResponse
{
$todos = Todos::all();
return response()->json($todos, 200,
['Content-Type' => 'application/json;charset=UTF-8', 'Charset' => 'utf-8'],
JSON_UNESCAPED_UNICODE);
}
public function getTodo(Request $request, int $id): JsonResponse
{
$todo = Todos::find($id);
return response()->json($todo, 200,
['Content-Type' => 'application/json;charset=UTF-8', 'Charset' => 'utf-8'],
JSON_UNESCAPED_UNICODE);
}
登録、更新、削除
DB::beginTransaction
でトランザクションを開始し、成功時にはコミット、失敗時にはロールバックしています。
単一テーブルへの操作なので特に必要ないですが、お試しに入れてみました。Controllerにトランザクション処理があるのは正直気持ち悪さはありますがw
public function createTodo(Request $request): JsonResponse
{
$task = $request->input('task');
DB::beginTransaction();
try {
$new = Todos::create([
'task' => $task,
]);
DB::commit();
} catch ($exception) {
DB::rollBack();
}
return response()->json($new, 201,
['Content-Type' => 'application/json;charset=UTF-8', 'Charset' => 'utf-8'],
JSON_UNESCAPED_UNICODE);
}
public function updateTodo(Request $request, int $id): JsonResponse
{
$task = $request->input('task');
DB::beginTransaction();
try {
$todo = Todos::find($id);
$todo->update(['task' => $task]);
DB::commit();
} catch ($exception) {
DB::rollBack();
}
return response()->json($todo, 201,
['Content-Type' => 'application/json;charset=UTF-8', 'Charset' => 'utf-8'],
JSON_UNESCAPED_UNICODE);
}
public function deleteTodo(Request $request, int $id): JsonResponse
{
DB::beginTransaction();
try {
$todo = Todos::find($id);
$todo->delete();
DB::commit();
} catch ($exception) {
DB::rollBack();
}
return response()->json(null, 200);
}
まとめ
とりあえず目的のAPIを作ることはできました。検索はもっと複雑な絞り込みや結合を試さないとですし、ロジックをControllerに書いてしまっているのでソフトウェアアーキテクチャを導入して責務を明確にしてあげる必要がありますしユニットテストも書きたいし。まだまだやることはありますね。
それらについてはまだ後日余力があれば試したいと思います。
今回作ったソースはGitHubに上げてあります。
github.com