Generate Dart/Flutter REST API Clients from OpenAPI with Gemini CLI
Learn how to use Gemini CLI to automatically generate robust Dart/Flutter HTTP clients from your OpenAPI specifications.
Posted on: 2026-03-12 by AI Assistant

Integrating REST APIs into your Dart or Flutter applications can sometimes feel like a chore. Manually writing data models, handling HTTP requests, and dealing with JSON serialization is repetitive and prone to errors. But what if you could automate this entire process using an OpenAPI specification and a powerful AI assistant?
In this post, we’ll explore how to leverage the Gemini CLI to automatically generate a complete, robust HTTP client for your Dart/Flutter projects based on an OpenAPI (Swagger) spec.
Why Automate API Client Generation?
Before we dive into the “how,” let’s quickly cover the “why”:
- Speed: Generating code takes seconds; writing it takes hours.
- Accuracy: Automated generation ensures your Dart models perfectly match the API specification, reducing runtime errors.
- Maintainability: When the API changes, you simply regenerate the client instead of hunting down manual updates across your codebase.
- Consistency: Generated code follows a uniform structure, making it easier for teams to understand and maintain.
Prerequisites
To follow along, you’ll need:
- A Dart or Flutter project set up.
- Gemini CLI installed and authenticated.
- An OpenAPI specification file (e.g.,
openapi.yamlorswagger.json) for the API you want to consume.
Step 1: Prepare Your OpenAPI Spec
Ensure you have your OpenAPI specification file ready in your project directory. For this example, let’s assume you have a file named petstore-openapi.yaml.
Step 2: Use Gemini CLI to Generate the Client
The beauty of Gemini CLI is that you can interact with it using natural language, providing it with context (your files) and instructions.
Open your terminal in your project’s root directory and run a command similar to this:
gemini -p "Read the OpenAPI spec in petstore-openapi.yaml. Generate a complete Dart HTTP client for this API. Include necessary data models using json_serializable, and use the 'http' or 'dio' package for making network requests. Put the generated code in the lib/src/api directory."
What’s happening here?
- Context: We are telling Gemini to read the
petstore-openapi.yamlfile. - Instruction: We are explicitly asking for a Dart HTTP client.
- Specifics: We specify our preferred packages (
json_serializablefor models,dioorhttpfor networking) and where to save the files.
Step 3: Review and Refine
Gemini CLI will analyze the spec, generate the Dart code, and create the necessary files in your lib/src/api directory (or wherever you specified).
It’s crucial to review the generated code:
- Check the data models to ensure they correctly map to the API schema.
- Review the API service class to confirm the endpoints, methods, and parameters are accurate.
If the generated code isn’t quite right (for example, if it missed a specific authentication header requirement), you can iteratively prompt Gemini to refine it:
gemini -p "Update the generated API client in lib/src/api to include a Bearer token in the Authorization header for all requests."
Step 4: Run Build Runner
Since we requested the use of json_serializable (a common and recommended practice in Dart), you’ll need to run the build runner to generate the .g.dart files:
dart run build_runner build --delete-conflicting-outputs
(Or flutter pub run build_runner build if you are in a Flutter project).
Step 5: Integrate into Your App
Now you can import and use your newly generated client!
import 'package:your_app/src/api/petstore_client.dart';
import 'package:your_app/src/api/models/pet.dart';
void main() async {
final apiClient = PetstoreClient(baseUrl: 'https://petstore.swagger.io/v2');
try {
Pet myPet = await apiClient.getPetById(123);
print('Found pet: ${myPet.name}');
} catch (e) {
print('Error fetching pet: $e');
}
}
Conclusion
By combining the standardized structure of OpenAPI with the code-generation capabilities of Gemini CLI, you can drastically reduce the boilerplate code required to consume REST APIs in your Dart and Flutter apps. This allows you to focus more on building features and less on plumbing.
Give it a try on your next project and see how much time it saves!