BAB 39. ROUTING
Flutter Routing — GoRouter
TemuBelajar menggunakan GoRouter untuk manajemen navigasi Flutter karena mendukung deep linking, route guard, dan redirect yang mudah diintegrasikan dengan Riverpod.
Struktur Route Flutter
/ → Redirect berdasarkan auth state
├── /login → Halaman Login
├── /change-password → Ganti Password (first login)
├── /dashboard → Dashboard utama (protected)
├── /profile → Profil pengguna
│ └── /profile/edit → Edit profil
├── /request → Daftar request
│ ├── /request/create → Buat request baru
│ └── /request/:id → Detail request
├── /booking → Daftar booking
│ └── /booking/:id → Detail booking
├── /meeting
│ ├── /meeting/check-in → Halaman Check-In
│ └── /meeting/:id → Detail sesi meeting
├── /chat
│ └── /chat/:bookingId → Ruang chat
├── /leaderboard → Halaman leaderboard
├── /teacher → Dashboard guru (role:teacher)
│ └── /teacher/monitor → Monitoring sesi
└── /settings → Pengaturan
Route Guard — Auth & Role
flowchart TD
A["🔗 Navigasi ke Route"] --> B{{"Token ada di\nSecure Storage?"}}
B -->|Tidak| C["➡️ Redirect ke /login"]
B -->|Ya| D{{"must_change_password?"}}
D -->|true| E["➡️ Redirect ke /change-password"]
D -->|false| F{{"Role Check"}}
F -->|student| G["✅ Student Routes"]
F -->|teacher| H["✅ Teacher Routes"]
F -->|admin| I["✅ Admin Routes"]
F -->|Salah role| J["❌ 403 Forbidden Page"]
style C fill:#dc2626,color:#fff
style G fill:#059669,color:#fff
style H fill:#059669,color:#fff
style I fill:#059669,color:#fff
Implementasi GoRouter
// app/router/app_router.dart
final appRouterProvider = Provider<GoRouter>((ref) {
final authState = ref.watch(authStateProvider);
return GoRouter(
initialLocation: '/dashboard',
redirect: (context, state) {
final isLoggedIn = authState.isAuthenticated;
final mustChange = authState.user?.mustChangePassword ?? false;
if (!isLoggedIn) return '/login';
if (mustChange && state.uri.path != '/change-password') {
return '/change-password';
}
return null;
},
routes: [
GoRoute(
path: '/login',
builder: (context, state) => const LoginPage(),
),
GoRoute(
path: '/change-password',
builder: (context, state) => const ChangePasswordPage(),
),
GoRoute(
path: '/dashboard',
builder: (context, state) => const DashboardPage(),
),
GoRoute(
path: '/request',
builder: (context, state) => const RequestListPage(),
routes: [
GoRoute(
path: 'create',
builder: (context, state) => const CreateRequestPage(),
),
GoRoute(
path: ':id',
builder: (context, state) => RequestDetailPage(
id: int.parse(state.pathParameters['id']!),
),
),
],
),
GoRoute(
path: '/chat/:bookingId',
builder: (context, state) => ChatPage(
bookingId: int.parse(state.pathParameters['bookingId']!),
),
),
],
);
});
Laravel API Routing
Routing API dipisah per domain dalam file terpisah, kemudian di-include ke routes/api.php:
routes/
├── api.php # Main router (include semua)
└── api/
├── auth.php # /auth/login, /auth/logout
├── profile.php # /profile, /profile/skills
├── requests.php # /requests CRUD
├── bookings.php # /bookings/accept, /reject
├── meetings.php # /meetings/check-in, /check-out
├── ratings.php # /ratings
├── leaderboard.php # /leaderboard
└── notifications.php # /notifications
// routes/api.php
Route::prefix('v1')->group(function () {
require __DIR__ . '/api/auth.php';
Route::middleware('auth:sanctum')->group(function () {
require __DIR__ . '/api/profile.php';
require __DIR__ . '/api/requests.php';
require __DIR__ . '/api/bookings.php';
require __DIR__ . '/api/meetings.php';
require __DIR__ . '/api/ratings.php';
require __DIR__ . '/api/leaderboard.php';
require __DIR__ . '/api/notifications.php';
});
});
Ringkasan Endpoint per File Route
| File | Method | Endpoint |
|---|---|---|
auth.php | POST | /auth/login, /auth/logout, /auth/change-password |
profile.php | GET, PUT | /profile, /profile/skills |
requests.php | GET, POST, PUT, DELETE | /requests, /requests/{id} |
bookings.php | POST | /bookings/{id}/accept, /reject, /reschedule |
meetings.php | POST | /meetings/check-in, /check-out, /{id}/summary |
ratings.php | POST | /ratings |
leaderboard.php | GET | /leaderboard |
notifications.php | GET, PUT | /notifications, /notifications/{id}/read |