Skip to content

Flutter Integration Tutorial

See the Flutter Example for a working demo you can run immediately.

Prerequisites

  • Flutter SDK ≥ 3.0
  • ApiSorcery CLI installed (npm i -g @apisorcery/cli)
  • Device registered (apisorcery register)
  • A .apisorceryrc.json configured for your project (Service Config)

Generated File Structure

After running apisorcery generate, the following files are created under outputDir (e.g. lib/api/auto/):

auto/
└── {service_code}/
    ├── api_{tag}.dart         # One file per Swagger tag — do NOT edit
    ├── model.dart             # All request / response model classes — do NOT edit
    ├── base.dart              # Base helpers — do NOT edit
    └── http_client/
        ├── dio_client.dart    # Dio instance setup — edit base URL here
        ├── interceptors/
        │   ├── request.dart   # ✏️ Add auth token here
        │   └── response.dart  # ✏️ Handle global errors here
        └── types/
            └── extension.dart

Re-generation

Files marked do NOT edit are overwritten every time you run apisorcery generate. Only modify files inside http_client/interceptors/.

Install Dependencies

Add to your pubspec.yaml:

yaml
dependencies:
  dio: ^5.4.0

Then run:

bash
flutter pub get

Configure Base URL

Open http_client/dio_client.dart and set your API server address:

dart
final dio = Dio(BaseOptions(
  baseUrl: 'https://your-api.com',   // ✏️ change this
  connectTimeout: const Duration(seconds: 10),
  receiveTimeout: const Duration(seconds: 30),
));

Configure Auth Token

Open http_client/interceptors/request.dart and inject your token:

dart
@override
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
  final token = YourAuthService.getToken(); // ✏️ use your own token source
  if (token != null) {
    options.headers['Authorization'] = 'Bearer $token';
  }
  handler.next(options);
}

Open http_client/interceptors/response.dart to handle auth errors globally:

dart
@override
void onError(DioException err, ErrorInterceptorHandler handler) {
  if (err.response?.statusCode == 401) {
    // ✏️ redirect to login
  }
  handler.next(err);
}

Using the Generated APIs

dart
import 'package:your_app/api/auto/demo/api_user.dart';
import 'package:your_app/api/auto/demo/model.dart';

// Call a generated method — all parameters are strongly typed
final users = await ApiUser.getUserList(UserPageQueryDto(page: 1, limit: 10));

Common Issues

returnLevel — which value should I use?

Most backends wrap responses in a common envelope like { code, data, message }. Use "returnLevel": "second" (the default) to unwrap the inner data field automatically. If your API returns the payload directly without a wrapper, use "returnLevel": "first".

Chinese tag names generate uncompilable class names

If your Swagger spec uses Chinese tags (e.g. 用户管理), add a tagNameMap to your service config:

json
"tagNameMap": { "用户管理": "User", "订单管理": "Order" }

See Service Config for details.