HTTP Requests

The Request object (rq) is available inside every Controller method and every app.get/post callback. It provides access to the full HTTP request and all response helpers.

Accessing the Request

Inside a Controller subclass:

class MyController extends Controller {
  Future<String> index() async {
    // rq is available directly as a getter
    var name = rq.get<String>('name', def: 'World');
    return rq.renderString(text: 'Hello $name');
  }
}

In an inline app.get() / app.post() callback, rq is the function parameter:

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

In an anonymous FinchRoute index closure, use 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');
  },
),

Reading Input Data

GET and POST fields

rq.get<T>(key, {T? def, trim = true}) reads from GET query params or POST body fields:

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

Check if a field is present:

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

URL path parameters

For paths like users/{id}, read with rq.getParam():

var id = rq.getParam('id');
// Returns null if the parameter is not present

Adding parameters manually

addParam / addParams injects data into the request context, making it available in templates:

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

In a Jinja template: {{ user.name }}, {{ title }}

Request Properties

Property / Method Type Description
rq.method String HTTP method (GET, POST, …)
rq.isPost bool true if method is POST
rq.uri Uri Full request URI
rq.headers HttpHeaders HTTP headers
rq.authorization Authorization Parsed Authorization header
rq.cookies List<Cookie> Request cookies
rq.session HttpSession Server-side session
rq.isApiEndpoint bool true when path starts with /api/
rq.clientIP String Client IP address
rq.route FinchRoute? Matched route (has permissions, key, etc.)
rq.getLanguage() String Current language code (en, fa, …)

Cookies

// Read a cookie
var theme = rq.getCookie('theme', def: 'light');

// Read an encrypted cookie
var token = rq.getCookie('auth_token', def: '', safe: true);

// Set a cookie
rq.addCookie('theme', 'dark');

// Set an encrypted cookie
rq.addCookie('auth_token', 'abc123', safe: true);

// Remove a cookie
rq.removeCookie('theme');

The encryption key is FinchConfigs.cookiePassword.

Sessions

// Read
var userEmail = rq.getSession('user', def: '');

// Write
rq.addSession('user', '[email protected]');

// Remove
rq.session.remove('user');

Redirects

// Redirect to a relative path
return rq.redirect('/login');

// Redirect to a full URL
return rq.redirect('https://example.com');

// With a specific status code
return rq.redirect('/dashboard', status: 301);

Response Methods Summary

Method Content-Type Description
renderView(path: '...') text/html Render Jinja template file
renderData(data: {...}) application/json JSON response
renderString(text: '...') text/plain Plain text
renderHtml(html: '...') text/html HTML string
renderTag(tag: Tag) text/html Render Htmler Tag
renderError(404) varies Standard error page or JSON
renderSSE(stream) text/event-stream Server-Sent Events
renderSocket() WebSocket handshake placeholder

renderView

rq.addParams({'title': 'Home', 'items': items});
return rq.renderView(path: 'pages/home');
// Loads: widgetsPath + '/pages/home.' + widgetsType

renderData (JSON)

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

renderError

// HTML error page
return rq.renderError(404);

// JSON error (for API routes)
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);
}