seanleblanc
07/01/2025, 8:37 PMjdaugherty
07/02/2025, 12:54 PMimplementation "io.swagger.core.v3:swagger-annotations:${swaggerVersion}"
to annotate our comamnds, etc.jdaugherty
07/02/2025, 12:54 PMjdaugherty
07/02/2025, 12:54 PMmuser
07/02/2025, 5:17 PMcjchalmers
07/13/2025, 3:06 PMjdaugherty
07/13/2025, 3:32 PMopenapi.yaml
This file contains all of the app info since we don't use the annotations on the application, etc (only controllers and associated components), so something like this:
#file: noinspection YAMLSchemaValidation
openapi: 3.0.1
info:
title: My API Name
description: |
Markdown syntax here to describe your API
version: API_VERSION
x-logo:
url: URL Logo
href: URL Website
servers:
- url: example link to your api
description: Production API
variables: {}
security:
- Bearer: []
# use use x-tagGroups: & tags: since we use redoc to render our api spec
components:
securitySchemes:
Bearer:
type: http
description: description of your security scheme, any caveats
scheme: bearer
bearerFormat: JWTThen in our gradle file:
tasks.register('updateOpenAPIVersion', Copy) {
from "openapi.yaml"
into "$buildDir/tmp"
filter { line -> line.replaceAll('API_VERSION', project.version) }
}
// Generates api spec that we serve up via redoc
// However, you can also generate static documentation, install the redoc-cli via 'npm i -g redoc-cli'
// Run 'gradle resolve' and then 'redoc-cli build build/resources/main/openapi/my-api-name.yaml -o build/my-api-name.html'
//
resolve {
dependsOn(tasks.updateOpenAPIVersion, classes)
classpath = sourceSets.main.runtimeClasspath
outputDir = file("$buildDir/resources/main/openapi")
outputFileName = 'my-api-name.yaml'
openApiFile = file("$buildDir/tmp/openapi.yaml")
outputFormat = 'YAML'
resourcePackages = ['com.example'] # packages to search for the annotations
readAllResources = false
prettyPrint = true
}
bootJarMainClassName {
dependsOn(resolve)
}
dependencies {
// other dependencies
implementation "io.swagger.core.v3swagger annotations${swaggerVersion}"
implementation "javax.ws.rs:javax.ws.rs-api:2.1.1"
}
jdaugherty
07/13/2025, 3:34 PM```@Secured(AuthenticatedVoter.IS_AUTHENTICATED_ANONYMOUSLY)
class RedocController {
def index() {
Resource redocHtml = ApplicationContextHolder.applicationContext.getResource("classpath:redoc/index.html")
try(InputStreamReader reader = new InputStreamReader(redocHtml.inputStream)) {
render(text: reader.text, contentType: "text/html", encoding: "UTF-8")
}
}
def definition() {
Resource apiYaml = ApplicationContextHolder.applicationContext.getResource("classpath:openapi/my-api-name.yaml")
try(InputStreamReader reader = new InputStreamReader(apiYaml.inputStream)) {
render(text: reader.text, contentType: "application/x-yaml", encoding: "UTF-8")
}
}
}```with a index.html similar to this:
<!DOCTYPE html>
<html lang="en">
<head>
<title>My API Name | API Reference</title>
<!-- needed for adaptive design -->
<meta charset='UTF-8'/>
<meta name='viewport' content='width=device-width, initial-scale=1'/>
<!-- prevent IE from caching this page -->
<meta http-equiv="Cache-Control" content="no-store"/>
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="-1">
<!-- force this page to be rendered with the latest version of IE -->
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="layout" content="none"/>
<link href='https://fonts.googleapis.com/css?family=Montserrat:300,400,700%7CRoboto:300,400,700' rel='stylesheet'/>
<!-- ReDoc doesn't change outer page styles -->
<style>
body {
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<redoc spec-url='/definition' path-in-middle-panel="true" expand-responses="all" showObjectSchemaExamples="true" showExtensions="true"></redoc>
<script src='https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js'></script>
</body>
</html>
jdaugherty
07/13/2025, 3:35 PMjdaugherty
07/13/2025, 3:36 PMplugins {
id "io.swagger.core.v3.swagger-gradle-plugin"
}
jdaugherty
07/13/2025, 3:36 PMcjchalmers
07/14/2025, 7:37 AM