Tutorial #4: API Manajemen Pengguna (Admin & Petugas)
Halo bos bank! Hari ini kita akan membuat API untuk mengelola data admin dan petugas. Admin bisa nambah, ngubah, ngapus, dan lihat daftar petugas atau admin lain. Pokoknya admin jadi bosnya para user!
Yang akan kita buat:
- ✅ Controller untuk manajemen user (UserController).
- ✅ Route API khusus admin (dilindungi middleware isAdmin).
- ✅ Fungsi lihat semua user (hanya admin & petugas? kita batasi admin saja).
- ✅ Fungsi tambah user baru (dengan role admin/petugas).
- ✅ Fungsi lihat detail user.
- ✅ Fungsi update user.
- ✅ Fungsi hapus user.
- ✅ Validasi input biar tidak sembarangan.
Langkah 1: Membuat UserController untuk API
Buka terminal di folder bank-backend, jalankan perintah:
php artisan make:controller Api/UserController --api
Parameter --api akan membuat method index, store, show, update, destroy sekaligus. File akan muncul di app/Http/Controllers/Api/UserController.php.
index untuk menampilkan daftar, store untuk menyimpan data baru, show untuk detail satu user, update untuk mengubah, destroy untuk menghapus. Praktis!
Langkah 2: Mengisi UserController
Buka file UserController.php dan isi dengan kode berikut. Jangan lupa kita import model User, Hash, dan Request.
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\Rule;
class UserController extends Controller
{
/**
* Menampilkan daftar user (hanya admin & petugas?
* Tapi karena route ini khusus admin, kita tampilkan semua user dengan role admin & petugas saja.
* Bisa juga ditampilkan semua, terserah. Kali ini kita tampilkan semua kecuali nasabah?
* Kita tampilkan semua user, tapi kita filter di frontend nanti.
*/
public function index()
{
// Ambil semua user beserta relasi role
$users = User::with('role')->get();
return response()->json($users);
}
/**
* Menyimpan user baru (khusus admin & petugas)
*/
public function store(Request $request)
{
$request->validate([
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:6',
'role_id' => 'required|integer|in:1,2', // hanya boleh admin (1) atau petugas (2)
]);
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password),
'role_id' => $request->role_id,
]);
// Kalau role_id = 2 (petugas) tidak perlu dibuatkan account (rekening), karena petugas bukan nasabah.
return response()->json([
'message' => 'User berhasil ditambahkan',
'user' => $user->load('role')
], 201);
}
/**
* Menampilkan detail user
*/
public function show($id)
{
$user = User::with('role')->findOrFail($id);
return response()->json($user);
}
/**
* Mengupdate data user
*/
public function update(Request $request, $id)
{
$user = User::findOrFail($id);
$request->validate([
'name' => 'sometimes|string|max:255',
'email' => ['sometimes', 'string', 'email', 'max:255', Rule::unique('users')->ignore($user->id)],
'password' => 'sometimes|string|min=6|nullable',
'role_id' => 'sometimes|integer|in:1,2',
]);
$data = $request->only('name', 'email', 'role_id');
if ($request->filled('password')) {
$data['password'] = Hash::make($request->password);
}
$user->update($data);
return response()->json([
'message' => 'User berhasil diupdate',
'user' => $user->load('role')
]);
}
/**
* Menghapus user
*/
public function destroy($id)
{
$user = User::findOrFail($id);
// Cegah admin menghapus dirinya sendiri? Boleh sebagai proteksi
if ($user->id == auth()->id()) {
return response()->json(['message' => 'Tidak bisa menghapus akun sendiri'], 403);
}
$user->delete();
return response()->json(['message' => 'User berhasil dihapus']);
}
}
Penjelasan:
- index: mengambil semua user dengan relasi role. Nanti kita bisa filter di frontend sesuai kebutuhan.
- store: validasi role_id hanya 1 (admin) atau 2 (petugas). Jadi admin tidak bisa bikin akun nasabah lewat sini (nasabah daftar via register).
- update: validasi unik email kecuali untuk user yang sedang diupdate. Password boleh diisi atau tidak.
- destroy: tidak boleh hapus diri sendiri biar nggak kacau.
Langkah 3: Menambahkan Route dengan Middleware isAdmin
Buka routes/api.php. Di dalam group middleware auth:sanctum dan isAdmin (yang sudah kita buat di tutorial #3), tambahkan route resource untuk user.
Route::middleware(['auth:sanctum', 'isAdmin'])->group(function () {
Route::apiResource('users', App\Http\Controllers\Api\UserController::class);
});
Fungsi apiResource akan membuat route secara otomatis:
| Method | URL | Controller Method |
|---|---|---|
| GET | /api/users | index |
| POST | /api/users | store |
| GET | /api/users/{id} | show |
| PUT/PATCH | /api/users/{id} | update |
| DELETE | /api/users/{id} | destroy |
Langkah 4: Uji Coba dengan Postman
Pastikan server jalan (php artisan serve). Kita perlu login sebagai admin dulu untuk mendapatkan token.
Login admin: POST ke /api/login dengan email admin@bank.com (yang kita buat di tutorial sebelumnya) dan password rahasia123. Copy token yang didapat.
Set Authorization header: di Postman, pilih tab Authorization, pilih tipe Bearer Token, tempel token.
Coba GET /api/users – harusnya muncul daftar user (termasuk admin, petugas, nasabah).
Coba POST /api/users dengan data:
{
"name": "Petugas Baru",
"email": "petugas2@bank.com",
"password": "123456",
"role_id": 2
}
Response: 201 Created dengan data user baru.
Coba PUT /api/users/{id} misal ganti nama atau password.
Coba DELETE /api/users/{id} (jangan hapus admin sendiri).
php artisan tinker lalu User::create(['name'=>'Admin','email'=>'admin@bank.com','password'=>Hash::make('rahasia123'),'role_id'=>1]);
Langkah 5: Menambahkan Proteksi Tambahan
Kita mungkin ingin memastikan bahwa admin tidak bisa mengubah role user menjadi nasabah (role_id 3). Di method update kita sudah batasi role_id hanya 1 atau 2. Tapi kalau admin iseng mengirim role_id = 3, akan ditolak validasi.
Juga kita bisa menambahkan policy agar user biasa tidak bisa mengakses route ini. Tapi karena route sudah dibungkus middleware isAdmin, aman.
Bonus: Menambahkan Fitur Filter (Misal hanya tampilkan admin & petugas)
Di method index, kita bisa tambahkan parameter query untuk filter. Misal ?role=petugas. Tapi untuk sekarang kita biarkan semua. Nanti di frontend kita bisa filter sendiri.
Kesimpulan
- ✅ UserController dengan CRUD untuk admin dan petugas.
- ✅ Route terproteksi oleh middleware isAdmin.
- ✅ Validasi membatasi role_id hanya 1 dan 2.
- ✅ Tidak bisa hapus diri sendiri.
Di tutorial selanjutnya (#5: API Transaksi Nabung dan Tarik Tunai oleh Petugas) kita akan membuat petugas bisa melakukan transaksi setor dan tarik tunai untuk nasabah. Siap-siap jadi teller bank! 💸