Tutorial Laravel: Migrasi dan Relasi Model untuk RESTful API

Thumbnail Tutorial Laravel: Migrasi dan Relasi Model untuk RESTful API

Dalam pengembangan back-end seperti RESTful API sudah pasti sering terlibat dengan manajemen database, mengatur setiap keperluan pada database menggunakan aplikasi DBMS seperti phpMyAdmin terkadang terasa merepotkan karena mengharuskan kita untuk membuka aplikasinya secara berulang, balik ke kodingan terus buka lagi phpMyAdmin dan begitu seterusnya hingga keperluan terpenuhi.

Untungnya Laravel menyediakan fitur database migrations yang mempermudah pengelolaan database, sehingga kita dapat mengatur langsung dengan menggunakan beberapa baris kode saja, contohnya seperti mengatur tabel, kolom, hingga, mengatur relasi antar tabel juga dapat dilakukan. Selain itu, database migrations juga berfungsi sebagai version control layaknya git. Sehingga jika terjadi kesalahan, kita dapat mengembalikkan ke versi tertentu atau dikenal dengan istilah rollback.

Pada artikel ini saya akan memberikan contoh bagaimana cara mengatur tabel dan relasinya menggunakan database migrations di Laravel untuk RESTful API, dengan menggunakan studi kasus untuk memberikan response dalam bentuk JSON yang berisi kategori dan artikel terkait kategori tersebut.

Note: saya berasumsi bahwa teman-teman sudah menyiapkan proyek laravel dan sudah terkoneksi ke database.

1. Membuat Migration untuk Tabel categories dan articles

Langkah pertama adalah membuat file migration untuk kedua tabel yang akan kita gunakan, yaitu categories dan articles. Tabel categories akan memiliki kolom name saja, sedangkan tabel articles akan memiliki beberapa kolom seperti title, content, dan relasi ke kolom category_id.

Untuk membuat migration categories, jalankan perintah:

php artisan make:migration create_categories_table

Kemudian, bukalah folder migrations di dalam folder database yang ada di proyek aplikasi laravel yang kamu gunakan, akan terdapat sebuah file dengan nama kurang lebih seperti berikut:

xxx_create_categories_table.php

Nilai xxx merupakan waktu file tersebut dibuat.

Buka file itu, kemudian buatlah struktur tabel categories seperti di bawah ini dan pastikan dibuat dalam fungsi up(), yang berarti akan menaikkan atau menambahkan sesuatu.

public function up(): void
{
    Schema::create('categories', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->timestamps();
    });
}

Buat file migration articles dengan perintah:

php artisan make:migration create_articles_table

Kemudian, isi file migration articles dengan definisi tabel seperti pada kode berikut:

public function up(): void
{
    Schema::create('articles', function (Blueprint $table) {
        $table->id(); // kolom id
        $table->string('title'); // kolom title
        $table->text('content'); // kolom content
        $table->foreignId('category_id')->constrained()->onDelete('cascade'); // kolom category_id
        $table->timestamps(); // kolom created_at dan updated_at
    });
}

Dengan migrasi di atas, kita sudah mendefinisikan tabel articles yang berelasi dengan tabel categories melalui kolom category_id. Kita juga menggunakan foreignId untuk memastikan referensi antar tabel sesuai dengan aturan relational database yang baik, menggunakan fungsi constrained() untuk menghubungkannya ke kolom id pada tabel categories, dan fungsi onDelete('cascade') bertujuan untuk menentukan perilaku saat record di tabel utama dihapus, maka semua record yang bergantung padanya akan ikut terhapus, misalnya jika menghapus kategori anime maka semua artikel yang memiliki kategori anime akan ikut terhapus.

Baca juga: Cara Implementasi Auth JWT untuk RESTful API di Laravel.

2. Membuat Model Article dan Category

Setelah migrasi selesai, saatnya membuat model untuk kedua tabel tersebut, dan di setiap file model kita akan mendefinisikan relasinya juga. Mulai dengan membuat model Article dengan perintah berikut:

php artisan make:model Article

Kemudian, buka file Article.php pada folder Models yang ada pada folder app dan isikan seperti 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', 'category_id'];
    
    // relasi banyak artikel ke satu kategori
    public function category() {
        return $this->belongsTo(Category::class);
    }
}

Untuk model Category, jalankan perintah:

php artisan make:model Category

Buka file Category.php dan isikan dengan baris kode:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
    use HasFactory;
    protected $fillable = ['name'];
    
    // relasi satu kategori ke banyak artikel
    public function articles() {
        return $this->hasMany(Article::class);
    }
}

Dengan ini, model Category dan Article sudah saling terhubung melalui relasi satu ke banyak. Artinya, setiap kategori bisa memiliki banyak artikel, dan setiap artikel hanya berhubungan dengan satu kategori.

3. Menambah Data Dummy untuk Pengujian

Agar tidak perlu membuat data palsu manual untuk pengujiannya nanti, saya akan memanfaatkan fitur Seeder dan Faker untuk membuat data palsu atau dummy yang telah disediakan oleh Laravel. Untuk penjelasan mengenai Seeder silahkan baca artikel Tutorial Laravel: Membuat Seeder untuk RESTful API dengan Data Relasional.

a. Membuat Seeder untuk Article

Jalankan perintah berikut ini pada terminal:

php artisan make:seeder ArticleSeeder

Buka file ArticleSeeder.php yang terdapat pada folder seeders di folder database dan isi dengan kode berikut:

<?php

namespace Database\Seeders;

use App\Models\Article;
use App\Models\Category;
use Illuminate\Database\Seeder;

class ArticleSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        $categoriesId = Category::all()->pluck('id')->flatten()->toArray();
        $maxArticles = 10;
        $articles = [];
        
        for ($i = 0; $i < $maxArticles; $i++) {
	    $randomCategoryId = $categoriesId[array_rand($categoriesId)];
            array_push($articles, [
                'title' => fake()->words(10, true),
                'content' => fake()->paragraphs(10, 20),
                'category_id' => $randomCategoryId,
                'created_at' => now(),
                'updated_at' => now()
            ]);
        }
        
        // insert ke tabel articles
        Article::insert($articles);
    }
}

b. Membuat Seeder untuk Category

Jalankan perintah berikut:

php artisan make:seeder CategorySeeder

Buka file CategorySeeder.php, kemudian isi dengan kode seperti berikut:

<?php

namespace Database\Seeders;

use App\Models\Category;
use Illuminate\Database\Seeder;

class CategorySeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        $categories = [
            [
                'name' => 'Anime',
                'created_at' => now(),
                'updated_at' => now()
            ],
            [
                'name' => 'Game',
                'created_at' => now(),
                'updated_at' => now()
            ],
            [
                'name' => 'Pemrograman',
                'created_at' => now(),
                'updated_at' => now()
            ]
        ];
        
        Category::insert($categories);
    }
}

Langkah terakhir untuk bagian ini adalah memastikan keduanya dipanggil pada file DatabaseSeeder.php agar dapat dijalankan melalui terminal dengan mudah. Buka file DatabaseSeeder.php dan isi seperti berikut:

<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     */
    public function run(): void
    {
        $this->call([
            CategorySeeder::class, // pastikan category terlebih dahulu
            ArticleSeeder::class,
        ]);
    }
}

Data dummy siap diisikan ke tabel articles dan categories, akan kita eksekusi setelah menyelesaikan dua langkah lagi.

4. Menyediakan API untuk Mengakses Data

Sekarang, kita akan membuat controller untuk menangani permintaan terhadap API. Buat controller untuk mengelola data Category dengan perintah:

php artisan make:controller Api/CategoryController

Di dalam CategoryController.php, buatlah metode untuk mendapatkan data Category beserta Article-nya dan juga metode untuk menghapus kategori tertentu berdasarkan id-nya.

<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Category;

class CategoryController extends Controller
{
    public function index() {
        $categories = Category::with('articles')->get();
        return response()->json($categories);
    }
    
    public function show($id) {
        $category = Category::with('articles')->findOrFail($id);
        return response()->json($category);
    }
    
    public function destroy($id) {
        $category = Category::findOrFail($id);
        $category->delete(); // menghapus category beserta articles terkait
        return response()->json([
            'message' => 'Category and related articles deleted successfully'
        ]);
    }
}

Dengan adanya metode index() dan show(), kita dapat mengakses semua kategori beserta setiap artikelnya, atau satu kategori dengan artikelnya. Metode destroy() digunakan untuk menghapus kategori berdasarkan id beserta artikel terkait kategori tersebut.

5. Menambahkan Routes API

Jika kamu menggunakan Laravel 11, maka untuk memunculkan routes yang diatur khusus untuk API harus menjalankan perintah berikut:

php artisan install:api

Jika muncul pertanyaan untuk menjalankan migrasi database, pilih tidak, karena saya ingin menjalankannya diakhir dengan perintah khusus untuk migrasi saja.

Kemudian buka file api.php yang ada dalam folder routes dan tambahkan tiga rute berikut:

Route::get('/categories', [CategoryController::class, 'index']);
Route::get('/categories/{id}', [CategoryController::class, 'show']);
Route::delete('/categories/{id}', [CategoryController::class, 'destroy']);

Ketiga rute di atas dibuat untuk mengapatkan semua kategori, satu kategori, dan menghapus satu kategori, nantinya setiap rute tersebut akan diuji menggunakan aplikasi untuk simulasi penggunaan API agar lebih mudah.

6. Menjalankan Migrasi, Seeder, dan Aplikasi

Akhirnya sampailah pada tahap terakhir, untuk menjalankan migrasi gunakan perintah:

php artisan migrate

Untuk menjalankan Seeder gunakan:

php artisan db:seed

Terakhir, jalankan aplikasi Laravel yang baru saja dibuat dengan perintah:

php artisan serve

7. Pengujian API

Kamu bisa menguji API ini menggunakan aplikasi simulasi API di sisi client seperti Postman atau HTTPie. Cukup buat permintaan GET ke endpoint /api/categories atau /api/categories/{id} untuk mendapatkan data JSON yang mencakup kategori dan artikel terkaitnya. Gunakan permintaan DELETE ke endpoint /api/categories/{id} untuk menghapus kategori tertentu beserta artikelnya.

Berikut adalah gambar hasil pengujian saya menggunakan HTTPie:

Hasil untuk endpoint /api/categories dengan method GET
Hasil untuk endpoint /api/categories/{id} dengan method GET
Hasil untuk endpoint /api/categories/{id} dengan method DELETE

Kesimpulan

Membuat migration dan relasi model untuk RESTful API di Laravel menjadi mudah dengan menggunakan fitur relasi antar tabel. Dalam contoh ini, kita telah membuat dua tabel, categories dan articles, yang saling berhubungan. Selain itu, kita juga telah membangun Seeder untuk mengelola data dummy dan controller untuk menampilkan dan menghapus data yang memiliki relasi antar model tersebut. Dengan API yang sudah terstruktur dengan baik, kamu diharapkan bisa mengembangkan aplikasi lebih lanjut menggunakan Laravel.

Terima kasih telah berkunjung, mohon maaf bila terdapat kekurangan, jika ingin menambahkan atau mengoreksi yang telah ada, silahkan tulis di kolom komentar. Begitu juga jika ada pertanyaan, tapi mungkin saya tidak bisa memberikan jawaban secara maksimal, karena bagaimana pun saya sendiri masih belajar dan belum punya banyak pengalaman.

Sumber: Laravel Database Migrations, Laravel Database Seeder, Laravel Eloquent Relationship.