
io.javalin.plugin.openapi.OpenApiOptions.kt Maven / Gradle / Ivy
The newest version!
package io.javalin.plugin.openapi
import com.fasterxml.jackson.databind.ObjectMapper
import io.javalin.core.event.HandlerMetaInfo
import io.javalin.core.security.RouteRole
import io.javalin.http.Context
import io.javalin.http.Handler
import io.javalin.http.HandlerType
import io.javalin.plugin.openapi.annotations.HttpMethod
import io.javalin.plugin.openapi.dsl.OpenApiDocumentation
import io.javalin.plugin.openapi.dsl.documented
import io.javalin.plugin.openapi.jackson.JacksonModelConverterFactory
import io.javalin.plugin.openapi.jackson.JacksonToJsonMapper
import io.javalin.plugin.openapi.jackson.ToJsonMapper
import io.javalin.plugin.openapi.ui.ReDocOptions
import io.javalin.plugin.openapi.ui.SwaggerOptions
import io.javalin.plugin.openapi.utils.LazyDefaultValue
import io.swagger.v3.oas.models.OpenAPI
import io.swagger.v3.oas.models.examples.Example
import io.swagger.v3.oas.models.info.Info
class OpenApiOptions constructor(val initialConfigurationCreator: InitialConfigurationCreator) {
/** If not null, creates a GET route to get the schema as a json */
var path: String? = null
var roles: Set = setOf()
/**
* If not null, creates a GET route to the swagger ui
* @see https://swagger.io/tools/swagger-ui/
*/
var swagger: SwaggerOptions? = null
/**
* If not null, creates a GET route to the reDoc ui
* @see https://github.com/Rebilly/ReDoc
*/
var reDoc: ReDocOptions? = null
/**
* Function that is applied to every new operation.
* You can use this to set defaults (like a 500 response).
*/
var default: DefaultDocumentation? = null
/**
* The default jackson mapper used, for "modelConverterFactory" and "toJsonMapper" if not overridden.
*/
var jacksonMapper: ObjectMapper by LazyDefaultValue { JacksonToJsonMapper.defaultObjectMapper }
/**
* Creates a model converter, which converts a class to an open api schema.
* Defaults to the jackson converter.
*/
var modelConverterFactory: ModelConverterFactory by LazyDefaultValue { JacksonModelConverterFactory(jacksonMapper) }
/**
* The json mapper for creating the object api schema json. This is separated from
* the default JavalinJson mappers.
*/
var toJsonMapper: ToJsonMapper by LazyDefaultValue { JacksonToJsonMapper(jacksonMapper) }
/**
* Function that allows modification of the OpenAPI model before it is sent to the client.
* Since the OpenAPI model is mutable, care should be taken to make sure any modifications
* are idempotent. If this is not possible, caching of the model may be disabled, but this
* incurs a performance penalty.
*/
var responseModifier: OpenApiModelModifier by LazyDefaultValue { NoOpOpenApiModelModifier() }
/**
* A list of package prefixes to scan for annotations.
*/
var packagePrefixesToScan = mutableSetOf()
/**
* Manual set the documentation of specific paths
*/
var overriddenDocumentation: MutableList = mutableListOf()
/**
* A list of paths to ignore in documentation
*/
var ignoredPaths: MutableList>> = mutableListOf()
/**
* A list of the only paths which will be considered as part of the OpenAPI documentation. If this list is empty
* it will be considered as meaning that all paths should be included with the exception of the ignored paths
*/
val includedPaths: MutableList>> = mutableListOf()
/**
* Validate the generated schema with the swagger parser
* (prints warnings if schema is invalid)
*/
var validateSchema: Boolean = false
/**
* Flag indicating whether or not the generated schema should be cached. Caching is enabled by default.
*/
var cacheSchema: Boolean = true;
constructor(info: Info) : this(InitialConfigurationCreator { OpenAPI().info(info) })
fun path(value: String) = apply { path = value }
fun disableCaching() = apply { cacheSchema = false }
fun responseModifier(value: OpenApiModelModifier) = apply { responseModifier = value }
fun swagger(value: SwaggerOptions) = apply { swagger = value }
fun reDoc(value: ReDocOptions) = apply { reDoc = value }
fun roles(vararg value: RouteRole) = apply { roles = value.toSet() }
fun defaultDocumentation(value: DefaultDocumentation) = apply { default = value }
fun defaultDocumentation(apply: (documentation: OpenApiDocumentation) -> Unit) = apply {
default = object : DefaultDocumentation {
override fun apply(documentation: OpenApiDocumentation) = apply(documentation)
}
}
fun examples(examples: Map, Map>) {
openApiExamples = examples.mapValues { it.value.toMutableMap() }.toMutableMap()
}
@JvmSynthetic
inline fun addExample(name: String, example: Example) = addExample(T::class.java, name, example)
fun addExample(clazz: Class, name: String, example: Example) {
openApiExamples.computeIfAbsent(clazz) { mutableMapOf() }[name] = example
}
/**
* Activate annotation scanning for specific package prefixes.
* This will search for `OpenApi` annotations which define the `path` and `method` * property.
* If an handler with the same path and method is added and the handler doesn't have
* any documentation or the documentation cannot be accessed by reflection, the annotation will be used.
* Currently this is just required for java method references.
*/
fun activateAnnotationScanningFor(vararg packagePrefixes: String) = apply {
packagePrefixesToScan.addAll(packagePrefixes)
}
fun jacksonMapper(value: ObjectMapper) = apply { jacksonMapper = value }
fun modelConverterFactory(value: ModelConverterFactory) = apply { modelConverterFactory = value }
fun toJsonMapper(value: ToJsonMapper) = apply { toJsonMapper = value }
fun getFullDocumentationUrl(ctx: Context) = "${ctx.contextPath()}${path!!}"
fun setDocumentation(path: String, method: HttpMethod, documentation: OpenApiDocumentation) = apply {
overriddenDocumentation.add(HandlerMetaInfo(HandlerType.valueOf(method.name), path, documented(documentation, Handler { }), emptySet()))
}
fun validateSchema(validate: Boolean = true) = apply { validateSchema = validate }
fun ignorePath(path: String, vararg httpMethod: HttpMethod) = apply {
ignoredPaths.add(Pair(path, httpMethod.asList().ifEmpty { HttpMethod.values().asList() }))
}
/**
* adds the given path and methods to the list of paths which should be scanned by OpenAPI
*
* @param path : the path to include in the paths to scan
* @param httpMethod : the list of http methods to include in the scan (as a vararg)
*/
fun includePath(path: String, vararg httpMethod: HttpMethod) = apply {
includedPaths.add(Pair(path, httpMethod.asList().ifEmpty { HttpMethod.values().asList() }))
}
}
fun OpenApiOptions(createInitialConfiguration: () -> OpenAPI) =
OpenApiOptions(InitialConfigurationCreator(createInitialConfiguration))
@FunctionalInterface
interface DefaultDocumentation {
fun apply(documentation: OpenApiDocumentation)
}
@FunctionalInterface
interface InitialConfigurationCreator {
fun create(): OpenAPI
}
fun InitialConfigurationCreator(createInitialConfiguration: () -> OpenAPI) = object : InitialConfigurationCreator {
override fun create() = createInitialConfiguration()
}
internal var openApiExamples = mutableMapOf, MutableMap>()
© 2015 - 2025 Weber Informatics LLC | Privacy Policy