کنترلرها

یک کنترلر (controller) کلاسی در Dart است که از Controller ارث‌بری می‌کند و handlerهای مرتبط با درخواست را در کنار هم گروه‌بندی می‌کند. هر متد handler یک Future<String> برمی‌گرداند — بدنه پاسخ HTTP.

ساخت یک کنترلر

import 'package:finch/finch_route.dart';

class UserController extends Controller {
  UserController();

  @override
  Future<String> index() async {
    return rq.renderData(data: {'message': 'User list'});
  }

  Future<String> show() async {
    var id = rq.getParam('id');
    return rq.renderData(data: {'id': id});
  }

  Future<String> profile() async {
    rq.addParam('title', 'User Profile');
    return rq.renderView(path: 'user/profile');
  }
}

شیء rq

درون هر زیرکلاس Controller، rq یک getter است که Context.rq — شیء Request جاری — را برمی‌گرداند. این شیء دسترسی به داده‌های درخواست، session، کوکی‌ها و تمام متدهای پاسخ را فراهم می‌کند.

ضمیمه کردن یک کنترلر به یک مسیر

final userController = UserController();

FinchRoute(
  key: 'users.index',
  path: 'users',
  methods: Methods.ONLY_GET,
  controller: userController,  // userController.index() را فراخوانی می‌کند
),
FinchRoute(
  key: 'users.show',
  path: 'users/{id}',
  methods: Methods.ONLY_GET,
  index: userController.show,  // یک متد خاص را فراخوانی می‌کند
),

controller از متد index() استفاده می‌کند. index یک Future<String> Function()? می‌پذیرد — یک ارجاع به متد از کنترلر پاس دهید تا یک اکشن دیگر فراخوانی شود.

متدهای پاسخ

تمام متدهای پاسخ روی شیء rq قرار دارند:

متد توضیح
rq.renderView(path: 'template/path') رندر یک قالب Jinja از widgetsPath
rq.renderData(data: {...}) پاسخ JSON
rq.renderString(text: '...') پاسخ متن ساده
rq.renderHtml(html: '...') پاسخ رشته HTML
rq.renderTag(tag: Tag) رندر یک Tag از Htmler
rq.renderError(404) پاسخ خطای استاندارد
rq.redirect('/path') هدایت مجدد HTTP
rq.renderSSE(stream) استریم Server-Sent Events
rq.renderSocket() placeholder برای دست‌دهی (handshake) WebSocket

renderView

Future<String> dashboard() async {
  rq.addParams({
    'title': 'Dashboard',
    'user': currentUser,
  });
  return rq.renderView(path: 'pages/dashboard');
  // بارگذاری می‌شود از: widgetsPath/pages/dashboard.{widgetsType}
}

renderData (JSON)

Future<String> apiUsers() async {
  var users = await UserCollection().getAll();
  return rq.renderData(data: {'users': users.map((u) => u.toJson()).toList()});
}

renderError

Future<String> notFound() async {
  return rq.renderError(404);
}

خواندن داده‌های درخواست

// خواندن یک فیلد GET یا POST
var name = rq.get<String>('name', def: 'anonymous');
var age  = rq.get<int>('age', def: 0);

// خواندن یک پارامتر مسیر از {id}
var id = rq.getParam('id');

// بررسی متد درخواست
if (rq.isPost) { ... }
if (rq.method == Methods.DELETE) { ... }

// آیا endpoint یک API است؟ (مسیر با /api/ شروع می‌شود)
bool isApi = rq.isApiEndpoint;

ارسال داده به قالب‌ها

Future<String> show() async {
  var user = await UserCollection().findById(rq.getParam('id'));

  // addParam / addParams داده را در قالب‌های Jinja در دسترس قرار می‌دهد
  rq.addParams({
    'user': user?.toJson(),
    'title': 'User Profile',
  });

  return rq.renderView(path: 'user/show');
}

در قالب:

<h1>{{ user.name }}</h1>

دسترسی به سایر کنترلرها

کنترلرها اشیاء ساده Dart هستند. آن‌ها را در سطح بالا (top level) نمونه‌سازی کرده و به اشتراک بگذارید:

final authController = AppAuthController();
final homeController = HomeController();

// در AuthController.loginPost():
return homeController.renderView('example/form');