Skip to content

gisila_doc or gisila?

gisila_doc and gisila share one runtime. Both generate an attachToApp extension per controller that registers routes through gisilaRoute(...), so requests go through the same pipeline: AppConfig.defaultRouteConfig, class-level @UseRouteConfig, per-route RouteConfig, guards (@RequireAuth, @Permissions, @AnyPermission, @Roles, @Public), named middleware (@UseMiddleware), Form binding, Service injection and the JSON error envelope.

The difference is what else the generated code does. gisila_doc’s version also writes an OpenAPI 3.1 operation for every route into an OpenApiSpec, and its annotations carry documentation fields (summary, description, operationId, tags, deprecated, documented bodies and responses).

  • You publish an HTTP JSON API to people or teams who need a contract: frontend developers, partners, mobile clients.
  • You want a client SDK generated from the spec.
  • You want interactive docs (Swagger UI, Redoc) served by the app itself.
  • You want the documented auth requirements (security, 401/403) to follow the guards that actually run.
  • Server-rendered HTML apps, webhooks receivers or internal services nobody consumes through a spec. Plain gisila has the same runtime with less to configure.
  • You want to keep the API surface minimal and avoid the extra build-time dependencies (gisila_doc pins analyzer >=7.4.0 <8.0.0, which can constrain other generators in the same project).

The two packages differ in a few concrete places:

gisila gisila_doc
Import package:gisila/gisila.dart package:gisila_doc/gisila_doc.dart (re-exports gisila)
@Controller Controller([path]) Controller([path, tags])
Verb annotations path, statusCode, contentType, config path, summary, description, operationId, deprecated, tags, statusCode, body, responses, config
Parameter annotations @Body, @Query({name}), @Path({name}), @Header({name}) same names, plus description (and example, which is currently not emitted)
Extra annotations none @ApiResponse, @Returns, @Responses, @QueryDoc, @BodyDoc, @Tag
Generated method attachToApp(app, router, {prefix}) attachToApp(app, router, spec, {prefix})
Builder output .gisila.g.part .gisila_doc.g.part

The generated runtime code is otherwise equivalent: both pass routeId: 'METHOD path' to gisilaRoute, so a shared AppConfig.rateLimitStore gives each route one budget across isolates.

Because gisila_doc hides gisila’s Controller, Route, Get, Post, Put, Patch, Delete, Head, Options, Body, Query, Path and Header, a file that imports gisila_doc uses the doc-aware versions. Do not import both packages unprefixed in the same controller file.

The same route in both styles:

// gisila
import 'package:gisila/gisila.dart';
part 'users_controller.g.dart';
@Controller('/users')
class UsersController {
@Get('/{id}')
Future<User> getUser(String id, UserService users) => users.getById(id);
}
// gisila_doc
import 'package:gisila_doc/gisila_doc.dart';
part 'users_controller.g.dart';
@Controller('/users', ['Users'])
class UsersController {
@Get('/{id}', summary: 'Fetch a user')
@ApiResponse(404, description: 'User not found')
Future<User> getUser(String id, UserService users) => users.getById(id);
}