Code generator for Alfred REST APIs with OpenAPI support, based on Pennyworth.
For a full sample, please refer to https://github.com/d-markey/pennyworth_sample.
- Annotate your REST services and REST entities using Pennyworth annotations, e.g.:
@RestEntity(title: 'User info')
class UserInfoDto {
UserInfoDto(this.userId, this.name, this.roles) : error = null;
UserInfoDto.success(User user)
: userId = user.userid,
name = user.name,
roles = user.roles.toList(),
error = null;
UserInfoDto.error(this.error)
: userId = '',
name = null,
roles = null;
final String userId;
final String? name;
final List<String>? roles;
final RestError? error;
Map toJson() => autoSerialize();
}
@RestService('/user', tags: ['USER'])
// ignore: camel_case_types
class User_v1 extends NestedOpenedApi {
@RestOperation(uri: '/:userid:alpha', summary: 'Get user info')
@RestOperation.middleware([ [RoleMiddleware, 'ADM'] ])
Future<UserInfoDto> getUserInfo(String userId) async {
final user = await _userService.getInfo(userId);
if (user == null) {
throw AlfredException(HttpStatus.notFound, 'User not found');
}
return UserInfoDto.success(user);
}
}
- In your server's main program, use Pennyworth's
OpenApiService
to register your REST services, and install theSwaggerApi
to enable Swagger UI.
final app = Alfred();
app.typeHandlers.insert(0, openApiTypeHandler);
final openApiService = setupOpenApiDocumentation_v3(app);
var apis = [
Api_v1(app.route('/api')),
SwaggerApi(app.route('/dev/open-api'), openApiService, Directory('assets/swagger-ui-4.1.2/')),
];
for (var api in apis) {
openApiService.mount(api);
}
final server = await app.listen(8080);
openApiService.addServer(server);
- Create a Dart build file to generate Alfred services, including Open API documentation.
targets:
$default:
builders:
pennyworth_builder:rest_builder:
generate_for:
- bin/**
enabled: true
builders:
# name of the builder
pennyworth_builder:rest_builder:
# library URI containing the builder
import: 'package:pennyworth_builder/pennyworth_builder.dart'
# Name of the function in the above library to call.
builder_factories: [ 'restServiceBuilder', 'restEntityBuilder' ]
# The mapping from the source extension to the generated file extension
build_extensions: { '.dart': [ '.svc.g.dart', '.dto.g.dart' ] }
# Will automatically run on any package that depends on it
auto_apply: dependents
# Generate to a hidden cache dir
build_to: cache
# Combine the parts from each builder into one part file.
applies_builders: ["source_gen|combining_builder"]
- Build your project
dart run build_runner build
- Run your app
dart run .\bin\server.dart
- Point your browser to
http://localhost:8080/dev/open-api/index.html
and start exploring your APIs!