Pada tutorial kali ini, kita akan mempelajari tentang pembuatan RESTful API di Laravel 11, untuk pemula. Tutorial ini akan menerangkan langkah-langkah awal menginstall Laravel 11 hingga pengujian API yang telah dibuat. Selama proses pembuatan API, kita juga akan belajar cara mengupload gambar di Laravel 11. Selain itu, kita akan memanfaatkan fitur bawaan Laravel yang dikenal sebagai API Resources. Dengan menggunakan fitur ini, kita dapat dengan mudah dan cepat menampilkan data dari model ke format JSON.
Membuat Project Laravel 11
Tahapan awal yang perlu dilakukan adalah menginstal Composer pada komputer. Untuk menginstal Composer, kalian dapat mengikuti panduan yang disediakan oleh situs resminya di sini.
Jika composer telah terinstall, maka kita dapat membuat sebuah projek laravel baru dengan menggunakan perintah berikut pada terminal/CMD.
composer create-project --prefer-dist laravel/laravel:^11.0 laravel11-restapi
Dalam beberapa kasus, instalasi laravel 11 akan gagal dan menampilkan error seperti berikut.

Hal ini disebabkan karena secara default, laravel 11 menggunakan sqlite sebagai driver database default. Untuk menghilangkan error ini, bisa dengan mengaktifkan ekstensi pdo_sqlite pada php nya. Jika ekstensi pdo_sqlite pada php sudah diaktifkan, maka proses instalasi tidak akan error. Kalian juga bisa mengabaikan error ini karena nanti kita akan menggunakan mysql sebagai dirver database nya.

Sekarang kita dapat masuk ke dalam folder project dan menjalankan project laravel 11 yang baru kita install.
cd laravel11-restapi
php artisan servePerintah tersebut digunakan untuk menjalankan server local Laravel. Jika berhasil, proyek kita akan berjalan di localhost dengan port 8000. Kalian dapat membukanya di browser dengan mengetikkan http://localhost:8000. Jika berhasil, akan ditampilkan hasil seperti berikut ini.


Menjalankan Storange Link
Karena kita akan mengupload gambar, maka kita perlu menjalankan perintah storage:link di Laravel. Hal ini kita lakukan agar nantinya kita dapat mengakses file yang telah kita upload pada Projek Laravel. Silahkan mengetik perintah berikut pada terminal/CMD dan pastikan kalian berada pada folder projek laravel.
php artisan storage:link
Membuat Model dan Migration
Untuk membuat file Model dan Migration. kita dapat menjalankan perintah berikut pada terminal/CMD.
php artisan make:model Post -mJika berhasil, maka akan ada 2 file baru pada folder Model dan Migration.
- app/Models/Post.php
- database/migrations/ xxx_xx_xx_xxxxxx_create_posts_table.php
untuk nama file migration akan random sesuai waktu pembuatannya.
Kemudian kita dapat mengubah file migration untuk menambahkan Field / Kolom pada method up.
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->string('image');
$table->text('content');
$table->timestamps();
});
}
Kita sudah menambahkan 3 field baru di dalam file migration, yaitu title, image, dan content. Berikut ini detailnya.
| Field | Type Data | Keterangan |
title | String | untuk menyimpan judul post. |
image | String | untuk menyimpan nama gambar yang di upload. |
content | Text | untuk menyimpan isi post. |
Kita juga perlu mengubah file Model, agar field yang telah kita tambahkan dapat menyimpan nilai ke dalam database. Silahkan buka file app/Models/Post.php dan tambahkan kode berikut.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use HasFactory;
/**
* fillable
*
* @var array
*/
protected $fillable = [
'image',
'title',
'content',
];
/**
* image
*
* @return Attribute
*/
protected function image(): Attribute
{
return Attribute::make(
get: fn ($image) => url('/storage/posts/' . $image),
);
}
}Pada kode di atas, kita menambahkan properti baru dengan nama $fillable. properti tersebut disebut dengan Mass Assignment dan di dalamnya berisikan fields yang sesuai di dalam file migration.
Kita juga membuat method baru dengan nama image(). Hal ini disebut Accessor yang memungkinkan kita untuk mengubah nilai pada field. Dalam method ini, kita mengembalikan field image untuk menghasilkan URL lengkap dari folder storage. Jadi, saat kita memanggil field image, outputnya akan otomatis seperti ini:
http://localhost:8000/storage/posts/nama-file.png
Kemudian kita harus melakukan konfigurasi database mysql. Silahkan buka file .env , kemudian tambahkan kode berikut ini.
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel11-restapi
DB_USERNAME=root
DB_PASSWORD=
DB_COLLATION=utf8mb4_unicode_ci
SESSION_DRIVER=database
SESSION_LIFETIME=120Setelah semua berhasil dibuat, berikutnya kita dapat menjalankan perintah migrate. Dengan menjalankan perintah ini, maka database beserta tabel dan juga field-nya akan digenerate.
Silahkan jalankan perintah berikut ini di dalam terminal/CMD di dalam project Laravel-nya.
php artisan migrateJika muncul pertanyaan seperti ini, maka silahkan pilih Yes dan tekan Enter.

Membuat API Resources
Selanjutnya kita akan membuat API resources. Tujuan dari API Resources ini adalah untuk mengonversi data dari Model ke dalam format JSON sesuai kebutuhan, termasuk penambahan informasi status dan pesan yang akan ditampilkan.
Silahkan jalankan perintah berikut ini di dalam terminal/CMD di dalam project Laravel-nya.
php artisan make:resource ApiResourcePerintah di atas akan membuat sebuah file baru pada folder app/Http/Resources/ApiResource.php. Silahkan membuka file tersebut dan rubah semua kode nya menjadi seperti berikut ini:
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class ApiResource extends JsonResource
{
/**
* __construct
*
* @param mixed $status
* @param mixed $message
* @param mixed $data
* @return void
*/
public function __construct(public $status, public $message, public $data){ }
/**
* toArray
*
* @param mixed $request
* @return array
*/
public function toArray(Request $request): array
{
return [
'status' => $this->status,
'message' => $this->message,
'data' => $this->data
];
}
}
Dari perubahan kode di atas, pertama-tama, kita membuat method _construct yang menerima 3 parameter: $status, $message, dan $data, yang akan digunakan untuk menginisialisasi nilai dari properti $status dan $message sesuai dengan nilai yang diberikan oleh Controller.
Setelah itu, di dalam method toArray, kita mengubah bagian return-nya agar menghasilkan format JSON yang sesuai dengan kebutuhan. ApiResource ini dapat digunakan berulang agar format JSON yang ditampilkan seragam, lalu jika kita membutuhkan format JSON yang lain maka kita dapat membuat file Resource baru.
CRUD Post
Silahkan jalankan perintah berikut ini di dalam terminal/CMD di dalam project Laravel-nya.
php artisan make:controller Api/PostControllerPerintah di atas akan membuat sebuah file baru pada folder app/Http/Controllers/Api/PostController.php. Silahkan membuka file tersbut dan rubah semua kode nya menjadi seperti berikut ini:
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Http\Resources\ApiResource;
use App\Models\Post;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;
class PostController extends Controller
{
/**
* index
*
* @return void
*/
public function index()
{
//get latest posts
$posts = Post::latest()->paginate(10);
//return response
return new ApiResource(true, 'All Posts', $posts);
}
/**
* store
*
* @param mixed $request
* @return void
*/
public function store(Request $request)
{
//define validation rules
$validator = Validator::make($request->all(), [
'image' => 'required|image|mimes:webp,jpeg,png,jpg|max:2048',
'title' => 'required',
'content' => 'required',
]);
//check if validation fails
if ($validator->fails()) {
//return error response
return response()->json($validator->errors(), 422);
}
//upload image
$image = $request->file('image');
$image->storeAs('public/posts', $image->hashName());
//create new post
$post = Post::create([
'image' => $image->hashName(),
'title' => $request->title,
'content' => $request->content,
]);
//return response
return new ApiResource(true, 'Post Created!', $post);
}
/**
* show
*
* @param mixed $id
* @return void
*/
public function show($id)
{
//find post by ID
$post = Post::find($id);
//return single post resource
return new ApiResource(true, 'Post Detail', $post);
}
/**
* update
*
* @param mixed $request
* @param mixed $id
* @return void
*/
public function update(Request $request, $id)
{
//define validation rules
$validator = Validator::make($request->all(), [
'title' => 'required',
'content' => 'required',
]);
//check if validation fails
if ($validator->fails()) {
return response()->json($validator->errors(), 422);
}
//find post by ID
$post = Post::find($id);
//check if image is not empty
if ($request->hasFile('image')) {
//upload image
$image = $request->file('image');
$image->storeAs('public/posts', $image->hashName());
//delete old image
Storage::delete('public/posts/' . basename($post->image));
//update post
$post->update([
'image' => $image->hashName(),
'title' => $request->title,
'content' => $request->content,
]);
} else {
//update post without upload image
$post->update([
'title' => $request->title,
'content' => $request->content,
]);
}
//return response
return new ApiResource(true, 'Post Updated!', $post);
}
/**
* destroy
*
* @param mixed $id
* @return void
*/
public function destroy($id)
{
//find post by ID
$post = Post::find($id);
//delete image
Storage::delete('public/posts/'.basename($post->image));
//delete post
$post->delete();
//return response
return new ApiResource(true, 'Post Deleted!', null);
}
}Membuat Route Rest API
Pada Laravel 11 route api sudah tidak tersedia secara default saat membuat projek baru. Oleh karena itu kita harus menginstallnya terlebih dahulu. Silahkan jalankan perintah berikut ini di dalam terminal/CMD di dalam project Laravel-nya.
php artisan install:apiSekarang route Untuk Rest API sudah tersedia di dalam folder routes/api.php. Silahkan membuka file tersebut dan mengubahnya menjadi seperti berikut:
<?php
use App\Http\Controllers\Api\PostController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
Route::get('/user', function (Request $request) {
return $request->user();
})->middleware('auth:sanctum');
//posts
Route::apiResource('/posts', PostController::class);
Pada kode di atas, kita menambahkan route baru dengan jenis apiResource dan memiliki path /posts yang mengarah kepada PostController. Untuk memastikan route tersebut berhasil ditambahkan, jalankan perintah berikut ini di dalam terminal/CMD.
php artisan route:list
Uji Coba Rest API
Dalam pengujian ini, kita akan menggunakan Postman.
Insert Post
Sekarang buka aplikasi Postman, kemudian masukkan URL berikut ini http://localhost:8000/api/posts dan method-nya silahkan pilih POST. Kemudian masuk ke tab body, lalu pilih form data dan masukkan data sebagai berikut:
| KEY | TYPE | VALUE |
| title | text | judul post 1 |
| image | file | pilih gambar dari PC |
| content | text | ini adalah content dari post pertama |
Klik tombol Send. Jika berhasil maka akan menampilkan hasil seperti gambar di bawah ini. Silahkan menambahkan post beberapa kali untuk menyimpan lebih banyak data ke dalam database.

Menampilkan Post
Pada postman, silahkan mengganti method nya menjadi GET. Jika tidak ada error, maka akan menampilkan data Post terbaru sebagai berikut:
{
"status": true,
"message": "All Posts",
"data": {
"current_page": 1,
"data": [
{
"id": 4,
"title": "judul post 4",
"image": "http://localhost:8000/storage/posts/sB4pLt3pcVPZ5rcSR6SaHzbr0NDXCvlVynRWrKuv.webp",
"content": "Ini adalah content dari post keempat",
"created_at": "2024-04-02T04:37:37.000000Z",
"updated_at": "2024-04-02T04:37:37.000000Z"
},
{
"id": 3,
"title": "judul post 3",
"image": "http://localhost:8000/storage/posts/538muPLLP19GgNWPgUkkPtEeVeWe3q4ot3GksoVI.webp",
"content": "Ini adalah content dari post ketiga",
"created_at": "2024-04-02T04:37:28.000000Z",
"updated_at": "2024-04-02T04:37:28.000000Z"
},
{
"id": 2,
"title": "judul post 2",
"image": "http://localhost:8000/storage/posts/sW7mZKhHWeriE5O5v1APX9GCr61dLsAc2LBTFK1E.webp",
"content": "Ini adalah content dari post kedua",
"created_at": "2024-04-02T04:37:21.000000Z",
"updated_at": "2024-04-02T04:37:21.000000Z"
},
{
"id": 1,
"title": "judul post 1",
"image": "http://localhost:8000/storage/posts/dWmZugz5b1gSIhzeoU4BGGDVXCRqJTYkdSPyeyrE.webp",
"content": "Ini adalah content dari post pertama",
"created_at": "2024-04-02T04:24:07.000000Z",
"updated_at": "2024-04-02T04:24:07.000000Z"
}
],
"first_page_url": "http://localhost:8000/api/posts?page=1",
"from": 1,
"last_page": 1,
"last_page_url": "http://localhost:8000/api/posts?page=1",
"links": [
{
"url": null,
"label": "« Previous",
"active": false
},
{
"url": "http://localhost:8000/api/posts?page=1",
"label": "1",
"active": true
},
{
"url": null,
"label": "Next »",
"active": false
}
],
"next_page_url": null,
"path": "http://localhost:8000/api/posts",
"per_page": 10,
"prev_page_url": null,
"to": 4,
"total": 4
}
}Menampilkan Detail Post
Tambahkan ID pada akhir URL pada Postman. Sebagai contoh, saya akan menampilkan detail Post dengan ID = 3. Maka URL nya menjadi http://localhost:8000/api/posts/3. Berikut hasil dari detail post.
{
"status": true,
"message": "Post Detail",
"data": {
"id": 3,
"title": "judul post 3",
"image": "http://localhost:8000/storage/posts/538muPLLP19GgNWPgUkkPtEeVeWe3q4ot3GksoVI.webp",
"content": "Ini adalah content dari post ketiga",
"created_at": "2024-04-02T04:37:28.000000Z",
"updated_at": "2024-04-02T04:37:28.000000Z"
}
}Mengupdate Data Post
Sebagai contoh kita akan mengupdate Post dengan ID = 2. Maka ubah URL nya menjadi: http://localhost:8000/api/posts/2. Pilih Method menjadi POST, dan pada tab body isikan form-data sebagai berikut dan klik Send.
| KEY | TYPE | VALUE |
_method | text | PUT |
title | text | judul post 1 |
image | file | pilih gambar dari PC |
content | text | ini adalah content dari post pertama |
Jika berhasil, maka akan menampilkan hasil sebagai berikut:

Menghapus Data Post
Silahkan mengubah URL nya menjadi: http://localhost:8000/api/posts/4 untuk menghapus Post dengan ID=4. Rubah method nya menjadi DELETE. Jika berhasil akan menampilkan output Sebagai Berikut:
{
"status": true,
"message": "Post Deleted!",
"data": null
}Kita telah selesai membuat Sebuah Projek Restfull API pada Larevel 11. Pada artikel selanjutnya kita akan membuat Authentikasi Pada Laravel 11 dengan menggunakan Sanctum.