Making Flutter and REST API Work Together — Building Dart Types from Swagger/OpenAPI Schemas (Part 6)

Alex Josef Bigler
Full Struggle Developer
5 min readMar 28, 2023

Imagine that you’re trying to create a Flutter application using REST API, and suddenly you realize that you need to manually create several thousand lines of code. How would you feel? I would say, as usual, because most developers know that this can be extremely tedious and time-consuming.

This is where code generation can be a real blessing. It can significantly reduce the time spent on creating code and allow you to focus on other aspects of development. But as I mentioned in my first article, using code generators can lead to problems if you don’t know how the code works.

That’s why in this article, we’ll look at how to use Swagger Codegen and other tools to automatically generate Dart code to support REST API in a Flutter application.

The following posts are suggested reading for this post to get you started:

Install

Before we start generating code, we need to install Swagger Codegen. This is a command-line tool that allows us to generate client code based on the Swagger specification. Swagger Codegen supports many programming languages, including Dart, which is used in Flutter.

To install Swagger Codegen, go to the official Swagger website: https://swagger.io/tools/swagger-codegen/. Select the platform you need and follow the instructions for installation.

However, since we decided to write code within our IDE from the very beginning, we can install Swagger Codegen through the command line using the following command (for MacOS):

brew install swagger-codegen

Please note that the first installation may take a long time.

Generate

Code generation starts with obtaining a link to the Swagger specification that we want to use for generating the client-side code. As an example, we will be using the Swagger specification for the Petstore API, which is available at https://petstore.swagger.io/v2/swagger.json.

Here’s the command to run in the root folder:

swagger-codegen generate -i https://petstore.swagger.io/v2/swagger.json -l dart -o ./lib/swagger

This command generates Dart client code based on the Petstore API Swagger specification and saves the generated files in the swagger directory inside the lib directory of the Flutter project. Remember to create the swagger directory beforehand.

After the command is executed, we look at the IDE and see a wonderful picture like this:

It seems that the IDE window, full of red errors, looks like a Christmas tree, only instead of lights, there are red error bulbs, and each bulb will require manually rewriting the code.

Yes, that’s because Swagger Codegen still doesn’t have null-safety support for Dart. You could rewrite all the problematic code yourself, leave a new issue in the developers’ repository, or bump the old one (https://github.com/swagger-api/swagger-codegen/issues/11294). But I have a better idea.

Delete

For those of you who are following this manual line by line, there may be some frustration right now. But it’s necessary. Trust me, dude.

Repeat

Since we are determined to save time by using code generation (despite the unsuccessful first attempt, well, it happens, no need to complain), let’s not rush to write code manually and use an alternative tool — the Swagger Dart Code Generator from EPAM (guys, reach out to me 📞).

To use the Swagger Dart Code Generator, add the following dependencies to the pubspec.yaml file of your project:

dependencies:
chopper: ^6.1.1
json_annotation: ^4.8.0

dev_dependencies:
build_runner: ^2.3.3
chopper_generator: ^6.0.0
json_serializable: ^6.6.1
swagger_dart_code_generator: ^2.10.3
analyzer: ^5.10.0

Then create a build.yaml file in the root directory of your project with the following contents:

targets:
$default:
builders:
swagger_dart_code_generator:
options:
input_folder: 'lib/swaggers/'
output_folder: 'lib/generated_code/'
input_urls: ['https://petstore.swagger.io/v2/swagger.json']

I’ll save you 30 seconds and say the obvious — don’t forget to create the directories that you specify in the configuration.

We run the following command in the terminal:

flutter pub run build_runner build

We get the following result:

This looks much better, there are no obvious errors.

For each .swagger downloaded file, three output files will be created:

  • .dart, generated by Swagger Dart Code Generator, containing all models, requests, converters, enums, enum mappings, etc.
  • .chopper.dart — generated by Chopper.
  • .g.dart — generated by json_serializable.

What does all of this mean? Actually, it’s not clear yet, except that the client code we’re interested in is located in the swagger.swagger.dart file, which contains over 1000 lines of code and bunch of abstract classes...

Indeed, we got the result. From the very beginning, we had a plan that we adhered to 🤡.

In popular tutorials, as well as in vanilla melodramas, it is customary to end any article on a happy note. For example, to confirm that all your code works, even by outputting one miserable print(). But we are underground, dude.

The truth, nothing but the truth.

In conclusion

Using code generators has its advantages, but also risks. Swagger Codegen, despite its popularity, does not yet support null-safety, which can be a problem for some projects (like ours). However, there are alternatives, such as Swagger Dart Code Generator, which can solve this problem.

Nonetheless, the generated code contains abstract classes and many lines of code, so to fully understand and use its capabilities, additional work is required. In any case, choosing code generation tools should be conscious and justified, and depend on the specific requirements of the project and your experience.

Subscribe to stay up to date on new materials!

--

--

Alex Josef Bigler
Full Struggle Developer

Enthusiast of new technologies, entrepreneur, and researcher. Writing about IT, economics, and other stuff. Exploring the world through the lens of data.