diff --git a/Project.md b/Project.md index 2707fc77c..229c0b340 100644 --- a/Project.md +++ b/Project.md @@ -1,6 +1,6 @@ # Kompendium -Welcome to Kompendium, the straight-forward, minimally-invasive OpenAPI generator for Ktor. +Welcome to Kompendium, the straight-forward, non-invasive OpenAPI generator for Ktor. ## How to install @@ -21,21 +21,74 @@ In addition to publishing releases to Maven Central, a snapshot version gets pub to `main`. These can be consumed by adding the repository to your gradle build file. Instructions can be found [here](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-gradle-registry#using-a-published-package) -## Setting up the Kompendium Plugin +## Setting up Kompendium -Kompendium is instantiated as a Ktor Feature/Plugin. It can be added to your API as follows +Kompendium's core features are comprised of a singular application level plugin and a collection of route level plugins. +The former sets up your OpenApi spec along with various cross-route metadata and overrides such as custom types (useful +for things like datetime libraries) + +### `NotarizedApplication` plugin + +The notarized application plugin is installed at (surprise!) the app level ```kotlin private fun Application.mainModule() { - // Installs the Kompendium Plugin and sets up baseline server metadata - install(Kompendium) { - spec = OpenApiSpec(/*..*/) - } - // ... + install(NotarizedApplication()) { + spec = OpenApiSpec( + // spec details go here ... + ) + } } ``` -## Notarization +### `NotarizedRoute` plugin -The concept of notarizing routes / exceptions / etc. is central to Kompendium. More details on _how_ to notarize your -API can be found in the kompendium-core module. +Notarized routes take advantage of Ktor 2's [route specific plugin](https://ktor.io/docs/plugins.html#install-route) +feature. This allows us to take individual routes, document them, and feed them back in to the application level plugin. + +This also allows you to adopt Kompendium incrementally. Individual routes can be documented at your leisure, and is +purely +additive, meaning that you do not need to modify existing code to get documentation working, you just need new code! + +Non-invasive FTW 🚀 + +Documenting a simple `GET` endpoint would look something like this + +```kotlin +private fun Route.documentation() { + install(NotarizedRoute()) { + parameters = listOf( + Parameter( + name = "id", + `in` = Parameter.Location.path, + schema = TypeDefinition.STRING + ) + ) + get = GetInfo.builder { + summary("Get user by id") + description("A very neat endpoint!") + response { + responseCode(HttpStatusCode.OK) + responseType() + description("Will return whether or not the user is real 😱") + } + } + } +} + + +route("/{id}") { + documentation() + get { + call.respond(HttpStatusCode.OK, ExampleResponse(true)) + } +} +``` + +Full details on application and route notarization can be found in the `core` module + +## The Playground + +In addition to the documentation available here, Kompendium has a number of out-of-the-box examples available in the +playground module. Go ahead and fork the repo and run them directly on your machine to get a sense of what Kompendium +can do! diff --git a/build.gradle.kts b/build.gradle.kts index 9ae5ace4c..fcacf80d5 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,9 +1,9 @@ plugins { kotlin("jvm") version "1.7.10" apply false kotlin("plugin.serialization") version "1.7.10" apply false - id("io.bkbn.sourdough.library.jvm") version "0.9.0" apply false - id("io.bkbn.sourdough.application.jvm") version "0.9.0" apply false - id("io.bkbn.sourdough.root") version "0.9.0" + id("io.bkbn.sourdough.library.jvm") version "0.9.1" apply false + id("io.bkbn.sourdough.application.jvm") version "0.9.1" apply false + id("io.bkbn.sourdough.root") version "0.9.1" id("com.github.jakemarsden.git-hooks") version "0.0.2" id("org.jetbrains.dokka") version "1.7.10" id("org.jetbrains.kotlinx.kover") version "0.5.1" diff --git a/core/Module.md b/core/Module.md index 6224a2668..7d025f424 100644 --- a/core/Module.md +++ b/core/Module.md @@ -6,12 +6,14 @@ It is also the only mandatory client-facing module for a basic setup. # Package io.bkbn.kompendium.core -The root package contains several objects that power Kompendium, including the Kompendium Ktor Plugin, route -notarization methods, and the reflection engine that analyzes method info type parameters. +## Plugins -## Plugin +As mentioned in the root documentation, there are two core Kompendium plugins. -The Kompendium plugin is an extremely light-weight plugin, with only a couple areas of customization. +1. The application level plugin that handles app level metadata, configuring up your OpenAPI spec, managing custom data + types, etc. +2. The route level plugin, which is how users declare the documentation for the given route. It _must_ be installed on + every route you wish to document ### Serialization @@ -23,85 +25,27 @@ serializer not listed above, please open an issue on GitHub 🙏 Note for Kotlinx ⚠️ -You will need to include the `SerializersModule` provided in `KompendiumSerializersModule` in order to serialize -any provided defaults. This comes down to how Kotlinx expects users to handle serializing `Any`. Essentially, this -serializer module will convert any `Any` serialization to be `Contextual`. This is pretty hacky, but seemed to be the -only way to get Kotlinx to play nice with serializing `Any`. If you come up with a better solution, definitely go ahead +You will need to include the `SerializersModule` provided in `KompendiumSerializersModule` in order to serialize +any provided defaults. This comes down to how Kotlinx expects users to handle serializing `Any`. Essentially, this +serializer module will convert any `Any` serialization to be `Contextual`. This is pretty hacky, but seemed to be the +only way to get Kotlinx to play nice with serializing `Any`. If you come up with a better solution, definitely go ahead and open up a PR! -## Notarization +## NotarizedApplication -Central to Kompendium is the concept of notarization. +TODO -Notarizing a route is the mechanism by which Kompendium analyzes your route types, along with provided metadata, and -converts to the expected OpenAPI format. +## NotarizedRoute -Before jumping into notarization, lets first look at a standard Ktor route - -```kotlin -routing { - get { - call.respond(HttpStatusCode.OK, BasicResponse(c = UUID.randomUUID().toString())) - } -} -``` - -Now, let's compare this to the same functionality, but notarized using Kompendium - -```kotlin -routing { - notarizedGet(simpleGetExample) { - call.respond(HttpStatusCode.OK, BasicResponse(c = UUID.randomUUID().toString())) - } -} -``` - -Pretty simple huh. But hold on... what is this `simpleGetExample`? How can I know that it is so "simple". Let's take a -look - -```kotlin -val simpleGetExample = GetInfo( - summary = "Simple, Documented GET Request", - description = "This is to showcase just how easy it is to document your Ktor API!", - responseInfo = ResponseInfo( - status = HttpStatusCode.OK, - description = "This means everything went as expected!", - examples = mapOf("demo" to BasicResponse(c = "52c099d7-8642-46cc-b34e-22f39b923cf4")) - ), - tags = setOf("Simple") -) -``` - -See, not so bad 😄 `GetInfo<*,*>` is an implementation of `MethodInfo`, a sealed interface designed to -encapsulate all the metadata required for documenting an API route. Kompendium leverages this data, along with the -provided type parameters `TParam` and `TResp` to construct the full OpenAPI Specification for your route. - -Additionally, just as a backup, each notarization method includes a "post-processing' hook that will allow you to have -final say in the generated route info prior to being attached to the spec. This can be accessed via the optional -parameter - -```kotlin -routing { - notarizedGet(simpleGetExample, postProcess = { spec -> spec }) { - call.respond(HttpStatusCode.OK, BasicResponse(c = UUID.randomUUID().toString())) - } -} -``` - -This should only be used in _extremely_ rare scenarios, but it is nice to know it is there if you need it. +TODO # Package io.bkbn.kompendium.core.metadata Houses all interfaces and types related to describing route metadata. -# Package io.bkbn.kompendium.core.parser - -Responsible for the parse of method information. Base implementation is an interface to support extensibility as shown -in the `kompendium-locations` module. - # Package io.bkbn.kompendium.core.routes -Houses any routes provided by the core module. At the moment the only supported route is to enable ReDoc support. +Houses any routes provided by the core module. At the moment the only supported route is to enable ReDoc support. # Package io.bkbn.kompendium.core.util diff --git a/docs/index.html b/docs/index.html index 28f59027d..6277c7a0c 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1 +1 @@ - + diff --git a/gradle.properties b/gradle.properties index d3d4e8ea7..fc4dd64aa 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ # Kompendium -project.version=3.0.0-alpha +project.version=3.0.0-beta # Kotlin kotlin.code.style=official # Gradle diff --git a/json-schema/Module.md b/json-schema/Module.md new file mode 100644 index 000000000..9d2604458 --- /dev/null +++ b/json-schema/Module.md @@ -0,0 +1,3 @@ +# Module kompendium-json-schema + +This module handles converting Kotlin data classes to compliant [JsonSchema](https://json-schema.org) diff --git a/locations/Module.md b/locations/Module.md index 9a1b8a32d..303440435 100644 --- a/locations/Module.md +++ b/locations/Module.md @@ -1,4 +1,3 @@ # Module kompendium-locations -Adds support for Ktor [Locations](https://ktor.io/docs/locations.html) API. Any notarized location _must_ be provided -with a `TParam` annotated with `@Location`. Nested Locations are supported +Adds support for Ktor [Locations](https://ktor.io/docs/locations.html) API. diff --git a/playground/src/main/kotlin/io/bkbn/kompendium/playground/BasicPlayground.kt b/playground/src/main/kotlin/io/bkbn/kompendium/playground/BasicPlayground.kt index 1f384d7ae..24ec31ff3 100644 --- a/playground/src/main/kotlin/io/bkbn/kompendium/playground/BasicPlayground.kt +++ b/playground/src/main/kotlin/io/bkbn/kompendium/playground/BasicPlayground.kt @@ -47,7 +47,7 @@ private fun Application.mainModule() { redoc(pageTitle = "Simple API Docs") route("/{id}") { - locationDocumentation() + documentation() get { call.respond(HttpStatusCode.OK, ExampleResponse(true)) } @@ -55,7 +55,7 @@ private fun Application.mainModule() { } } -private fun Route.locationDocumentation() { +private fun Route.documentation() { install(NotarizedRoute()) { parameters = listOf( Parameter(