modular_api 0.1.0
modular_api: ^0.1.0 copied to clipboard
Use-case centric API toolkit for Dart — Shelf UseCase base class, HTTP adapters, CORS middleware, and automatic OpenAPI documentation.
modular_api #
Use-case centric toolkit for building modular APIs with Shelf.
Define UseCase classes (input → validate → execute → output), connect them to HTTP routes, and get automatic Swagger/OpenAPI documentation.
Also available in TypeScript: modular_api_ts
Quick start #
import 'package:modular_api/modular_api.dart';
// ─── Module builder (separate file in real projects) ──────────
void buildGreetingsModule(ModuleBuilder m) {
m.usecase('hello', HelloWorld.fromJson);
}
// ─── Server ───────────────────────────────────────────────────
Future<void> main() async {
final api = ModularApi(basePath: '/api');
api.module('greetings', buildGreetingsModule);
await api.serve(port: 8080);
}
curl -X POST http://localhost:8080/api/greetings/hello \
-H "Content-Type: application/json" \
-d '{"name":"World"}'
{"message":"Hello, World!"}
Docs → http://localhost:8080/docs
Health → http://localhost:8080/health
See example/example.dart for the full implementation including Input, Output, UseCase with validate(), and the builder.
Features #
UseCase<I, O>— pure business logic, no HTTP concernsInput/Output— DTOs withtoJson()andtoSchema()for automatic OpenAPIOutput.statusCode— custom HTTP status codes per responseUseCaseException— structured error handling (status code, message, error code, details)ModularApi+ModuleBuilder— module registration and routinguseCaseTestHandler— unit test helper (no HTTP server needed)cors()middleware — built-in CORS support- Swagger UI at
/docs— auto-generated from registered use cases - Health check at
GET /health - All endpoints default to
POST(configurable per use case)
Installation #
dependencies:
modular_api: ^0.1.0
dart pub add modular_api
Error handling #
@override
Future<void> execute() async {
final user = await repository.findById(input.userId);
if (user == null) {
throw UseCaseException(
statusCode: 404,
message: 'User not found',
errorCode: 'USER_NOT_FOUND',
);
}
output = GetUserOutput(user: user);
}
{"error": "USER_NOT_FOUND", "message": "User not found"}
Testing #
import 'package:modular_api/modular_api.dart';
import 'package:test/test.dart';
void main() {
test('HelloWorld returns greeting', () async {
final handler = useCaseTestHandler(HelloWorld.fromJson);
final response = await handler({'name': 'World'});
expect(response.statusCode, 200);
expect(response.body['message'], 'Hello, World!');
});
}
dart test
Architecture #
HTTP Request → ModularApi → Module → UseCase → Business Logic → Output → HTTP Response
- UseCase layer — pure logic, independent of HTTP
- HTTP adapter — turns a UseCase into a Shelf Handler
- Middlewares — cross-cutting concerns (CORS, logging)
- Swagger UI — documentation served automatically
Documentation #
- AGENTS.md — Framework guide (AI-optimized)
- doc/INDEX.md — Documentation index
- doc/usecase_dto_guide.md — Creating Input/Output DTOs
- doc/usecase_implementation.md — Implementing UseCases
- doc/testing_guide.md — Testing guide
Compile to executable #
dart compile exe bin/main.dart -o build/server
License #
MIT © ccisne.dev