OpenAPI
The documentation of the API (at least the backend template for now) follows the OpenAPI specification. The OpenAPI specification is generated by scanning all Spring @Controller annotations, which serve as the Single Source of Truth.
The next sections provide an overview how the documentation is integrated and explains the usage.
Available documentation endpoints
The OpenAPI documentation is exposed via two endpoints explained below. Both endpoints will be dynamically updated based on the current annotations and Javadoc present in the @Controller code.
Swagger UI
The Swagger UI provides a web-based interface for exploring and testing the documented API. It is automatically available when using springdoc-openapi-starter-webmvc-ui (which is included in the backend template by default) and can be accessed via the following path:
/swagger-ui/index.htmlor/swagger-ui(shortform)
This endpoint renders the OpenAPI specification in a user-friendly format and allows direct interaction with all available endpoints.
OpenAPI
The raw OpenAPI specification is served as machine-readable .json and .yaml. It can be retrieved from the following standard paths:
/v3/api-docs(.json) or/v3/api-docs.yaml
These endpoints are normally used for client generation, validation or export of the documentation as this is a standardized format for any OpenAPI generator.
Documenting endpoints
Currently, there are two ways to add documentation to an endpoint. Those will be further explained below.
Information
We suggest to combine both mechanisms and provide the basic API documentation via Javadoc enriched via advanced metadata where necessary using annotations.
Javadoc (suggested)
Documenting the various endpoints via Javadoc is the more intuitive way and has other benefits for generation of documentation and IDE support. By documenting a method with basic Javadoc the generator will supply information directly to the OpenAPI documentation.
Information
Using Javadoc only allows the documentation of a description, the variables used for the request and the return value. Examples for a request are automatically created with default values.
More information about the Javadoc integration can be found in the official Springdoc documentation.
Example:
/**
* This text is used as a description for the following request.
* @param someId describes the path variable used for this request.
* @return explains the return value of the request.
*/
@GetMapping("{someId}")
@ResponseStatus(HttpStatus.OK)
public SomeEntity getEndpoint(@PathVariable("someId") final UUID someId) {
return service.doSth(someId);
}Swagger Annotations
In addition to Javadoc, it's possible to document endpoints using OpenAPI-specific annotations. This approach offers much finer control over the generated documentation, allowing for custom examples, detailed descriptions, response codes, parameter specifications, and security requirements.
Annotation-based documentation is especially useful when more structured metadata is needed, such as for standardized response objects or complex request examples.
A full list of available annotations can be found in the Swagger OpenAPI documentation
Example:
@Operation(
summary = "Your summary here",
description = "This text is used as a description for the following request.",
parameters = {
@Parameter(
name = "someId",
description = "someId for an entity",
required = true,
in = ParameterIn.PATH,
example = "a81bc81b-dead-4e5d-abff-90865d1e13b1"
)
}
)
@ApiResponses(value = {
@ApiResponse(
responseCode = "200",
description = "Entity for someId was found"
),
@ApiResponse(responseCode = "404", description = "SomeEntity not found"),
})
@GetMapping("{someId}")
@ResponseStatus(HttpStatus.OK)
public SomeEntity getEndpoint(@PathVariable("someId") final UUID someId) {
return service.doSth(someId);
}Generating API specification
An OpenAPI specification for the backend API layer (e.g. controllers and DTOs) can be generated locally as a .yaml file using the Springdoc Maven plugin.
This is useful for different use-cases e.g.:
- OpenAPI-based client generation
- External documentation processing
The export is performed in the backend via the following command:
mvn springdoc-openapi:generateInformation
The backend component must be running during this process, because the plugin fetches the OpenAPI specification via its /v3/api-docs endpoint.
Every controller should be annotated as follows:
@RequestMapping(..., produces = MediaType.APPLICATION_JSON_VALUE)Additionally, every secured controller should include:
@SecurityRequirement(name = OpenAPIDocumentationConfiguration.SECURITY_SCHEME_NAME)On the @RequestMapping, the produces media type is explicitly defined to ensure that the generated specification uses the correct media type (application/json) instead of the generic */*. The @SecurityRequirement annotation indicates that this controller is secured using the global SecurityConfiguration. Adjust this as required based on the projects security setup. Neither of these annotations affects OpenAPI client generation. They only improve the accuracy and completeness of the generated specification.
The OpenAPI .yaml file is saved in the backends api-spec folder. The filename is derived from the Maven artifact defined inside the pom.xml. By default, this file is and should be kept under version control as it may be used inside the following step.
IMPORTANT
Changing the name or location via plugin configuration is highly discouraged, as other features (e.g. client generation) might depend on the default configuration. As any generated file, the OpenAPI specification must not be edited. Instead, it should be regenerated from backend sources using the previously described Maven plugin.
Generating API client from specification
The generator is configured via the openapitools.json file in the frontend / webcomponent project, which references the exported OpenAPI specification from the backend. The generated API specification from the previous step can be used to generate API clients for the frontend or webcomponent template. For this purpose the @openapitools/openapi-generator-cli dependency is used, which can be executed manually via the pre-build script. It's also automatically called when using the build or lint script.
"scripts": {
...
"pre-build": "openapi-generator-cli generate",
...
},Usage behind a proxy
When using a proxy, it might be necessary to run the provided script after installing the dependency. This script downloads the required artifact that includes the generator logic. It automatically extracts the relevant version from the openapitools.json, downloads the required .jar and places into the projects node_modules folder. The NPM dependency only provides a wrapper around this .jar.
./download-openapi-jar.sh./download-openapi-jar.batThe script needs to be executed each time the version inside the openapitools.json is changed.
Typical workflow
- Generate / Update the OpenAPI specification in the backend (see Generating API specification)
- Run
npm run buildornpm run lintinside the frontend or webcomponent project
If multiple clients (e.g. based on different specifications) are to be generated, the configuration in openapitools.json must be adapted accordingly. Otherwise, no modifications are necessary, as the default configuration already handles standard use cases (e.g. independence from the specification filename).
Generated folder structure
After generating, the API client is placed inside the folder src/api/generated/<specification-filename>. The folder name is derived from the specification filename.
For each Spring controller a dedicated API class (src/api/generated/<specification-filename>/apis/*) is generated. Those should be used via the provided ApiFactory.ts and its getInstance function. All DTOs for requests and responses are generated inside the models folder. Field constraints of the Java DTOs (e.g. @NotNull or @Size) are respected in the generated TypeScript code as well.
Usage of frontend without backend
If the frontend or web component is used without a backend (and therefore without an API specification), the call of openapi-generator-cli inside the pre-build script inside the package.json needs to be removed.
"scripts": {
...
"pre-build": "openapi-generator-cli generate",
"pre-build": "",
...
},No further adjustment is required.