chore: rollback docs due to sonatype disaster (#581)
This commit is contained in:
@ -1,125 +1,106 @@
|
||||
Kompendium enables users to enrich their payloads with additional metadata
|
||||
such as field description, deprecation, and more.
|
||||
|
||||
Enrichments, unlike annotations, are fully decoupled from the implementation of the class
|
||||
itself. As such, we can not only enable different metadata on the same class in different
|
||||
areas of the application, we can also reuse the same metadata in different areas, and even
|
||||
support enrichment of types that you do not own, or types that are not easily annotated,
|
||||
such as collections and maps.
|
||||
|
||||
A simple enrichment example looks like the following:
|
||||
Kompendium allows users to enrich their data types with additional information. This can be done by defining a
|
||||
`TypeEnrichment` object and passing it to the `enrichment` parameter of the relevant `requestType` or `responseType`.
|
||||
|
||||
```kotlin
|
||||
post = PostInfo.builder {
|
||||
summary(TestModules.defaultPathSummary)
|
||||
description(TestModules.defaultPathDescription)
|
||||
request {
|
||||
requestType(
|
||||
enrichment = ObjectEnrichment("simple") {
|
||||
TestSimpleRequest::a {
|
||||
StringEnrichment(id = "simple-enrichment") {
|
||||
description = "A simple description"
|
||||
}
|
||||
data class SimpleData(val a: String, val b: Int? = null)
|
||||
|
||||
val myEnrichment = TypeEnrichment<SimpleData>(id = "simple-enrichment") {
|
||||
SimpleData::a {
|
||||
description = "This will update the field description"
|
||||
}
|
||||
SimpleData::b {
|
||||
// Will indicate in the UI that the field will be removed soon
|
||||
deprecated = true
|
||||
}
|
||||
}
|
||||
|
||||
// In your route documentation
|
||||
fun Routing.enrichedSimpleRequest() {
|
||||
route("/example") {
|
||||
install(NotarizedRoute()) {
|
||||
parameters = TestModules.defaultParams
|
||||
post = PostInfo.builder {
|
||||
summary(TestModules.defaultPathSummary)
|
||||
description(TestModules.defaultPathDescription)
|
||||
request {
|
||||
requestType<SimpleData>(enrichment = myEnrichment) // Simply attach the enrichment to the request
|
||||
description("A test request")
|
||||
}
|
||||
TestSimpleRequest::b {
|
||||
NumberEnrichment(id = "blah-blah-blah") {
|
||||
deprecated = true
|
||||
}
|
||||
response {
|
||||
responseCode(HttpStatusCode.Created)
|
||||
responseType<TestCreatedResponse>()
|
||||
description(TestModules.defaultResponseDescription)
|
||||
}
|
||||
}
|
||||
)
|
||||
description("A test request")
|
||||
}
|
||||
response {
|
||||
responseCode(HttpStatusCode.Created)
|
||||
responseType<TestCreatedResponse>()
|
||||
description(TestModules.defaultResponseDescription)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
For more information on the various enrichment types, please see the following sections.
|
||||
{% hint style="warning" %}
|
||||
An enrichment must provide an `id` field that is unique to the data class that is being enriched. This is because
|
||||
under the hood, Kompendium appends this id to the data class identifier in order to support multiple different
|
||||
enrichments
|
||||
on the same data class.
|
||||
|
||||
## Scalar Enrichment
|
||||
If you provide duplicate ids, all but the first enrichment will be ignored, as Kompendium will view that as a cache hit,
|
||||
and skip analyzing the new enrichment.
|
||||
{% endhint %}
|
||||
|
||||
Currently, Kompendium supports enrichment of the following scalar types:
|
||||
### Nested Enrichments
|
||||
|
||||
- Boolean
|
||||
- String
|
||||
- Number
|
||||
|
||||
At the moment, all of these types extend a sealed interface `Enrichment`... as such you cannot provide
|
||||
enrichments for custom scalars like dates and times. This is a known limitation, and will be addressed
|
||||
in a future release.
|
||||
|
||||
## Object Enrichment
|
||||
|
||||
Object enrichment is the most common form of enrichment, and is used to enrich a complex type, and
|
||||
the fields of a class.
|
||||
|
||||
## Collection Enrichment
|
||||
|
||||
Collection enrichment is used to enrich a collection type, and the elements of that collection.
|
||||
Enrichments are portable and composable, meaning that we can take an enrichment for a child data class
|
||||
and apply it inside a parent data class using the `typeEnrichment` property.
|
||||
|
||||
```kotlin
|
||||
post = PostInfo.builder {
|
||||
summary(TestModules.defaultPathSummary)
|
||||
description(TestModules.defaultPathDescription)
|
||||
request {
|
||||
requestType(
|
||||
enrichment = ObjectEnrichment("simple") {
|
||||
ComplexRequest::tables {
|
||||
CollectionEnrichment<NestedComplexItem>("blah-blah") {
|
||||
description = "A nested description"
|
||||
itemEnrichment = ObjectEnrichment("nested") {
|
||||
NestedComplexItem::name {
|
||||
StringEnrichment("beleheh") {
|
||||
description = "A nested description"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
description("A test request")
|
||||
data class ParentData(val a: String, val b: ChildData)
|
||||
data class ChildData(val c: String, val d: Int? = null)
|
||||
|
||||
val childEnrichment = TypeEnrichment<ChildData>(id = "child-enrichment") {
|
||||
ChildData::c {
|
||||
description = "This will update the field description of field c on child data"
|
||||
}
|
||||
response {
|
||||
responseCode(HttpStatusCode.Created)
|
||||
responseType<TestCreatedResponse>()
|
||||
description(TestModules.defaultResponseDescription)
|
||||
ChildData::d {
|
||||
description = "This will update the field description of field d on child data"
|
||||
}
|
||||
}
|
||||
|
||||
val parentEnrichment = TypeEnrichment<ParentData>(id = "parent-enrichment") {
|
||||
ParentData::a {
|
||||
description = "This will update the field description"
|
||||
}
|
||||
ParentData::b {
|
||||
description = "This will update the field description of field b on parent data"
|
||||
typeEnrichment = childEnrichment // Will apply the child enrichment to the internals of field b
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Map Enrichment
|
||||
## Available Enrichments
|
||||
|
||||
Map enrichment is used to enrich a map type, and the keys and values of that map.
|
||||
All enrichments support the following properties:
|
||||
|
||||
```kotlin
|
||||
get = GetInfo.builder {
|
||||
summary(TestModules.defaultPathSummary)
|
||||
description(TestModules.defaultPathDescription)
|
||||
response {
|
||||
responseType<Map<String, TestSimpleRequest>>(
|
||||
enrichment = MapEnrichment("blah") {
|
||||
description = "A nested description"
|
||||
valueEnrichment = ObjectEnrichment("nested") {
|
||||
TestSimpleRequest::a {
|
||||
StringEnrichment("blah-blah-blah") {
|
||||
description = "A simple description"
|
||||
}
|
||||
}
|
||||
TestSimpleRequest::b {
|
||||
NumberEnrichment("blah-blah-blah") {
|
||||
deprecated = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
description("A good response")
|
||||
responseCode(HttpStatusCode.Created)
|
||||
}
|
||||
}
|
||||
```
|
||||
- description -> Provides a reader friendly description of the field in the object
|
||||
- deprecated -> Indicates that the field is deprecated and should not be used
|
||||
|
||||
### String
|
||||
|
||||
- minLength -> The minimum length of the string
|
||||
- maxLength -> The maximum length of the string
|
||||
- pattern -> A regex pattern that the string must match
|
||||
- contentEncoding -> The encoding of the string
|
||||
- contentMediaType -> The media type of the string
|
||||
|
||||
### Numbers
|
||||
|
||||
- minimum -> The minimum value of the number
|
||||
- maximum -> The maximum value of the number
|
||||
- exclusiveMinimum -> Indicates that the minimum value is exclusive
|
||||
- exclusiveMaximum -> Indicates that the maximum value is exclusive
|
||||
- multipleOf -> Indicates that the number must be a multiple of the provided value
|
||||
|
||||
### Arrays
|
||||
|
||||
- minItems -> The minimum number of items in the array
|
||||
- maxItems -> The maximum number of items in the array
|
||||
- uniqueItems -> Indicates that the array must contain unique items
|
||||
|
@ -9,9 +9,8 @@ you to rip out and replace the amazing code you have already written.
|
||||
| 1.X | 1 | 3.0 |
|
||||
| 2.X | 1 | 3.0 |
|
||||
| 3.X | 2 | 3.1 |
|
||||
| 4.X | 2 | 3.1 |
|
||||
|
||||
> These docs are focused solely on Kompendium 4, previous versions should be considered deprecated and no longer
|
||||
> These docs are focused solely on Kompendium 3, previous versions should be considered deprecated and no longer
|
||||
> maintained
|
||||
|
||||
# Getting Started
|
||||
@ -37,11 +36,9 @@ custom type overrides (typically useful for custom scalars such as dates and tim
|
||||
```kotlin
|
||||
private fun Application.mainModule() {
|
||||
install(NotarizedApplication()) {
|
||||
spec = {
|
||||
OpenApiSpec(
|
||||
// ...
|
||||
)
|
||||
}
|
||||
spec = OpenApiSpec(
|
||||
// ...
|
||||
)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
@ -1,6 +1,20 @@
|
||||
The Playground is a module inside the Kompendium repository that provides out of the box examples for a variety of
|
||||
Kompendium features.
|
||||
|
||||
You can find all the playground
|
||||
At the moment, the following playground applications are
|
||||
|
||||
| Example | Description |
|
||||
|--------------|------------------------------------------------------------|
|
||||
| Basic | A minimally viable Kompendium application |
|
||||
| Auth | Documenting authenticated routes |
|
||||
| Custom Types | Documenting custom scalars to be used by Kompendium |
|
||||
| Exceptions | Documenting exception responses |
|
||||
| Gson | Serialization using Gson instead of the default Kotlinx |
|
||||
| Hidden Docs | Place your generated documentation behind authorization |
|
||||
| Jackson | Serialization using Jackson instead of the default KotlinX |
|
||||
| Locations | Using the Ktor Locations API to define routes |
|
||||
| Resources | Using the Ktor Resources API to define routes |
|
||||
|
||||
You can find all of the playground
|
||||
examples [here](https://github.com/bkbnio/kompendium/tree/main/playground/src/main/kotlin/io/bkbn/kompendium/playground)
|
||||
in the Kompendium repository
|
||||
|
@ -20,22 +20,21 @@ reference [OpenAPI spec](https://spec.openapis.org/oas/v3.1.0) itself.
|
||||
For public facing APIs, having the default endpoint exposed at `/openapi.json` is totally fine. However, if you need
|
||||
more granular control over the route that exposes the generated schema, you can modify the `openApiJson` config value.
|
||||
|
||||
For example, if we want to hide our schema behind a basic auth check with a custom json encoder, we could do the
|
||||
following
|
||||
For example, if we want to hide our schema behind a basic auth check, we could do the following
|
||||
|
||||
```kotlin
|
||||
private fun Application.mainModule() {
|
||||
// Install content negotiation, auth, etc...
|
||||
install(NotarizedApplication()) {
|
||||
// ...
|
||||
specRoute = { spec, routing ->
|
||||
routing {
|
||||
authenticate("basic") {
|
||||
route("/openapi.json") {
|
||||
get {
|
||||
call.response.headers.append("Content-Type", "application/json")
|
||||
call.respondText { CustomJsonEncoder.encodeToString(spec) }
|
||||
}
|
||||
openApiJson = {
|
||||
authenticate("basic") {
|
||||
route("/openapi.json") {
|
||||
get {
|
||||
call.respond(
|
||||
HttpStatusCode.OK,
|
||||
this@route.application.attributes[KompendiumAttributes.openApiSpec]
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -75,14 +74,32 @@ This means that we only need to define our custom type once, and then Kompendium
|
||||
application.
|
||||
|
||||
> While intended for custom scalars, there is nothing stopping you from leveraging custom types to circumvent type
|
||||
> analysis on any class you choose. If you have an alternative method of generating JsonSchema definitions, you could
|
||||
> put them all in this map and effectively prevent Kompendium from having to do any reflection
|
||||
> analysis
|
||||
> on any class you choose. If you have an alternative method of generating JsonSchema definitions, you could put them
|
||||
> all
|
||||
> in this map and effectively prevent Kompendium from having to do any reflection
|
||||
|
||||
## Schema Configurator
|
||||
|
||||
Out of the box, Kompendium supports KotlinX serialization... however, in order to allow for users of other
|
||||
serialization libraries to use Kompendium, we have provided a `SchemaConfigurator` interface that allows you to
|
||||
configure how Kompendium will generate schema definitions.
|
||||
The `SchemaConfigurator` is an interface that allows users to bridge the gap between Kompendium serialization and custom
|
||||
serialization strategies that the serializer they are using for their API. For example, if you are using KotlinX
|
||||
serialization in order to convert kotlin fields from camel case to snake case, you could leverage
|
||||
the `KotlinXSchemaConfigurator` in order to instruct Kompendium on how to serialize values properly.
|
||||
|
||||
For an example of the `SchemaConfigurator` in action, please see the `KotlinxSchemaConfigurator`. This will give you
|
||||
a good idea of the additional functionality it can add based on your own serialization needs.
|
||||
```kotlin
|
||||
private fun Application.mainModule() {
|
||||
install(ContentNegotiation) {
|
||||
json(Json {
|
||||
serializersModule = KompendiumSerializersModule.module
|
||||
encodeDefaults = true
|
||||
explicitNulls = false
|
||||
})
|
||||
}
|
||||
install(NotarizedApplication()) {
|
||||
spec = baseSpec
|
||||
// Adds support for @Transient and @SerialName
|
||||
// If you are not using them this is not required.
|
||||
schemaConfigurator = KotlinXSchemaConfigurator()
|
||||
}
|
||||
}
|
||||
```
|
||||
|
@ -23,7 +23,7 @@ level plugin, and **must** be install after both the `NotarizedApplication` plug
|
||||
private fun Application.mainModule() {
|
||||
install(Locations)
|
||||
install(NotarizedApplication()) {
|
||||
spec = { baseSpec }
|
||||
spec = baseSpec
|
||||
}
|
||||
install(NotarizedLocations()) {
|
||||
locations = mapOf(
|
||||
|
@ -30,7 +30,7 @@ application in a single block.
|
||||
private fun Application.mainModule() {
|
||||
install(Resources)
|
||||
install(NotarizedApplication()) {
|
||||
spec = { baseSpec }
|
||||
spec = baseSpec
|
||||
}
|
||||
install(NotarizedResources()) {
|
||||
resources = mapOf(
|
||||
|
Reference in New Issue
Block a user