Generating an OpenAPI document and SDK from Spring Boot
You have a Spring Boot API and need to generate SDKs or API documentation for other teams. Rather than writing and maintaining separate OpenAPI documents, we will walk through how to generate them directly from your Spring Boot code and then use them to create and customize an SDK.
We’ll work with real code you can run locally, building a simple bookstore API to demonstrate how to properly document API structures, including inheritance between models, endpoint definitions, response types, and error handling. The examples illustrate how Spring Boot annotations map to OpenAPI concepts, so you can see how your code translates into API specifications.
Example repository
The example below will guide you through the process of creating a Spring Boot
project, adding the necessary dependencies, writing Spring Boot controllers
with OpenAPI annotations, and generating an OpenAPI document from it. To skip
this setup and follow along with our example, clone the example
application
Setting up a Spring Boot project
First, create a new Spring Boot project using Spring Initializr
- Project: Maven
- Language: Java
- Spring Boot: 3.5.x (or the latest stable version)
- Project Metadata: Fill in as appropriate
- Dependencies: Spring Web
Download the project and extract it to your preferred directory.
Adding OpenAPI dependencies
Open the pom.xml
file and add the following dependency:
Configuring application properties
Open the src/main/resources/application.properties
file and add the following configuration:
These properties configure the application name that identifies your service, the endpoint where the OpenAPI document will be available (/api-docs
), the version of the OpenAPI document to generate, and the URL path where you can access the Swagger UI documentation (/swagger-ui.html
).
After starting your application, you can view the OpenAPI document at http://localhost:8080/api-docs
and access the interactive Swagger UI at http://localhost:8080/swagger-ui.html
.
Writing a Spring Boot application
You can find all the code for this step in the example application.
Open the src/main/java/com/bookstore/BookstoreApplication.java
file in your text editor to see where to begin when adding OpenAPI annotations to your project.
Defining the main application configuration with annotations
The BookstoreApplication
class is the entry point for the API, and it’s also where we define the main OpenAPI documentation properties:
The @OpenAPIDefinition
annotation populates the OpenAPI document with essential context for anyone who wants to use the API. The title
, version
, and description
fields describe what the API does, its current state, and how it can be used.
The @Server
annotation defines available endpoints for the API. In the example, there are two options:
- A production server at
https://api.bookstore.example.com
that uses live data - A localhost server at
http://localhost:8080
for testing with sample data
Defining data models with annotations
Next, let’s look at how you can use OpenAPI annotations to describe API data structures in the Models.java
file:
The @Schema
annotation can be used at both the class and field levels:
- At the class level,
@Schema
describes what aPublication
,Book
, orMagazine
represents in the API. - At the field level, fields like
id
andauthor
are documented with a description and example values.
The Publication
class acts as the base schema in the OpenAPI specification. By using @JsonTypeInfo
and @JsonSubTypes
, we tell OpenAPI that a Publication
can be either a Book
or Magazine
. This polymorphism is reflected in the OpenAPI document as a oneOf
schema, allowing endpoints to accept or return either type. API clients will include a type
field set to either BOOK
or MAGAZINE
to identify the publication type.
Here’s how we define an Order
class that references the Publication
schema:
The Order
class uses the @Schema
annotation to document the items
field, which references the Publication
schema. This tells OpenAPI that Orders
can contain an array of either books or magazines, using the polymorphic structure defined earlier.
For the order status, we use an enumeration:
This appears in the OpenAPI document as a string field with a set of allowed values.
Finally, we define an error response model:
Defining API endpoints with annotations
Now, let’s define the API endpoints in the PublicationsController.java
file:
The @Tag
annotation groups operations under “Publications” in the OpenAPI document. Combined with @RequestMapping("/publications")
, it tells API consumers that these endpoints handle publication-related operations.
For each endpoint method, we use annotations to document their purpose and responses:
The @Operation
and @ApiResponses
annotations document what the endpoint does and what responses to expect. For example, getPublication
is annotated to show that it returns a publication successfully (200
status) or returns an error (404
status) when the publication isn’t found.
The @Parameter
annotation describes the requirements for input parameters, such as the ID path parameter in this example.
Examining the generated OpenAPI document
Now that we’ve built the Spring Boot application, let’s generate and examine the OpenAPI document to understand how the Java code translates into API specifications.
First, install the necessary dependencies in the project and start the application with the following commands:
Download the OpenAPI document while running the application:
This command saves the OpenAPI document as openapi.yaml
in your current directory.
Let’s explore the generated OpenAPI document to see how the Spring Boot annotations translate into an OpenAPI specification.
The OpenAPI Specification version information
The OpenAPI document begins with version information:
This version is determined by the configuration in our application.properties
file. It tells API consumers which version of the OpenAPI Specification to expect.
API information
Next comes the info
object, which is generated from the @OpenAPIDefinition
annotation:
Notice how each field in the Java annotation maps directly to its counterpart in the OpenAPI document output. This one-to-one mapping makes it easy to understand how your code affects the final API documentation.
Server information
Server configurations defined with @Server
annotations appear in the servers array:
Polymorphic models
One of the more complex aspects of the API is how polymorphic models are represented. The Publication
class has been translated into a schema that supports polymorphism through a discriminator:
Key aspects to notice:
- The
@Schema
annotations provide descriptions and examples - The
@JsonTypeInfo
annotation determines the discriminator property - The
@JsonSubTypes
annotation defines the possible concrete implementations
API endpoints
Finally, let’s examine how controller methods translate into API endpoints. Here’s how the getPublication
endpoint appears in the OpenAPI document:
The mapping is clear:
- The
@Operation
annotation provides the summary and description. - Each
@ApiResponse
maps to an entry in the responses object. - The
@Parameter
annotation documents the path parameter.
Creating an SDK from the OpenAPI document
Now that we have an OpenAPI document for the Spring Boot API, we can create an SDK using Speakeasy.
First, make sure you have Speakeasy installed:
Now, generate a TypeScript SDK using the following command:
Follow the onscreen prompts to provide the configuration details for the new SDK, such as the name, schema location, and output path. Enter openapi.yaml
when prompted for the OpenAPI document location and select your preferred language (for example, TypeScript) when prompted for which language you would like to generate.
You’ll see the steps taken by Speakeasy to create the SDK in the terminal:
Speakeasy validates the OpenAPI document to check that it’s ready for code generation. Validation issues will be printed in the terminal. The generated SDK will be saved as a folder in your project.
If you get ESLint styling errors, run the speakeasy quickstart
command from outside your project.
Speakeasy also suggests improvements for your SDK using Speakeasy Suggest, which is an AI-powered tool in Speakeasy Studio. You can see suggestions by opening the link to your Speakeasy Studio workspace in the terminal:
After running this command, you’ll find the generated SDK code in the specified output directory. This SDK can be used by clients to interact with your Spring Boot API in a type safe manner.
In the SDK README.md
file, you’ll find documentation about your Speakeasy SDK. TypeScript SDKs generated with Speakeasy include an installable Model Context Protocol (MCP) server where the various SDK methods are exposed as tools that AI applications can invoke.
Your SDK documentation includes instructions for installing the MCP server.
Note that the SDK is not ready for production use. To get it production-ready, follow the steps outlined in your Speakeasy workspace.
Customizing the SDK
The example app added retry logic to the SDK’s listPublications
operation to handle network errors gracefully. This was done using one of Speakeasy’s OpenAPI extensions, x-speakeasy-retries
.
Instead of modifying the OpenAPI document directly, this extension was added to the Spring Boot controller, and the OpenAPI document and SDK were regenerated.
These imports were added to src/main/java/com/bookstore/PublicationsController.java
:
The listPublications
operation was modified to include the retry configuration:
The OpenAPI document was then regenerated:
The OpenAPI document includes the retry configuration for the listPublications
operation:
After recreating the SDK using Speakeasy:
The created SDK now includes retry logic for the listPublications
operation, automatically handling network errors and 5XX
responses.
Issues and feedback
Need some assistance or have a suggestion? Reach out to our team at support@speakeasy.com.
If you haven’t already, take a look at our blog to learn more about OpenAPI, SDK generation, and more, including:
- Native JSONL support in your SDKs
- Comprehensive SDK testing
- Model Context Protocol: TypeScript SDKs for the agentic AI ecosystem
Last updated on