openapi_retrofit_generator 2.0.2 copy "openapi_retrofit_generator: ^2.0.2" to clipboard
openapi_retrofit_generator: ^2.0.2 copied to clipboard

Package that generates REST clients and data classes from OpenApi definition file

OpenAPI Retrofit Generator #

pub version Tests

Note: This package is a complete rework of swagger_parser with enhanced features, improved architecture, and better maintainability.

Generate type-safe Dart REST clients from OpenAPI/Swagger specifications

Automatically create Retrofit-based REST clients and immutable data models from your API definition files. Save hours of boilerplate coding and eliminate manual typing errors.

Platform Support #

✅ All Platforms Supported: Web, Mobile (iOS/Android), Desktop (Windows/macOS/Linux)

This is a code generator (dev dependency) that creates platform-agnostic Dart code. While pub.flutter-io.cn may not list platform badges (since the generator itself only runs during development), the generated REST clients work on all Dart platforms including Flutter Web, thanks to Dio's universal HTTP support. Your generated API clients are fully compatible with any platform your Dart/Flutter app targets.

Why OpenAPI Retrofit Generator? #

  • Full Spec Support: OpenAPI 2.0 (Swagger), 3.0, and 3.1
  • Extensively Tested: Validated with 358 distinct OpenAPI schemas across all 3 serializers in comprehensive end-to-end tests
  • Format Flexible: Works with JSON and YAML schemas
  • Remote & Local: Generate from URLs or local files
  • Multiple Serializers: Choose from json_serializable, freezed, or dart_mappable
  • Type Safe: Strongly-typed models with null safety
  • Multi-Schema: Handle multiple API definitions in one project
  • Retrofit Integration: Built on battle-tested Retrofit + Dio

Quick Start #

1. Install #

Add to your pubspec.yaml:

dependencies:
  dio: ^5.9.0
  retrofit: ^4.9.0
  json_annotation: ^4.9.0

dev_dependencies:
  openapi_retrofit_generator: ^2.0.0
  build_runner: ^2.10.0
  json_serializable: ^6.11.0
  retrofit_generator: ^10.1.0

2. Configure #

Create openapi_generator.yaml in your project root:

openapi_generator:
  schema_path: api/openapi.yaml       # Path to your OpenAPI file
  output_directory: lib/api           # Where to generate code
  json_serializer: json_serializable  # Choose: json_serializable, freezed, or dart_mappable

3. Generate #

Run the generator:

dart run openapi_retrofit_generator
dart run build_runner build -d

4. Use #

import 'package:dio/dio.dart';
import 'api/export.dart';

void main() async {
  final dio = Dio(BaseOptions(baseUrl: 'https://api.example.com'));
  final client = RestClient(dio);

  // Type-safe API calls
  final users = await client.users.listUsers();
  final user = await client.users.getUser(userId: '123');
  
  print('Found ${users.length} users');
  print('User: ${user.name}');
}

What Gets Generated? #

From a Pet Store OpenAPI spec, you get:

lib/api/
├── pets/
│   └── pets_client.dart        # @RestApi() class with all endpoints
├── models/
│   ├── pet.dart                 # Data class with toJson/fromJson
│   ├── create_pet_request.dart
│   └── pet_status.dart          # Enum for status values
├── rest_client.dart             # Root client aggregating all APIs
└── export.dart                   # Barrel export for easy imports

Example Generated Client:

@RestApi()
abstract class PetsClient {
  factory PetsClient(Dio dio) = _PetsClient;

  @GET('/pets')
  Future<List<Pet>> listPets(@Query('limit') int? limit);

  @POST('/pets')
  Future<Pet> createPet(@Body() CreatePetRequest body);

  @GET('/pets/{id}')
  Future<Pet> getPet(@Path('id') String petId);
}

Example Generated Model:

@JsonSerializable()
class Pet {
  final String id;
  final String name;
  final PetStatus status;
  
  const Pet({
    required this.id,
    required this.name,
    required this.status,
  });
  
  factory Pet.fromJson(Map<String, dynamic> json) => _$PetFromJson(json);
  Map<String, dynamic> toJson() => _$PetToJson(this);
}

Serialization Options #

Choose the serializer that best fits your project:

json_serializable (Default) #

Standard Dart JSON serialization with @JsonSerializable:

dependencies:
  json_annotation: ^4.9.0
dev_dependencies:
  json_serializable: ^6.11.0

freezed #

Immutable data classes with union types and copyWith:

dependencies:
  freezed_annotation: ^3.1.0
dev_dependencies:
  freezed: ^3.2.0

openapi_generator:
  json_serializer: freezed

dart_mappable #

Fast, type-safe mapping:

dependencies:
  dart_mappable: ^4.6.0
dev_dependencies:
  dart_mappable_builder: ^4.6.0

openapi_generator:
  json_serializer: dart_mappable

Required: When using dart_mappable, you must create a build.yaml file in your project root with the following configuration:

global_options:
  dart_mappable_builder:
    runs_before:
      - retrofit_generator
    options:
      renameMethods:
        fromJson: fromJsonString   # Can be any name except "fromJson"
        toJson: toJsonString       # Can be any name except "toJson"
        fromMap: fromJson          # Must be exactly "fromJson"
        toMap: toJson              # Must be exactly "toJson"

This configuration is automatically validated before generation to ensure compatibility with Retrofit.

Configuration #

Basic Configuration (Single Schema) #

Create openapi_generator.yaml or add to pubspec.yaml:

openapi_generator:
  # ============ REQUIRED ============
  # Input: Choose ONE of these
  schema_path: api/openapi.yaml              # Path to local OpenAPI file
  # OR
  # schema_url: https://api.example.com/openapi.json  # URL to remote OpenAPI file
  
  # Output: Must specify where to generate
  output_directory: lib/api                  # Where to generate code
  
  # ============ OPTIONAL ============
  name: my_api                               # API identifier (defaults to schema filename)
  json_serializer: json_serializable         # Serializer (default: json_serializable)
  root_client: true                          # Generate root client (default: true)
  root_client_name: RestClient               # Root client name (default: RestClient)
  client_postfix: Client                     # Client suffix (default: null)

Required: schema_path OR schema_url, and output_directory
Everything else is optional with sensible defaults.

Common Options #

openapi_generator:
  # ... basic config above ...
  
  # Code organization
  merge_clients: false                       # Combine all endpoints into one client
  put_clients_in_folder: true                # Place clients in /clients subdirectory
  export_file: true                          # Generate barrel export file
  
  # Enum handling
  unknown_enum_value: true                   # Add 'unknown' to enums for forward compatibility
  
  # HTTP options
  original_http_response: false              # Return HttpResponse<T> instead of T
  extras_parameter_by_default: false         # Add @Extras() to all methods
  
  # Tag filtering
  include_tags: [public, v2]                 # Only generate these tags
  exclude_tags: [internal, deprecated]       # Skip these tags
  default_client: api                        # Name for untagged endpoints

Multiple API Schemas #

Generate clients for multiple APIs in one project:

openapi_generator:
  # ============ REQUIRED (ROOT) ============
  # Must provide default output directory for all schemas
  output_directory: lib/api
  
  # ============ OPTIONAL (ROOT) ============
  # These settings apply to all schemas as defaults
  json_serializer: json_serializable
  client_postfix: Client
  
  # ============ REQUIRED (SCHEMES) ============
  schemes:
    # Each schema MUST have schema_path OR schema_url
    - schema_path: api/v1.yaml           # REQUIRED: input source
      name: api_v1                       # OPTIONAL: defaults to filename
      root_client_name: ApiV1Client      # OPTIONAL: overrides for this schema
      # Inherits: output_directory, json_serializer, client_postfix from root
      
    - schema_url: https://petstore.swagger.io/v2/swagger.json  # REQUIRED
      name: petstore                     # OPTIONAL
      json_serializer: freezed           # OPTIONAL: overrides root default
      client_postfix: Service            # OPTIONAL: overrides root default
      output_directory: lib/petstore     # OPTIONAL: overrides root default

Multi-schema rules:

  • Root level: output_directory is required (provides default for all schemas)
  • Schema level: Each schema requires schema_path OR schema_url
  • Inheritance: All root settings become defaults; each schema can override any option

Advanced Usage #

Command Line Arguments #

Override config file options via command line:

# Custom config file
dart run openapi_retrofit_generator -f my_config.yaml

# Override output directory
dart run openapi_retrofit_generator --output_directory lib/generated

# Override schema source
dart run openapi_retrofit_generator --schema_path api/openapi.yaml
dart run openapi_retrofit_generator --schema_url https://api.example.com/openapi.json

# Override serializer
dart run openapi_retrofit_generator --json_serializer freezed

# Help
dart run openapi_retrofit_generator -help

Using Freezed #

For freezed serializer, create build.yaml in your project root:

global_options:
  freezed:
    runs_before:
      - json_serializable
  json_serializable:
    runs_before:
      - retrofit_generator

Then run:

dart run openapi_retrofit_generator
dart run build_runner build -d

Using dart_mappable #

For dart_mappable serializer, you must create build.yaml in your project root:

global_options:
  dart_mappable_builder:
    runs_before:
      - retrofit_generator
    options:
      renameMethods:
        fromJson: fromJsonString   # Can be any name except "fromJson"
        toJson: toJsonString       # Can be any name except "toJson"
        fromMap: fromJson          # Must be exactly "fromJson"
        toMap: toJson              # Must be exactly "toJson"

This configuration is automatically validated before generation. The generator will throw an error if:

  • build.yaml is missing
  • fromMap is not renamed to fromJson
  • toMap is not renamed to toJson
  • fromJson is not renamed (or still named fromJson)
  • toJson is not renamed (or still named toJson)

Then run:

dart run openapi_retrofit_generator
dart run build_runner build -d

Interceptors & Authentication #

Add interceptors to your Dio instance for auth, logging, etc.:

final dio = Dio(BaseOptions(baseUrl: 'https://api.example.com'));

// Auth interceptor
dio.interceptors.add(InterceptorsWrapper(
  onRequest: (options, handler) {
    options.headers['Authorization'] = 'Bearer $token';
    return handler.next(options);
  },
));

// Logging
dio.interceptors.add(LogInterceptor(responseBody: true));

final client = RestClient(dio);

Error Handling #

try {
  final user = await client.users.getUser(userId: '123');
} on DioException catch (e) {
  if (e.response?.statusCode == 404) {
    print('User not found');
  } else if (e.type == DioExceptionType.connectionTimeout) {
    print('Connection timeout');
  } else {
    print('Error: ${e.message}');
  }
}

Complete Configuration Reference #

For all available configuration options, see:

Key Options #

Option Default Description
schema_path - Path to local OpenAPI file
schema_url - URL to remote OpenAPI file
output_directory - Where to generate code (required)
json_serializer json_serializable Serializer: json_serializable, freezed, dart_mappable
root_client true Generate root client aggregating all APIs
client_postfix null Suffix for client classes (e.g., Client, Api)
merge_clients false Combine all endpoints into one client
unknown_enum_value true Add unknown to enums for compatibility
include_tags [] Only generate endpoints with these tags
exclude_tags [] Skip endpoints with these tags
default_client api Name for endpoints without tags
skipped_parameters [] Parameter names to exclude
original_http_response false Return HttpResponse<T> with headers
extras_parameter_by_default false Add @Extras() to all methods

Examples #

Check out the example directory for a complete working example:

cd example
dart run openapi_retrofit_generator
dart run build_runner build -d
dart run lib/main.dart

Troubleshooting #

Build Runner Issues #

If you encounter issues with build_runner, try:

dart run build_runner clean
dart run build_runner build --delete-conflicting-outputs

Generation Errors #

Enable verbose output to debug issues:

dart run openapi_retrofit_generator --verbose

Type Errors #

Ensure your OpenAPI spec is valid:

  • Use required fields correctly
  • Define proper types (string, integer, object, etc.)
  • Add nullable: true for optional fields in OpenAPI 3.0+

Migration from swagger_parser #

This package is a complete rework of swagger_parser. To migrate:

  1. Update pubspec.yaml:

    dev_dependencies:
      openapi_retrofit_generator: ^2.0.0  # was: swagger_parser
    
  2. Update config file name and key:

    • Rename swagger_parser config key to openapi_generator in your YAML files
    • The config file is now openapi_generator.yaml (was swagger_parser.yaml)
  3. Remove deprecated configuration options:

    • Truly removed (no longer available):
      • language: kotlin - Only Dart generation is supported
      • replacement_rules - Replaced by improved automatic naming with conflict resolution. Use proper component names in your OpenAPI schema
    • Auto-handled (no longer needed, just delete them):
      • use_freezed3, use_multipart_file, enums_to_json, enums_parent_prefix, dart_mappable_convenient_when
  4. Review default changes:

    • use_x_nullable now defaults to true (was false)
    • export_file now defaults to false (was true)
  5. Regenerate your code:

    dart run openapi_retrofit_generator
    dart run build_runner build -d
    

Most configurations will work with minimal changes. See the complete changelog for details.

Contributing #

Contributions are welcome! Here's how you can help:

  • Report bugs: Open an issue with reproduction steps
  • Request features: Describe your use case and proposed solution
  • Submit PRs: Add features, fix bugs, or improve documentation
  • Write tests: Supplement E2E tests with new scenarios

Before contributing, please:

  1. Check existing issues and PRs
  2. Follow the existing code style
  3. Add tests for new features
  4. Update documentation as needed

License #

MIT License - see LICENSE file for details.

Acknowledgments #

This package is a complete rework of swagger_parser (GitHub) originally created by Carapacik. We've rebuilt the architecture from the ground up while preserving and enhancing all the features that made swagger_parser great.

Resources #

1
likes
160
points
149
downloads

Publisher

verified publisherwestito.dev

Weekly Downloads

Package that generates REST clients and data classes from OpenApi definition file

Repository (GitHub)
View/report issues

Topics

#swagger #openapi #api #generator #retrofit

Documentation

API reference

License

MIT (license)

Dependencies

args, collection, dart_mappable, dio, freezed_annotation, json_annotation, meta, path, retrofit, yaml

More

Packages that depend on openapi_retrofit_generator