modular_api 0.1.0 copy "modular_api: ^0.1.0" to clipboard
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.

example/example.dart

import 'package:modular_api/modular_api.dart';

// ─── Server ───────────────────────────────────────────────────────────────────

Future<void> main(List<String> args) async {
  final api = ModularApi(basePath: '/api', title: 'Greetings API');

  api.module('greetings', buildGreetingsModule);

  await api.serve(port: 8080);
}

// ─── Module Builder ───────────────────────────────────────────────────────────
// In a real project, this would live in its own file:
//   lib/modules/greetings/greetings_builder.dart

void buildGreetingsModule(ModuleBuilder m) {
  m.usecase('hello', HelloWorld.fromJson);
}

// ─── Input DTO ────────────────────────────────────────────────────────────────

class HelloInput implements Input {
  final String name;

  HelloInput({required this.name});

  factory HelloInput.fromJson(Map<String, dynamic> json) =>
      HelloInput(name: (json['name'] ?? '').toString());

  @override
  Map<String, dynamic> toJson() => {'name': name};

  @override
  Map<String, dynamic> toSchema() => {
        'type': 'object',
        'properties': {
          'name': {'type': 'string', 'description': 'Name to greet'},
        },
        'required': ['name'],
      };
}

// ─── Output DTO ───────────────────────────────────────────────────────────────

class HelloOutput implements Output {
  final String message;

  HelloOutput({this.message = ''});

  factory HelloOutput.fromJson(Map<String, dynamic> json) =>
      HelloOutput(message: (json['message'] ?? '').toString());

  @override
  int get statusCode => 200;

  @override
  Map<String, dynamic> toJson() => {'message': message};

  @override
  Map<String, dynamic> toSchema() => {
        'type': 'object',
        'properties': {
          'message': {'type': 'string', 'description': 'Greeting message'},
        },
        'required': ['message'],
      };
}

// ─── UseCase ──────────────────────────────────────────────────────────────────

class HelloWorld implements UseCase<HelloInput, HelloOutput> {
  @override
  final HelloInput input;

  @override
  late HelloOutput output;

  HelloWorld({required this.input}) {
    output = HelloOutput();
  }

  static HelloWorld fromJson(Map<String, dynamic> json) {
    return HelloWorld(input: HelloInput.fromJson(json));
  }

  @override
  String? validate() {
    if (input.name.isEmpty) {
      return 'name is required';
    }
    return null;
  }

  @override
  Future<void> execute() async {
    output = HelloOutput(message: 'Hello, ${input.name}!');
  }

  @override
  Map<String, dynamic> toJson() => output.toJson();
}
0
likes
160
points
130
downloads

Publisher

verified publisherccisne.dev

Weekly Downloads

Use-case centric API toolkit for Dart — Shelf UseCase base class, HTTP adapters, CORS middleware, and automatic OpenAPI documentation.

Repository (GitHub)
View/report issues

Topics

#api #openapi #macss

Documentation

API reference

License

MIT (license)

Dependencies

shelf, shelf_router, shelf_swagger_ui

More

Packages that depend on modular_api