Tutorial Laravel: Membuat Seeder untuk RESTful API

Thumbnail Tutorial Laravel: Membuat Seeder untuk RESTful API

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:

Hasil dalam bentuk JSON untuk data yang dibuat menggunakan seeder di Laravel untuk RESTful API

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.