Generating Client APIs using Swagger Part 1

Miragon
4 min readAug 20, 2021

--

Also available in German at miragon.io

With each new backend release a frontend developer has to rewrite huge parts of the API client. What if there would be a solution to update the whole client in just a few seconds?

In this blog post, we're introducing Swagger’s client generation, showing how to use the generated API in React applications and pointing out how to integrate Auth0's authentication token.

To keep things simple, this topic will be divided into a series consisting of three parts:

  1. Generating Client APIs using Swagger Part 1: Integrating Swagger into Spring Boot, generating the API client and using it as part of a React web app
  2. Generating Client APIs using Swagger Part 2: Securing the endpoints using Auth0 and authorising the web client’s requests
  3. Generating Client APIs using Swagger Part 3: Using the generated API client as part of a React Native App.

Integrating Swagger in Spring Boot and generating the client

The goal of this section is to generate the API documentation of a Java Spring Boot application using Swagger, create the according TypeScript Axios Client, which encapsulates the API calls, and integrate this client into a React web app. The result will look like this:

tl;dr

  1. Clone our example-backend, start Docker and run the application using the Spring Boot no-security profile.
  2. Clone our example-webapp, install all dependencies using yarn install and run yarn generate-api in the project’s root

Step 1) Integrate Swagger into Spring Boot

All code snippets are part of our example-backend. This backend application allows managing projects, which represent an object containing the customer’s name and their address. Using the API endpoints, a client is able to create, read, update, and delete (CRUD) projects.

1a) Annotate the controllers and add information about each endpoint

After adding the springdoc-openapi-ui dependency to the dependency management file (e.g. build.gradle or pom.xml), you’ll be able use its annotations for the projects controllers.

@Slf4j
@Validated
@RestController
@RequiredArgsConstructor
@Tag(name = "Project Controller")
@RequestMapping("/api/project")
public class ProjectController {

private final ProjectService projectService;
private final ProjectApiMapper projectMapper;

@Transactional(readOnly = true)
@GetMapping
@Operation(summary = "Get list of all projects")
public ResponseEntity<List<ProjectTO>> getAllProject() {
log.debug("Received request to load all projects");
final List<Project> allProjects = this.projectService.getAllProjects();
return ResponseEntity.ok(this.projectMapper.mapToTO(allProjects));
}
...

1b) Visit the generated API documentation

  1. As described in the project’s README, both Docker services (nginx and postgres) have to run until you can start the example backend.
  2. Please make sure that you’ve enabled the no-security profile in the run configurations:
    IntelliJ → Run → Edit Configurations… → Active profiles: no-security
  3. Now you should be able open the API documentation in your browser: http://localhost:8081/swagger-ui.html
API documentation of our example project

Step 2) Generate the API Client

There are several ways to generate an API client using Swagger: You could use a Gradle or Maven plugin, use Swagger Editor or use a third-party JavaScript library. In our opinion, generating the client API should not be part of the backend. That’s why we went with the Swagger Editor in the first place and later switched to the openapi-generator-cli later on to have the benefit of strongly typed interfaces. In this section, we’ll explain both ways, using Swagger Editor and openapi-generator-cli:

a) Swagger Editor

  1. Open the URL http://localhost:8081/v3/api-docs and copy everything.
  2. Visit Swagger Editor (https://editor.swagger.io/) and paste it into the editor window → you will be asked if you want to convert it to .yaml → Accept.
  3. In the menu of Swagger Editor, you’ll find the “Generate Client” dropdown. Select “TypeScript Axios”, and wait until the download has finished.
  4. Unzip it, copy api.ts, base.ts, configuration.ts, apis-folder, and models-folder into a new folder in your frontend project.

b) Openapi-Generator-Cli

  1. Download and add @openapitools/openapi-generator-cli as dev-dependency in your webapp using the following command:
    yarn add --dev @openapitools/openapi-generator-cli
  2. Make sure that your backend is up and running.
  3. Run the following command:
yarn openapi-generator-cli generate \
-i http://localhost:8081/v3/api-docs \
-g typescript-axios \
-o src/api

Optional: Delete the files .npmignore, .gitignore, and git_push.sh, and add them to the file .openapi-generator-igonre. Add openapitools.json, and /src/api/.openapi-generator to your project’s .gitignore.

Step 3) Using the API Client in a React Web Application

To work with the generated API using an nginx as reverse proxy, you first have to set the BASE_PATH variable in src/api/base.ts to an empty string:

export const BASE_PATH = "";

Now you can fetch data from the API endpoint with just three lines of code:

const projectController = new ProjectControllerApi()
const response = await projectController.getAllProject()
const data = response.data

In our example-webapp, we encapsulated the all api-calls within a helper method to catch the errors. Additionally we’re using redux-store to cache the received data, which allows us to reduce the backend calls.

In the next part of this series, we will see how to secure the endpoints using Auth0 and authorize the web client’s requests. Stay tuned for part 2!

--

--

Miragon

We are experts in workflow automation and customized software development. We share our experiences with Camunda, Spring Boot, React, Apache Kafka and more!