Introduction
When consuming large REST APIs, it requires writing a lot of boilerplate code to support all required endpoints. To make your life easier, you can use generators to automatically create type-safe production code for your apps. I’ll show you how to do this in this article. All it takes are 5 minutes of setup and you can enjoy the best way to consume APIs in your apps.
Requirements
This approach only works if the API source offers an open API specification file to generate the code. It can be either in json or yaml format and is usually available for download in the documentation of the API.
Generators
Open API generators are available for many programming languages. In this example, we’ll focus on Dart code. You need the packages openapi_generator and openapi_generator_annotations.
dependencies:
openapi_generator_annotations: ^latest
dev_dependencies:
openapi_generator: ^latest
Under the hood, these tools use the openapi-generator base library written in Java. If you develop for Android, chances are high that it is already installed on your system. Otherwise, you have to install it.
Generating API packages
The generator parses the specification file and creates a package to consume the api. You can store this in your project, on GitHub, or even on pub.dev or your own package repository to reuse.
Instructions for the generator are supplied via annotations. Here is an example:
import 'package:openapi_generator_annotations/openapi_generator_annotations.dart';
@Openapi(
additionalProperties: AdditionalProperties(pubName: "park_api", ),
inputSpec: InputSpec(path: "lib/api/specs/document.json"),
generatorName: Generator.dart,
outputDirectory: 'packages/park_api',
)
class ParkApiExample {}
This is a minimal form but there are many more options to configure the generator.
pubName
is the name of the generated package- The
InputSpec
path tells the generator where it can find the specification file. There is also aRemoteSpec
object which accepts a URL path. generatorName
defines what underlying library is used for HTTP requests. In Dart, you change choose between http (Generator.dart
) and dio (Generator.dio
).- With the
outputDirectory
you can specify where to put the generated files.
You can put this file anywhere and also include multiple specifications in it.
To create the package, run the build runner:
dart run build_runner build --delete-conflicting-outputs
After some seconds, new packages should appear in your project folder.

Have a look at the generated model classes for one of my APIs. It’s a massive list and it would take you a while to type that stuff 😉

The next step is to find out how we can use the package in our app.
Using generated packages
To use the package, you need to import it in your pubspec.yaml
first.

In my case, I created a bunch of packages for different APIs and included them all.
To access the endpoints, you need to create an instance of DefaultApi
which contains all endpoints as methods. You can then work with the API in a type-safe and object-oriented way rather than composing requests and parsing responses manually.

This approach saves you time, you’ll have fewer bugs, and the development feels easier overall. Code generators are a life-saving tool in that case as you have seen.
Dealing with code errors
The Open API Specification is quite complex to support many use cases. It is possible that the generator will create invalid code in some cases. Sometimes, it is because the API spec has a problem and sometimes, the generator doesn’t support this case yet.

If you encounter a problem, you have a few options here:
- Fix the generated code manually. This is probably the fastest approach but you have to do it every time when you rerun the generator!
- Ask the API maintainer to investigate. It can happen that a declaration is missing in the code which leads to the invalid generation.
- Open a bug in the OpenAPI Tools GitHub repo or look for possible workarounds. Filing a bug is the most time-consuming approach.
Conclusion
For large APIs, generating the code from a specification is the best way APIs in your apps. Don’t waste time writing requests and parsing responses manually. Go the type-safe way and skip the part of writing boilerplate code. Let code generators do the heavy lifting for you!
Related articles

