Aturan Penting Lainnya
Best practices dan hal-hal yang sering dilupakan
Database Best Practices
1. Selalu Pakai Migration
# Buat migration
php artisan make:migration add_status_to_users_table
public function up()
{
Schema::table('users', function ($table) {
$table->enum('status', ['active', 'inactive']);
});
}
# Edit langsung di phpMyAdmin
# ❌ Tidak ter-track di version control
# ❌ Tim lain tidak tahu perubahan
# ❌ Sulit di-deploy ke production
2. Hindari N+1 Problem
N+1 Problem: Query yang terjadi berkali-kali
dalam loop. Gunakan
with() untuk
eager loading!
// Load dengan eager loading
$posts = Post::with('user')->get();
foreach ($posts as $post) {
echo $post->user->name;
}
// Total query: 2
// Query tanpa eager loading
$posts = Post::all();
foreach ($posts as $post) {
echo $post->user->name; // Query tiap loop!
}
// Total query: 1 + N
Standar Response API
Semua API endpoint harus return response dengan format yang konsisten:
📋 Format Response Standar:
// Success Response
{
"success": true,
"message": "Data berhasil diambil",
"data": {
"id": 1,
"name": "John Doe"
}
}
// Error Response
{
"success": false,
"message": "Validasi gagal",
"errors": {
"email": ["Email harus valid"]
}
}
⚠️ Status Code yang Benar:
200
OK (GET berhasil)
201
Created (POST berhasil)
204
No Content (DELETE berhasil)
400
Bad Request
401
Unauthorized (Belum login)
404
Not Found
422
Validation Error
500
Server Error
Wajib Pakai ResponseResource
ATURAN WAJIB: Gunakan ResponseResource!
DILARANG menggunakan
response()->json()
langsung. Harus pakai
new ResponseResource()
// ✅ Pakai ResponseResource
return new ResponseResource(200, true, 'Login berhasil', ['user' => $user]);
// ❌ Dilarang pakai langsung
return response()->json([
'message' => 'Login berhasil',
'user' => $user
]);
📝 Parameter ResponseResource:
// Format: new ResponseResource(status, success, message, data)
return new ResponseResource(
200, // HTTP Status Code
true, // Success flag
'Data berhasil diambil', // Message
['user' => $user] // Data (optional)
);
// Error Response
return new ResponseResource(
422,
false,
'Validasi gagal',
['errors' => $errors]
);
Kenapa ResponseResource?
- • Konsistensi response format di seluruh API
- • Otomatis mengikuti standar perusahaan
- • Mudah diubah jika ada perubahan format
- • Centralized response handling
Struktur Routes yang Rapi
🛑 Route Auth di Tempat Salah!
Route register/login jangan di
routes/api.php -
BAPER sedang di tempat umum!
✅ Perbaikan: Buat File Terpisah
// routes/api.php - ❌ Bercampur dengan route lain
Route::post('/register', [AuthController::class, 'register']);
Route::post('/login', [AuthController::class, 'login']);
Route::apiResource('products', ProductController::class);
Route::apiResource('users', UserController::class);
// routes/v1/auth.php - ✅ Terpisah & rapi
Route::post('/register', [AuthController::class, 'register']);
Route::post('/login', [AuthController::class, 'login']);
// routes/api.php - ✅ Load file auth
require __DIR__.'/v1/auth.php';
📁 Struktur Folder Routes:
// routes/
// ├── api.php # Route utama
// ├── v1/
// │ ├── auth.php # Routes authentication
// │ ├── users.php # Routes user management
// │ └── products.php # Routes products
// └── web.php # Web routes
Keuntungan Struktur Rapi
- • Mudah cari route tertentu
- • Maintenance lebih gampang
- • Kolaborasi tim lebih efisien
- • Versioning API lebih jelas (v1, v2, dst)
Logic Bisnis di Service
❌ Controller Langsung Handle Database!
Controller jangan nge-handle database & logic - Melanggar aturan perusahaan!
✅ Perbaikan: Buat AuthService
// ❌ Logic di Controller
public function login(Request $request)
{
$user = User::where('email', $request->email)->first();
if (!$user) {
throw new Exception('User not found');
}
return $user;
}
// ✅ Controller cuma panggil service
public function login(Request $request)
{
$data = $request->validate([...]);
$user = $this->authService->login($data);
return new ResponseResource(200, true, 'Login berhasil', ['user' => $user]);
}
// ✅ Logic di Service
public function login(array $data): User
{
$user = User::where('email', $data['email'])->first();
if (!$user) {
throw new Exception('User not found');
}
return $user;
}
📁 Struktur Folder Service:
// app/Services/
// ├── Auth/
// │ └── AuthService.php
// ├── User/
// │ └── UserService.php
// └── Product/
// └── ProductService.php
Kenapa Penting?
- • Kode bersih dan terorganisir
- • Mudah test logic bisnis
- • Mudah ganti implementasi
- • Controller tetap thin dan readable
Komentar yang Efektif
Golden Rule: Jelaskan "KENAPA", bukan "APA"
Kode sudah menjelaskan "APA" yang dilakukan. Komentar harus menjelaskan "KENAPA" itu dilakukan.
// Cache selama 1 jam karena
// data jarang berubah
$products = Cache::remember('products', 3600, function() {
return Product::all();
});
// Get all users
$users = User::all();
// Tambah 1
$i++;
Cara Menjalankan Backend
Langkah Setup Backend
Ikuti langkah-langkah berikut untuk menjalankan backend Laravel di lokal.
Install PHP & Node packages
composer install
npm install
Install semua dependencies PHP dan Node.js
Setup Environment
cp .env.example .env
php artisan key:generate
Copy file environment dan generate application key
Setup Database
php artisan migrate
php artisan db:seed
Jalankan migration dan seed database
Jalankan Server
composer run dev
Start Laravel development server
Test API
Buka: http://localhost:8000/docs/api
Akses dokumentasi API untuk testing
Tips Troubleshooting
- • Pastikan PHP 8.1+ dan Composer sudah terinstall
- • Check database connection di file .env
-
• Jika port 8000 conflict, gunakan
php artisan serve --port=8080 -
• Clear cache jika ada error:
php artisan config:clear
Selamat! 🎉
Anda telah menyelesaikan dokumentasi SOP Backend Developer
Gunakan dokumentasi ini sebagai referensi saat coding dan share ke tim!