gisila_doc or gisila?
What it is
Section titled “What it is”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).
When to use it
Section titled “When to use it”- 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.
When not to use it
Section titled “When not to use it”- 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_docpinsanalyzer >=7.4.0 <8.0.0, which can constrain other generators in the same project).
How it works
Section titled “How it works”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.
Example
Section titled “Example”The same route in both styles:
// gisilaimport '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_docimport '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);}