Tutorial Laravel: CRUD RESTful API Sederhana untuk Pemula

Thumbnail Tutorial Laravel: CRUD RESTful API Sederhana untuk Pemula

Pada kesempatan ini kita akan belajar cara membuat RESTful API sederhana untuk pemula atau untuk teman-teman yang baru mengenal Laravel, jadi tujuan utamanya adalah membuat RESTful API sesuai dengan ketentuan dasar, tapi tanpa memperhatikan best practice pada sisi kodingan. Emang apa saja ketentuan dasar yang ditetapkan agar API dikatakan sebagai RESTful? Nah, mari kita simak sekilas pembahasannya terlebih dahulu.

Apa itu RESTful API?

RESTful API singkatnya adalah cara bagi aplikasi berbeda untuk saling berbicara melalui internet menggunakan aturan tertentu. Bayangkan kamu memesan makanan di restoran. Kamu (klien) memberikan daftar pesanan ke pelayan (API). Pelayan ini tidak memasak makanan, tapi dia membawa pesananmu ke dapur (server) dan kembali dengan makanan yang kamu pesan. Pelayan ini bekerja dengan aturan yang jelas—dia hanya akan melayani jika pesananmu lengkap dan sesuai menu. Sama seperti itu, RESTful API membantu aplikasi bertukar data dengan aturan sederhana seperti "gunakan alamat tertentu (URL)" dan "pakai metode tertentu (GET, POST, dll.)" untuk melakukan permintaan.

Berdasarkan pada penjelasan di atas, maka terdapat beberapa ketentuan atau prinsip dasar untuk membangun RESTful API, yaitu:

  1. Stateless, setiap permintaan dari klien ke server haruslah mandiri, alias tidak bergantung pada permintaan sebelumnya. Bayangkan kamu pergi ke toko dan setiap kali bertemu kasir, kamu harus menjelaskan siapa kamu dan apa yang kamu beli, meskipun ini bukan pertama kalinya kamu datang. Kasir (server) tidak mengingat interaksi sebelumnya, jadi setiap transaksi baru dianggap terpisah. Ini membuat sistem lebih sederhana dan mudah dikelola, karena server tidak perlu menyimpan informasi tambahan tentang klien.

  2. Uniform Interface, yaitu memastikan semua interaksi antara klien dan server mengikuti aturan yang sama. Misalnya, bayangkan sebuah lemari buku dengan label di setiap rak (URI) untuk mengidentifikasi buku tertentu. Kamu bisa meminta buku (GET), menambahkan buku baru (POST), mengganti buku yang ada (PUT/PATCH), atau menghapus buku (DELETE). Apa pun rak yang kamu pilih, caranya selalu sama. Dengan aturan ini, klien tahu persis bagaimana berinteraksi dengan resource di server tanpa kebingungan.

  3. Layered System, misalnya, ketika kamu mengambil buku dari lemari, kamu mungkin tidak sadar bahwa ada lapisan kaca atau pengaman tambahan di depannya. Selama kamu tetap bisa mengambil buku (resource) dengan cara yang sama, lapisan-lapisan tersebut tidak memengaruhi pengalamanmu. Ini membuat API lebih fleksibel dan aman, karena lapisan seperti cache atau gateway bisa ditambahkan tanpa mengubah cara klien berinteraksi.

  4. Cacheable, artinya respons dari server bisa disimpan sementara (di-cache) untuk digunakan lagi tanpa harus selalu meminta ulang. Bayangkan kamu sering mengambil buku dari lemari yang sama. Daripada bolak-balik ke lemari, kamu bisa menyimpan buku itu di meja (cache) untuk akses cepat. Selama buku itu tidak berubah, kamu bisa membacanya dari meja tanpa perlu membuka lemari lagi. Ini membantu menghemat waktu dan mempercepat proses. Ketentuan ini bersifat opsional, tetapi akan bagus jika diterapkan.

Empat ketentuan dasar di atas merupakan hasil yang saya ringkas dan diambil secara garis besarnya saja, jika teman-teman merasa ada yang kurang, mohon dimaafkan dan silahkan koreksi pada kolom komentar.

Cara Membuat RESTful API di Laravel

Pada tutorial cara membuat RESTful API sederhana ini saya akan membawa analogi rak buku, dimana kita bisa menambahkan buku, mengambil, mengganti, hingga membuang/menghapus buku (CRUD). Kemudian rak tersebut akan saya beri label "books", label ini adalah Uniform Resource Identifier (URI), yang baiknya ditulis dalam bentuk jamak karena biasanya merepresentasikan kumpulan resource, dalam hal ini berarti kumpulan buku.

1. Menyiapkan Proyek Laravel

Langkah pertama, tentu saja menyiapkan proyek Laravel dengan menggunakan perintah:

composer create-project --prefer-dist laravel/laravel bookshelf-api

Konfigurasi database masing-masing untuk latihan, berikut adalah konfigurasi database milik saya:

DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=latihan
DB_USERNAME=postgres
DB_PASSWORD=root

Jangan lupa juga siapkan aplikasi untuk simulasi pengujian RESTful API pada sisi klien dengan menggunakan aplikasi seperti Postman atau HTTPie agar lebih mudah. Kalau kamu suka tantangan, silahkan dicoba menggunakan terminal seperti CMD dan mengujinya menggunakan curl.

2. Membuat Migrasi dan Model

Pada langkah ini adalah menyiapkan tabel dan juga model agar bisa menggunakan fitur Eloquent milik Laravel, sehingga kita tidak perlu membuat query SQL secara mentah. Jalankan perintah di bawah untuk membuat migrasi dan model dengan nama Book sekaligus:

php artisan make:model Book -m

Flag -m digunakan untuk membuat file migrasi dari model yang dibuat. Nah, tahu gak sih kalau di Laravel kita bisa membuat tabel yang saling berelasi/berhubungan dengan mudah? kalau kamu penasaran bisa cek artikel Tutorial Laravel: Membuat Migrasi dan Relasi Model.

Kemudian, bukalah file migrasi books dan sesuaikan dengan kode seperti milik saya:

public function up(): void
{
    Schema::create('books', function (Blueprint $table) {
        $table->id();
        $table->string('title');
        $table->string('author');
        $table->string('description');
        $table->timestamps();
    });
}

Jangan lupa jalankan file migrasi tersebut.

php artisan migrate

Pada kode di atas, saya akan membuat tabel di database bernama books dengan kolom id, title, author, description.

Berikutnya, bukalah model Book dan sesuaikan dengan kode berikut:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Book extends Model
{
    protected $fillable = ['title', 'author', 'description'];
}

Perhatikan variabel $fillable, nilai yang ada dalam variabel tersebut adalah setiap kolom pada tabel atau atribut model yang dapat diisi atau diubah, bahasa kerennya adalah Mass Assignment. Pada kode di atas, saya mengizinkan perubahan pada kolom title, author, dan description.

3. Membuat Controller

Agar operasi menambah, mengambil, mengganti, dan menghapus buku berjalan maka kita memerlukan metode atau fungsi yang ada dalam class untuk mengontrol setiap aksi yang dilakukan terhadap buku dalam rak. Buatlah controller dengan nama BookController:

php artisan make:controller BookController

Bukalah file BookController.php dan sesuaikan dengan kode milik saya berikut ini:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

// model
use App\Models\Book;

class BookController extends Controller
{
    // list buku
    public function index() {
        $books = Book::all();
        return response()->json([
            'status' => 'success',
            'data' => [
                'books' => $books
            ]
        ], 200);
    }
    
    // mengambil satu buku berdasarkan id
    public function show($id) {
        $book = Book::find($id);
        
        if ($book) {
            return response()->json([
                'status' => 'success',
                'data' => $book
            ], 200);
        }
        
        return response()->json([
            'status' => 'fail',
            'message' => 'Buku tidak ditemukan'
        ], 404);
    }
    
    // menambahkan buku
    public function store(Request $request) {
        // validasi input
        $validated = Validator::make($request->all(), [
            'title' => 'required|string',
            'author' => 'required|string',
            'description' => 'required|string'
        ]);
        
        if ($validated->fails()) {
            return response()->json([
                'status' => 'fail',
                'message' => 'Error Validasi',
                'data' => $validated->errors()
            ], 422);
        }
        
        Book::create([
            'title' => $request->title,
            'author' => $request->author,
            'description' => $request->description
        ]);
        
        return response()->json([
            'status' => 'success',
            'message' => 'Buku berhasil ditambahkan'
        ], 201);
    }
    
    // mengubah buku
    public function update(Request $request, $id) {
        $book = Book::find($id);
        
        if ($book) {
            // validasi input
            $validated = Validator::make($request->all(), [
                'title' => 'required|string',
                'author' => 'required|string',
                'description' => 'required|string'
            ]);
            
            if ($validated->fails()) {
                return response()->json([
                    'status' => 'fail',
                    'message' => 'Error Validasi',
                    'data' => $validated->errors()
                ], 422);
            }
            
            $book->update([
                'title' => $request->title,
                'author' => $request->author,
                'description' => $request->description
            ]);
            
            return response()->json([
                'status' => 'success',
                'message' => 'Buku berhasil diperbarui'
            ], 200);
        }
        
        return response()->json([
            'status' => 'fail',
            'message' => 'Buku tidak ditemukan'
        ], 404);
    }
    
    // menghapus buku
    public function destroy($id) {
        $book = Book::find($id);
        
        if ($book) {
            $book->delete();
            return response()->json([
                'status' => 'success',
                'message' => 'Buku berhasil dihapus'
            ], 200);
        }
        
        return response()->json([
            'status' => 'fail',
            'message' => 'Buku tidak ditemukan'
        ], 404);
    }
}

Penggunaan return response()->json() pada setiap metode yang ada dalam kode di atas adalah untuk memastikan data dikembalikan dalam format JSON dengan header HTTP yang tepat. Ini penting untuk RESTful API karena klien, seperti aplikasi web atau mobile, biasanya mengharapkan respons dalam format JSON. Selain itu, metode ini memudahkan kita menambahkan status kode HTTP yang tepat, sehingga memberikan kontrol lebih baik atas struktur respons.

Berbicara mengenai status kode HTTP dalam respons RESTful API itu sangatlah penting, gunakan statis kode yang sesuai dengan standar HTTP untuk setiap respons yang ada. Misalnya, jika respons-nya berhasil, seperti data bisa diambil maka berikan status kode 200, jika terjadi error akibat kesalah klien maka berikan status kode direntang 400, dan terjadi kesalahan pada sisi server berikanlah status kode dalam rentang 500. Selengkapnya mengenai status kode HTTP bisa teman-teman pelajari di https://developer.mozilla.org/en-US/docs/Web/HTTP/Status.

4. Membuat URI

Pada tahap inilah kita akan membuat URI, mudahnya URI digunakan untuk menunjuk ke sumber daya tertentu, di dalam sumber daya tersebut terdapat beberapa aksi yang dapat dilakukan. Pada tutorial ini, sumber daya tersebut adalah books, dan ke sumber daya tersebut klien dapat melakukan 4 aksi, yaitu menambah (POST), mengambil (GET), mengganti (PUT), dan menghapus (DELETE).

Ingat gunakanlah verb yang sesuai standar HTTP untuk setiap sumber daya yang dibuat, seperti GET untuk mengambil data dan selengkapnya bisa pelajari di https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods.

Apabila teman-teman membuat RESTful API di Laravel 11, maka jalankan terlebih dahulu perintah berikut agar file rute khusus untuk api muncul. Jika nanti muncul pertanyaan untuk migrasi, pilih saja tidak.

php artisan install:api

Saya akan memberikan dua cara untuk membuat sumber daya yang dapat diakses oleh klien, pilih saja salah satu yang kamu suka. Kode pada kedua cara ini disimpan pada file api.php.

Cara pertama, menggunakan fungsi apiResource() yang telah disediakan oleh Laravel. Dengan menggunakan apiResource(), kamu tidak perlu lagi mendefinisikan setiap rute berserta aksinya.

Route::apiResource('/books', App\Http\Controllers\BookController::class);

Cukup gunakan satu baris kode dan sudah mengcover rute untuk GET, POST, PUT, dan DELETE, sisanya tinggal menyesuaikan nama method yang ada pada BookController. Untuk melihat list rutenya jalankan perintah di bawah ini pada terminal:

php artisan route:list

Cara kedua, membuat setiap rute beserta jenis aksinya secara manual. Memang cukup ribet, tapi kamu tidak perlu mengintip lewat terminal untuk mengetahui setiap sumber daya.

Route::controller(App\Http\Controllers\BookController::class)
->prefix('books')
->group(function () {
    Route::post('', 'store');
    Route::get('', 'index');
    Route::get('/{id}', 'show');
    Route::put('/{id}', 'update');
    Route::delete('/{id}', 'destroy');
});

Simpan dan jalankan.

php artisan serve

Sekarang, saatnya kita melihat hasilnya dengan melakukan pengujian pada setiap rute/endpoint yang tersedia pada aplikasi RESTful API dengan CRUD sederhana ini.

5. Pengujian dan Hasil

Untuk pengujian ini saya menggunakan aplikasi HTTPie. Pengujian pertama, mari kita coba untuk menambah buku, kirimkan permintaan POST ke endpoint /books dengan menyertakan data berikut dalam format JSON.

{
"title": "Real Face",
"author": "Chinen Mikito",
"description": "Novel misteri dengan pemeran utama ahli anestesi dari Jepang"
}
Hasil pengujian untuk permintaan POST untuk menambahkan buku

Pengujian kedua, saya menyarankan untuk menambah satu buku lagi yang berbeda, kemudian kirimkan permintaan GET ke endpoint /books dan hasilnya seperti gambar:

Hasil pengujian untuk permintaan GET untuk melihat semua buku

Pengujian ketiga, kirimkan permintaan GET ke endpoint /books/1 untuk melihat detail buku dengan id bernilai satu.

Hasil pengujian untuk permintaan GET yang memiliki parameter id

Pengujian keempat, kirimkan permintaan PUT ke endpoint /books/2 untuk mengubah nilai yang ada pada buku dengan id bernilai dua. Misalnya, saya akan mengubah nilai buku kedua yang sudah saya tambahkan.

{
"title": "Buku Kematian",
"author": "Tsugumi Ohba",
"description": "Manga shounen supernatural dan psychological dari Jepang"
}

Untuk melihat hasilnya, silahkan mengirimkan permintaan PUT dan jika respons-nya berhasil, maka jalankan pengujian ketiga.

Hasil pengujian untuk permintaan PUT

Pengujian kelima, kirimkan permintaan DELETE ke endpoint /books/2 untuk menghapus buku dengan id bernilai dua. Kemudian, jalankan pengujian kedua untuk melihat hasilnya.

Hasil pengujian untuk permintaan DELETE

Demikianlah tutorial cara membuat RESTful API sederhana untuk Laravel. Untuk melihat kode Laravel ini secara keseluruhan, teman-teman dapat mengunjunginya di alamat GitHub: https://github.com/kodefiksi/restful-api-laravel-pemula.

Kesimpulan

Membuat RESTful API dengan Laravel adalah langkah awal yang tepat untuk memulai belajar back-end. Dalam tutorial ini, kita telah mempelajari bagaimana mengimplementasikan operasi CRUD Sederhana pada aplikasi RESTful API dengan menerapkan prinsip dasarnya, dan menggunakan standar HTTP verbs. Tidak hanya itu, kita juga belajar memberikan respons dalam bentuk JSON dengan status kode HTTP yang sesuai.

Untuk meningkatkan keamanan, penerapan JWT sebagai metode otentikasi dapat dipertimbangkan, sehingga akses ke API menjadi lebih terkontrol. Selain itu, penggunaan seeder sangat berguna dalam proses pengujian, karena memungkinkan kita untuk mengisi database dengan data dummy dengan cepat. Terakhir, penambahan slug untuk setiap resource seperti buku bisa mempermudah identifikasi dan meningkatkan pengalaman pengguna dalam mengakses data melalui URI yang lebih ramah sehingga tidak lagi menggunakan nilai id.