Use-case–centric toolkit for building Modular APIs with Shelf.
Define UseCase classes (input → validate → execute → output), connect them to HTTP routes,
add CORS / API Key middlewares, and expose Swagger / OpenAPI documentation.
Designed for the MACSS ecosystem — modular, explicit and testable server code.
-
✅
UseCase<I extends Input, O extends Output>base classes and DTOs (Input/Output). -
🧩
useCaseHttpHandler()adapter: accepts a factoryUseCase Function(Map<String, dynamic>)and returns a ShelfHandler. -
🧱 Included middlewares:
cors()— simple CORS support.apiKey()— header-based authentication; the key is read from theAPI_KEYenvironment variable (viaEnv).
-
📄 OpenAPI / Swagger helpers:
OpenApi.init(title)andOpenApi.docs— generate an OpenAPI spec from registered usecases (uses DTOtoSchema()), and provide a Swagger UIHandler.
-
📡 Automatic health endpoint:
- The server registers a simple health check endpoint at
GET /healthwhich responds with 200 OK and bodyok. This is implemented inmodular_api.dartas:_root.get('/health', (Request request) => Response.ok('ok'));
- The server registers a simple health check endpoint at
-
⚙️ Utilities:
Env.getString,Env.getInt,Env.setString(.env support via dotenv). -
Envbehavior: if a.envfile is not present the library will read values fromPlatform.environment; if a requested key is missing from both sources anEnvKeyNotFoundExceptionis thrown. -
🧪 Example project and tests included in
example/andtest/. -
🗄️ ODBC database client: a minimal ODBC
DbClientimplementation (DSN-based) tested with Oracle and SQL Server — seeNOTICEfor provenance and details.Usage:
import 'package:modular_api/modular_api.dart'; Future<void> runQuery() async { // Create a DSN-based client (example factories available in example/lib/db/db.dart) final db = createSqlServerClient(); try { final rows = await db.execute('SELECT @@VERSION as version'); print(rows); } finally { // ensure disconnect await db.disconnect(); } }
See
template/lib/db/db_client.dartfor convenience factories andNOTICEfor provenance details.
In pubspec.yaml:
dependencies:
modular_api: ^0.0.3Or from the command line:
dart pub add modular_api
dart pub getThis quick start mirrors the included example implementation (example/example.dart).
import 'package:modular_api/modular_api.dart';
Future<void> main(List<String> args) async {
final api = ModularApi(basePath: '/api');
// POST api/module1/hello-world
api.module('module1', (m) {
m.usecase('hello-world', HelloWorld.fromJson);
});
final port = 8080;
await api.serve(port: port,);
print('Docs on http://localhost:$port/docs');
}Example request (example server registers /api/module1/hello-world as a POST):
curl -H "Content-Type: application/json" -d '{"word":"world"}' \
-H "x-api-key: SECRET" \
"http://localhost:8080/api/module1/hello-world"Example response (HelloOutput):
{"output":"Hello, world!"}- UseCase layer — pure logic, independent of HTTP.
- HTTP adapter — turns a
UseCaseinto aHandler. - Middlewares — cross-cutting concerns (CORS, auth, logging).
- Swagger UI — documentation served automatically from registered use cases.
final api = ModularApi(basePath: '/api');
.use(cors())
.use(apiKey());To auto-generate the spec from registered routes and serve a UI:
Open http://localhost:<port>/docs to view the UI.
There are two example flavours included in this repository:
example/— a minimal, simplified runnable example. Checkexample/example.dartandtemplate/lib/modules/module1/hello_world.dartfor a concreteUseCase+ DTO example.template/— a fuller modular architecture template showing how to structure modules, repositories and tests for larger projects. See thetemplate/folder for a complete starter layout (modulesmodule1,module2,module3, and convenience DB clients).
The repository includes example tests (test/usecase_test.dart) that demonstrate the
recommended pattern and the useCaseTestHandler helper for unit-testing UseCase logic.
Run tests with:
dart test-
Windows
dart compile exe example/example.dart -o build/api_example.exe
-
Linux / macOS
dart compile exe example/example.dart -o build/api_example
MIT © ccisne.dev