Skip to content

Generated code and builder

For each @Controller class Foo, build_runner generates:

extension FooGisilaDoc on Foo {
void attachToApp(
GisilaApp app,
Router router,
OpenApiSpec spec, {
String prefix = '',
});
}

When to use: call it once per controller instance, either directly on a Router you own or inside app.registerController(attacher: ...). It matches gisila’s ControllerAttacher shape apart from the extra spec argument, so it can’t be passed as the attacher itself; wrap it in a closure.

Parameter Type Default Description
app GisilaApp required Supplies AppConfig.defaultRouteConfig, the authenticator, services and error handling to each route.
router Router required shelf_router Router the routes are added to.
spec OpenApiSpec required Receives operations, component schemas and controller tags.
prefix String '' Prepended to every route path and every documented path, e.g. '/api/v1'.

It runs these steps in order: spec.putSchema for each component schema the controller uses, spec.putTag for each controller tag, then for each route gisilaRoute(...), router.<verb>(...) and spec.putOperation(...). See How generation works.

Example

import 'package:gisila_doc/gisila_doc.dart';
final spec = OpenApiSpec(info: const ApiInfo(title: 'Demo', version: '1.0.0'));
final app = GisilaApp(config: AppConfig());
app.registerService<UserService>(UserService.new);
app.registerController(
prefix: '/api/v1',
attacher: (app, router, {String prefix = ''}) {
UsersController().attachToApp(app, router, spec, prefix: prefix);
OrdersController().attachToApp(app, router, spec, prefix: prefix);
},
);
await app.start(port: 8080);

The package’s build.yaml declares one builder:

Key Value
Builder gisila_doc (controllerBuilder in package:gisila_doc/builder.dart)
Output .gisila_doc.g.part, combined into <file>.g.dart by source_gen
auto_apply dependents: runs in every package that depends directly on gisila_doc
build_to cache

When to use: you normally configure nothing. Add part '<file>.g.dart'; to each controller file and run:

Terminal window
dart run build_runner build # one-off
dart run build_runner watch # rebuild on save

package:gisila_doc/builder.dart exports controllerBuilder(BuilderOptions). It is the build.yaml entry point; you never import it from app code.

The generator uses the analyzer 7 element API, so gisila_doc constrains analyzer to >=7.4.0 <8.0.0. Other generators in the same package must accept that range.

Message Cause
@Controller must be placed on a class. The annotation is on something else.
Could not classify parameter "x" of C.m. ... A second non-primitive parameter after the body was already bound. Annotate it, make it a Form or Service, or remove it.
Warning: C is annotated with @Controller but has no methods carrying @Get/@Post/...; skipping. No verb-annotated methods.

Guard and configuration annotations (RequireAuth, Public, Permissions, AnyPermission, Roles, UseMiddleware, UseRouteConfig) are recognised only when declared in package:gisila or package:gisila_doc. A look-alike class with the same name from another package is ignored.

package:gisila_doc/gisila_doc.dart re-exports all of package:gisila/gisila.dart except gisila’s Body, Controller, Delete, Get, Head, Header, Options, Patch, Path, Post, Put, Query and Route. It also re-exports shelf’s Request, Response, Handler and the shelf_router Router through gisila. The helpers below are what the generated code calls; they are documented in the framework section.

Symbol Used for
coerce<T>(String? value, String paramName, {required bool required}) Parsing path and query values. Throws BadRequestException.
readJsonBody(Request request, {bool required = true}) Reading a JSON body. Throws BadRequestException on an empty required body or malformed JSON.
jsonResponse({Object? body, int statusCode = 200, Map<String, String>? extraHeaders}) Encoding return values, calling toJson() recursively.
emptyResponse({int statusCode = 204}) void handlers.
BadRequestException Turned into a 400 error envelope by gisila.

When to use: in raw-Request handlers, these are the same helpers the generated code uses, so errors and encoding stay consistent with typed routes.

Symbol Notes
RouteConfig, UseRouteConfig Re-exported from gisila by annotations.dart. See Route annotations.