PHPのwebアプリケーションフレームワーク「Laravel」でAPIを作ってみる
2024年も始まり、早くも2月に突入してしまいましたが、みなさまはいかがお過ごしでしょうか?
私は、相変わらずバックエンドとフロントエンドを行き来する忙しい日々を送っています。
前回に引き続き、今回はLaravelを使ってAPIを作ってみたいと思います。
前提
- WSL2
- ubunts v20.04
- PHP v8.3
- Laravel v10.4
- Postman(ローカルにインストール済み)
開発環境のセットアップとプロジェクトの作成
Laravel Sailを利用して、開発環境を構築し、新しいLaravelプロジェクトを作成しましょう。尚、開発環境は稼働させておきます。
$ curl -s https://laravel.build/myFirstApiInLaravel | bash
$ cd myFirstApiInLaravel
$ sail up -d
- http://localhost/
モデルの生成と必要な開発要素のセットアップ
以下のコマンドでAPIの実装にとりあえずは必要なものを作れます。便利ですね~。
$ php artisan make:model Product -mfs --api
INFO Model [app/Models/Product.php] created successfully.
INFO Factory [database/factories/ProductFactory.php] created successfully.
INFO Migration [database/migrations/2024_01_11_010607_create_products_table.php] created successfully.
INFO Seeder [database/seeders/ProductSeeder.php] created successfully.
INFO Controller [app/Http/Controllers/ProductController.php] created successfully.
各オプションは、以下の通りです。
-m | モデルに対応するマイグレーションファイルも同時に生成 |
---|---|
-f | モデルに関連するファクトリを生成 |
-s | モデルに関連するシーダーを生成 |
–api | API用のCRUD処理を持つコントローラーを生成 |
マイグレーションファイルの編集
必要なカラムを定義しましょう。
今回はシンプルに、textとdescriptionだけ追加します。
# database/migrations/2024_01_11_010607_create_products_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('products', function (Blueprint $table) {
$table->id();
$table->string('text'); //追加
$table->longText('description'); //追加
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('products');
}
};
モデルの編集
追加したカラムにデータを挿入する時等に一括で扱えるよう$fillable
を追加します。
# app/Models/Product.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
use HasFactory;
//以下4行追加
protected $fillable = [
'title',
'description',
];
}
ファクトリの編集
後ほど、シーダーでテスト用のデータを登録するのですが、1つずつ入れていくのは骨が折れるので、ファクトリを作って一気に登録できるようにしておきましょう。
また、テスト用のデータも全部一緒だと面白くないので、Fakerを使ってダミーデータを登録するようにします。
# database/factories/ProductFactory.php
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Product>
*/
class ProductFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'title' => $this->faker->title(), //追加
'description' => $this->faker->text(), //追加
];
}
}
シーダーの編集
シーダーを編集していきます。
factoryで実際にテストデータを登録する処理をDatabaseSeederクラスのrun()メソッド内に直接記述するのではなく、ProductSeederクラスで記述しています。
DatabaseSeederクラスでは、call()メソッドを使って実行したいシーダーを指定できます。
#database/seeders/ProductSeeder.php
<?php
namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use App\Models\Product; //追加
class ProductSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
Product::factory()->count(3)->create(); //追加
}
}
#database/seeders/DatabaseSeeder.php
<?php
namespace Database\Seeders;
// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*/
public function run(): void
{
//以下3行追加
$this->call([
ProductSeeder::class,
]);
}
}
マイグレートとシーディング
$ sail php artisan migrate
$ sail php artisan db:seed
tinkerで確認
tinkerでテストデータが入ったか確認しましょう。
$ sail tinker
> \App\Models\Product::all()
= Illuminate\Database\Eloquent\Collection {#5699
all: [
App\Models\Product {#5956
id: 1,
title: "Mr.",
description: "Nulla sit facilis cumque et. Omnis non eligendi suscipit. Occaecati voluptatem quo porro occaecati. Qui sed est officiis ut nihil architecto.",
created_at: "2024-01-11 02:10:37",
updated_at: "2024-01-11 02:10:37",
},
App\Models\Product {#5957
id: 2,
title: "Dr.",
description: "Explicabo omnis perferendis repudiandae repudiandae. Fuga pariatur saepe cupiditate dolor.",
created_at: "2024-01-11 02:10:37",
updated_at: "2024-01-11 02:10:37",
},
App\Models\Product {#5958
id: 3,
title: "Dr.",
description: "Aut voluptate id officiis ea dolores. Cumque nihil totam maiores. Et odit placeat itaque ut est impedit. Nisi quo ab inventore nemo vel.",
created_at: "2024-01-11 02:10:37",
updated_at: "2024-01-11 02:10:37",
},
],
}
無事登録されていますね。
データの取得
まずはデータを取得してみましょう。
controllerの編集
登録されているデータ全てを返すようにしてみましょう。
response()->json()メソッドでレスポンスヘッダーのContent-Type
をapplication/json
にしつつ、引数として渡された配列をjson_enconde
したjsonを返すことができます。
#app/Http/Controllers/ProductController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Product; //追加
class ProductController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index()
{
//以下4行追加
$products = Product::all();
return response()->json([
'products' => $products,
], 200);
}
...省略...
routesの定義
ルーティングを定義しましょう。
Route::apiResource()
はAPI開発に特化したCRUDのルーティングを作れる優れものです。
#routes/api.php
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\ProductController; //追加
/*
|--------------------------------------------------------------------------
| 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!
|
*/
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user();
});
Route::apiResource('products', ProductController::class); //追加
Postmanで挙動確認
postmanで挙動を確認します。
GETリクエストを送ってみましょう。
無事シーダーで登録したデータ3件が取得できてますね。
データの登録
次にデータを登録する流れを見てみましょう。
Form Requestを作成
Form Requestを作成することで、validationの実装をコントローラーから切り離すことができるみたいですね。
$ sail php artisan make:request StoreProductRequest
# app/Http/Requests/StoreProductRequest.php
<?php
namespace App\Http\Requests;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\Exceptions\HttpResponseException; //追加
class StoreProductRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true; //修正
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'title' => ['required', 'string'], //追加
'description' => ['required', 'string'], //追加
];
}
//以下追加
protected function failedValidation(Validator $validator)
{
$res = response()->json([
'message' => 'Failed create product',
'errors' => $validator->errors(),
], 400);
throw new HttpResponseException($res);
}
}
controllerの修正
controllerのstore()メソッドを修正します。
送られてきたProductを登録して、成功メッセージと登録されたProductを返すようにします。
# app/Http/Controllers/ProductController.php
...省略...
use App\Http\Requests\StoreProductRequest; //追加
class ProductController extends Controller
{
...省略...
public function store(StoreProductRequest $request) //修正
{
//以下5行追加
$product = Product::create($request->all());
return response()->json([
'message' => 'Product created successfully!',
'product' => $product,
], 200);
}
...省略...
Postmanで挙動確認
postmanで挙動を確認します。
まず、JSON形式のデータをボディに含めないでPOSTリクエストを送ってみます。
バリデーションが失敗し、エラーメッセージとともに400BadRequestステータスが返ってきてますね。
次に、JSON形式のデータをボディに含めてPOSTリクエストしてみます。
無事にProductが登録され、登録されたProductの情報とともに、200OKステータスが返ってきてますね。
tinkerで確認してみます。
$ sail tinker
> \App\Models\Product::all()
= Illuminate\Database\Eloquent\Collection {#5960
all: [
...省略...
App\Models\Product {#5965
id: 4,
title: "input title",
description: "input description",
created_at: "2024-01-11 02:51:08",
updated_at: "2024-01-11 02:51:08",
},
],
}
しっかりと登録されていますね。
終わりに
Laravelで初めてAPIを作ってみましたが、思ったより理解しやすかったです。 updateもdeleteも同じ感じで実装できそうですね。
ここ3回程バックエンドの内容だったので、次回はフロントエンドについて書いてみようかなーなんて思ってますが、どうでしょうかね。。。 本格的に寒くなってきたので、体調管理にはくれぐれも気を付けたいですね。
では、また。
- Laravel – The PHP Framework For Web Artisans
- LaravelでAPIを作成しテストする方法|Kinsta®
- 【Laravel入門】モデルの作成とシーディング #Laravel – Qiita
- Laravel 10のEloquentメソッド一覧 | トビログ
- [Laravel]初期データを登録する方法(Seederを使う) | Thousand Tech Blog
- 何じゃこりゃ! : Laravel 10 で Faker、Factory、Seeder を使用して疑似データを生成および挿入
- Requestクラスについて(Laravel) #PHP – Qiita
- 知らなかった!モデル作成時の便利なオプション大公開!(laravel)
- Route:apiRresourceを使おう【Laravel Routing】
- Laravelでオリジナルリクエストを作る|fumi
この記事を書いた人
-
大学4年時春に文系就職を辞め、エンジニアになることを決意し、独学でRuby、Ruby on Railsを学習。
約1年間の独学期間を経てアーティスへWebエンジニアとして入社。現在はWebエンジニアとして、主にシステムの開発・運用に従事している。
抽象的なもの、複雑なものを言語化して文章にするのが好きで得意。
この執筆者の最新記事
- 2024年10月8日WEBVue3でjQueryのdatepickerを使いたい!実装手順と注意点を解説します。
- 2024年8月21日WEBVue3の非同期コンポーネントを使ってみる
- 2024年5月28日WEBLaravel×Inertia×Vue3でファイルアップロード機能を作ってみた
- 2024年4月15日WEBLaravel×Inertia×Vue3でCRUD機能を持つSPAを作ってみた
関連記事
最新記事
FOLLOW US
最新の情報をお届けします
- facebookでフォロー
- Twitterでフォロー
- Feedlyでフォロー