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

شیء Request (rq) درون هر متد Controller و هر callback از app.get/post در دسترس است. این شیء دسترسی به کل درخواست HTTP و تمام helperهای پاسخ را فراهم می‌کند.

دسترسی به درخواست

درون یک زیرکلاس Controller:

class MyController extends Controller {
  Future<String> index() async {
    // rq مستقیماً به‌عنوان یک getter در دسترس است
    var name = rq.get<String>('name', def: 'World');
    return rq.renderString(text: 'Hello $name');
  }
}

در یک callback درون‌خطی (inline) app.get() / app.post()، rq پارامتر تابع است:

app.get(
  path: '/hello',
  index: (rq) async {
    var name = rq.get<String>('name', def: 'World');
    return rq.renderString(text: 'Hello $name');
  },
);

در یک closure ناشناس (anonymous) index مربوط به FinchRoute، از Context.rq استفاده کنید:

FinchRoute(
  key: 'hello',
  path: 'hello',
  index: () async {
    var name = Context.rq.get<String>('name', def: 'World');
    return Context.rq.renderString(text: 'Hello $name');
  },
),

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

فیلدهای GET و POST

rq.get<T>(key, {T? def, trim = true}) از پارامترهای query در GET یا فیلدهای بدنه در POST می‌خواند:

var name    = rq.get<String>('name', def: 'anonymous');
var age     = rq.get<int>('age', def: 0);
var active  = rq.get<bool>('active', def: false);

بررسی اینکه آیا یک فیلد وجود دارد:

if (rq.hasData('name')) { ... }

پارامترهای مسیر URL

برای مسیرهایی مانند users/{id}، با rq.getParam() بخوانید:

var id = rq.getParam('id');
// اگر پارامتر وجود نداشته باشد null برمی‌گرداند

افزودن دستی پارامترها

addParam / addParams داده را به context درخواست تزریق می‌کند و آن را در قالب‌ها در دسترس قرار می‌دهد:

rq.addParam('user', user.toJson());
rq.addParams({
  'title': 'Dashboard',
  'year': DateTime.now().year,
});

در یک قالب Jinja: {{ user.name }}, {{ title }}

ویژگی‌های درخواست

ویژگی / متد نوع توضیح
rq.method String متد HTTP (GET, POST, …)
rq.isPost bool true اگر متد POST باشد
rq.uri Uri URI کامل درخواست
rq.headers HttpHeaders هدرهای HTTP
rq.authorization Authorization هدر Authorization تجزیه‌شده (parsed)
rq.cookies List<Cookie> کوکی‌های درخواست
rq.session HttpSession session سمت سرور
rq.isApiEndpoint bool true وقتی مسیر با /api/ شروع می‌شود
rq.clientIP String آدرس IP کلاینت
rq.route FinchRoute? مسیر مطابقت‌یافته (دارای permissions، key و غیره)
rq.getLanguage() String کد زبان جاری (en, fa, …)

کوکی‌ها

getCookie/addCookie به‌صورت پیش‌فرض مقدار را رمزگذاری و رمزگشایی می‌کنند (safe در هر دو به‌صورت پیش‌فرض true است) — برای یک مقدار کوکی ساده و قابل‌خواندن، صراحتاً safe: false پاس دهید:

// رمزگذاری‌شده (پیش‌فرض) — مقدار در مرورگر غیرقابل‌خواندن و غیرقابل‌دستکاری است
var token = rq.getCookie('auth_token', def: '');
rq.addCookie('auth_token', 'abc123');

// ساده (plain) — مقدار همان‌طور که هست ذخیره می‌شود و در dev tools مرورگر قابل‌خواندن است
var theme = rq.getCookie('theme', def: 'light', safe: false);
rq.addCookie('theme', 'dark', safe: false);

// حذف یک کوکی
rq.removeCookie('theme');

کلید رمزگذاری FinchConfigs.cookiePassword است. addCookie همچنین duration، expires، path، domain، secure، httpOnly و sameSite را برای کنترل کامل روی هدر Set-Cookie می‌پذیرد. برای مرجع کامل به Cookies and Sessions مراجعه کنید.

Session‌ها

// خواندن
var userEmail = rq.getSession('user', def: '');

// نوشتن
rq.addSession('user', '[email protected]');

// حذف
rq.session.remove('user');

هدایت مجدد

// هدایت مجدد به یک مسیر نسبی
return rq.redirect('/login');

// هدایت مجدد به یک URL کامل
return rq.redirect('https://example.com');

// با یک status code مشخص
return rq.redirect('/dashboard', status: 301);

خلاصه متدهای پاسخ

متد Content-Type توضیح
renderView(path: '...') text/html رندر فایل قالب Jinja
renderData(data: {...}) application/json پاسخ JSON
renderString(text: '...') text/plain متن ساده
renderHtml(html: '...') text/html رشته HTML
renderTag(tag: Tag) text/html رندر Tag از Htmler
renderError(404) متفاوت صفحه خطای استاندارد یا JSON
renderSSE(stream) text/event-stream Server-Sent Events
renderSocket() — placeholder برای دست‌دهی (handshake) WebSocket

renderView

rq.addParams({'title': 'Home', 'items': items});
return rq.renderView(path: 'pages/home');
// بارگذاری می‌شود از: widgetsPath + '/pages/home.' + widgetsType

renderData (JSON)

return rq.renderData(data: {'success': true, 'count': 10});

renderError

// صفحه خطای HTML
return rq.renderError(404);

// خطای JSON (برای مسیرهای API)
return rq.renderError(403, toData: true, params: {'message': 'Forbidden'});

renderSSE (Server-Sent Events)

Future<String> sseExample() async {
  Stream<String> streamer = Stream.periodic(
    Duration(seconds: 1),
    (count) => 'Message $count\n',
  ).take(10);

  return rq.renderSSEString(streamer);
}