Dalam pengembangan RESTful API terkadang memerlukan data yang realistis dan saling berelasi untuk pengujian. Laravel menyediakan fitur database seeder yang dapat menjadi solusi untuk menghasilkan data palsu yang mirip dengan data asli secara otomatis. Artikel ini akan membahas cara membuat seeder dengan data relasional, seperti relasi antara tabel users
, articles
, dan comments
.
Apa Itu Seeder dalam Laravel?
Fitur Database Seeder yang ada di Laravel adalah class
yang digunakan untuk mengisi data awal ke database yang dapat digunakan berulang kali sehingga tidak perlu repot mengisi data secara manual. Fungsi seeder pada Laravel utamanya digunakan selama masa pengembangan untuk memudahkan pembuatan data palsu. Dalam konteks RESTful API, seeder dapat membantu menghasilkan data yang menyerupai produksi seperti data yang saling berelasi.
Penggunaan seeder di Laravel biasanya berkaitan juga dengan migrations
untuk mengatur struktur database, serta factory
dan faker
sebagai pabrik untuk membuat data-nya.
Tutorial Membuat Seeder untuk RESTful API
Pada tutorial ini saya akan membuat seeder dengan data yang saling berelasi untuk tabel users
, articles
, dan comments
. Dengan definisi relasi antar tabelnya adalah sebagai berikut:
- Satu user dapat memiliki banyak artikel (
hasMany
). - Satu artikel dapat memiliki banyak komentar (
hasMany
). - Satu komentar memiliki satu user dan satu artikel (
belongsTo
).
Sebelum lanjut, siapkan terlebih dahulu proyek Laravel yang telah terkoneksi ke database untuk latihan dan secangkir kopi untuk menemani setiap langkah yang ada pada tutorial ini.
1. Membuat File Migrasi
Agar pengelolaan struktur database lebih mudah, saya akan menggunakan fitur migrations untuk tabel users
, articles
, dan comments
. Pembahasan mengenai migrations bisa teman-teman simak di artikel Tutorial Laravel: Migrasi dan Relasi Model untuk RESTful API dengan Studi Kasus.
Jalankan satu per satu perintah di bawah ini untuk membuat file migrasi ketiga tabel tadi:
php artisan make:migration create_articles_table
php artisan make:migration create_comments_table
Migrasi untuk tabel users
mana bang?
Untuk tabel users
sudah dibuatkan oleh Laravelnya ya.
Buka file xxx_create_articles_table.php
dan pada fungsi up()
isikan baris kode berikut untuk mendefinisikan tabel yang akan dibuat:
Schema::create('articles', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('content');
$table->foreignId('user_id')->constrained()->onDelete('cascade');
$table->timestamps();
});
Isikan juga kode berikut ke file migrasi untuk tabel comments
:
Schema::create('comments', function (Blueprint $table) {
$table->id();
$table->text('comment');
$table->foreignId('user_id')->constrained()->onDelete('cascade');
$table->foreignId('article_id')->constrained()->onDelete('cascade');
$table->timestamps();
});
2. Membuat File Model
Buatlah model untuk tabel articles
dan comments
untuk memudahkan interaksi dengan database, jalankan perintah berikut:
php artisan make:model Article
php artisan make:model Comment
Kemudian, definisikan relasi antar tabel. Pertama, buka model Article.php
dan sesuaikan isinya seperti kode berikut:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Article extends Model
{
use HasFactory;
protected $fillable = ['title', 'content', 'user_id'];
// relasi banyak artikel ke satu user
public function user() {
return $this->belongsTo(User::class);
}
// relasi satu artikel ke banyak komentar
public function comments() {
return $this->hasMany(Comment::class);
}
}
Sesuaikan juga kode pada model Comment.php
:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
use HasFactory;
protected $fillable = ['comment', 'user_id', 'article_id'];
// relasi banyak ke satu artikel
public function article() {
return $this->belongsTo(Article::class);
}
// relasi banyak ke satu user
public function user() {
return $this->belongsTo(User::class);
}
}
3. Membuat File Factory
Pada file factory inilah kita membuat data palsu yang dibantu menggunakan faker
, seharusnya User
telah memiliki file ini. Maka, sisanya adalah membuat file factory untuk Article
dan Comment
.
php artisan make:factory ArticleFactory --model=Article
php artisan make:factory CommentFactory --model=Comment
Buka file ArticleFactory.php
dan sesuaikan dengan kode di bawah ini:
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Article>
*/
class ArticleFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'title' => fake()->words(5, true),
'content' => fake()->paragraphs(6, true),
'user_id' => null // akan diisi melalui seeder
];
}
}
Begitu pun dengan file CommentFactory.php
:
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Comment>
*/
class CommentFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'comment' => fake()->words(6, true),
'user_id' => null, // akan diisi melalui seeder
'article_id' => null // akan diisi melalui seeder
];
}
}
4. Membuat File Seeder
Agar data yang digenerate oleh file factory di atas bisa tertanam ke database, maka diperlukan file seeder. File ini akan bertugas untuk menentukan jumlah record yang dibuat, kemudian dimasukkan ke masing-masing tabel yang sesuai.
Buatlah satu file seeder untuk tabel comments
.
php artisan make:seeder CommentSeeder
Kenapa hanya seeder untuk tabel comments
saja?
Hal ini dikarenakan data users
dan articles
memiliki relasi dengan comments
. Nantinya, logika pembuatan data users
dan articles
dapat digabungkan dalam satu file seeder.
Buka file CommentSeeder.php
, kemudian sesuaikan dengan kode berikut:
<?php
namespace Database\Seeders;
use App\Models\User;
use App\Models\Article;
use App\Models\Comment;
use Illuminate\Database\Seeder;
class CommentSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
// membuat 10 user
$users = User::factory(10)->create();
$users->each(function ($user) use ($users) {
// membuat 3 artikel untuk setiap user
$articles = Article::factory(3)->create(['user_id' => $user->id]);
// menambahkan 5 komentar ke setiap artikel
$articles->each(function ($article) use ($users) {
// setiap artikel memiliki 5 komentar
Comment::factory(5)->create([
'user_id' => $users->random()->id, // komentar oleh user acak
'article_id' => $article->id
]);
});
});
}
}
Kemudian, buka file DatabaseSeeder.php
dan edit seperti:
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*/
public function run(): void
{
$this->call([
CommentSeeder::class
]);
}
}
Perubahan yang dilakukan pada file DatabaseSeeder.php
bertujuan agar seeder dapat dijalankan dengan satu perintah bersamaan dengan perintah migrasi.
Sekarang, coba jalankan perintah di bawah dan lihat hasilnya di database yang kamu gunakan:
php artisan migrate --seed
Seharusnya jika kamu mengikuti setiap tahapan di atas dengan baik dan benar, tidak ada error yang muncul. Karena ya di komputer saya jalan (khas banget, wkwk).
Selanjutnya, mungkin muncul pertanyaan bagaimana menampilkan data yang telah dibuat oleh seeder tadi dalam bentuk JSON
, karena tujuan awalnya adalah membuat seeder untuk RESTful API. Maka kita memerlukan controller dan endpoints (routes
).
5. Membuat Controller dan Routes
Saya akan membuat satu controller saja dengan nama ArticleController
, jalankan perintah:
php artisan make:controller Api/ArticleController
Sesuaikan isi file ArticleController.php
seperti kode berikut:
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Models\Article;
class ArticleController extends Controller
{
public function index() {
// mendapatkan semua article beserta user dan komentarnya
$articles = Article::with(['user', 'comments.user' => function ($query) {
$query->select('id', 'name');
}])->get();
return response()->json($articles);
}
public function show($id) {
// mendapatkan satu artikel dengan user dan komentarnya
$article = Article::with(['user', 'comments.user' => function ($query) {
$query->select('id', 'name');
}])->findOrFail($id);
return response()->json($article);
}
}
Jika menggunakan Laravel 11, install routes
untuk api dengan perintah:
php artisan install:api
Apabila muncul pertanyaan untuk menjalankan migrasi, pilih saja tidak. Karena kita sudah melakukan hal tersebut pada tahap sebelumnya.
Kemudian, sesuaikan kode untuk routes
pada file api.php
:
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Api\ArticleController;
Route::get('/articles', [ArticleController::class, 'index']);
Route::get('/articles/{id}', [ArticleController::class, 'show']);
Hasil dan Kesimpulan
Untuk melihat hasilnya, jangan lupa simpan semua perubahan yang telah dilakukan kemudian jalankan proyek Laravel tersebut.
php artisan serve
Setelah berjalan, kamu bisa mencobanya dengan mengirimkan permintaan GET
ke endpoint /api/articles
atau /api/articles/{id}
menggunakan aplikasi simulasi API client seperti HTTPie. Berikut adalah hasil milik saya:
Kesimpulannya, membuat database seeder di Laravel adalah langkah penting untuk menghasilkan data dummy yang realistis dan saling berelasi, terutama saat mengembangkan RESTful API. Dengan memanfaatkan fitur bawaan Laravel seperti migrations, factories, dan seeders, pengelolaan data menjadi lebih mudah. Dalam tutorial ini, kita telah berhasil membuat data users
, articles
, dan comments
yang berelasi, serta menampilkannya dalam format JSON
menggunakan controller dan endpoint API.
Perhatikanlah endpoint /api/articles/{id}
, saat ini untuk mendapatkan detail dari satu artikel tertentu masih menggunakan primary key
, yang mana hal tersebut tidaklah baik dan sulid terbaca, apalagi jika berbicara mengenai SEO tentu tidaklah direkomendasikan. Solusi untuk mengatasi hal tersebut adalah dengan membuat slug, yaitu teks pendek yang biasanya digunakan dalam url dan merupakan versi judul artikel yang disederhanakan dengan mengubah karakter khusus seperti spasi dengan tanda hubung (-). Pada tutorial berikutnya, kita akan membahas cara membuat slug di Laravel.
Sumber: Laravel Documentation.