feat: NotarizedResource plugin

This commit is contained in:
Geir Sagberg
2022-11-09 14:11:42 +01:00
committed by GitHub
parent 01b6b59cf5
commit 3c57c8f5e4
8 changed files with 350 additions and 44 deletions

View File

@ -4,6 +4,12 @@ You can read more about it [here](https://ktor.io/docs/type-safe-routing.html).
Kompendium supports Ktor-Resources through an ancillary module `kompendium-resources`
{% hint style="warning" %}
The resources module contains _two_ plugins: `KompendiumResources` and `KompendiumResource`. You will find more
information on both below, but in a nutshell, the former is an application level plugin intended to define your entire
application, while the latter is a route level approach should you wish to split out your route definitions.
{% endhint %}
## Adding the Artifact
Prior to documenting your resources, you will need to add the artifact to your gradle build file.
@ -14,9 +20,11 @@ dependencies {
}
```
## Installing Plugin
## NotarizedResources
Once you have installed the dependency, you can install the plugin. The `NotarizedResources` plugin is an _application_ level plugin, and **must** be install after both the `NotarizedApplication` plugin and the Ktor `Resources` plugin.
The `NotarizedResources` plugin is an _application_ level plugin, and **must** be installed after both the
`NotarizedApplication` plugin and the Ktor `Resources` plugin. It is intended to be used to document your entire
application in a single block.
```kotlin
private fun Application.mainModule() {
@ -54,7 +62,64 @@ private fun Application.mainModule() {
}
```
Here, the `resources` property is a map of `KClass<*>` to `ResourceMetadata` instance describing that resource. This metadata is functionally identical to how a standard `NotarizedRoute` is defined.
Here, the `resources` property is a map of `KClass<*>` to `ResourceMetadata` instance describing that resource. This
metadata is functionally identical to how a standard `NotarizedRoute` is defined.
> ⚠️ If you try to map a class that is not annotated with the ktor `@Resource` annotation, you will get a runtime
> exception!
{% hint style="danger" %}
If you try to map a class that is not annotated with the ktor `@Resource` annotation, you will get a runtime exception!
{% endhint %}
## NotarizedResource
If you prefer a route-based approach similar to `NotarizedRoute`, you can use the `NotarizedResource<MyResourceType>()`
plugin instead of `NotarizedResources`. It will combine paths from any parent route with the route defined in the
resource, exactly as Ktor itself does:
```kotlin
@Serializable
@Resource("/list/{name}/page/{page}")
data class Listing(val name: String, val page: Int)
private fun Application.mainModule() {
install(Resources)
route("/api") {
listingDocumentation()
get<Listing> { listing ->
call.respondText("Listing ${listing.name}, page ${listing.page}")
}
}
}
private fun Route.listingDocumentation() {
install(NotarizedResource<Listing>()) {
parameters = listOf(
Parameter(
name = "name",
`in` = Parameter.Location.path,
schema = TypeDefinition.STRING
),
Parameter(
name = "page",
`in` = Parameter.Location.path,
schema = TypeDefinition.INT
)
)
get = GetInfo.builder {
summary("Get user by id")
description("A very neat endpoint!")
response {
responseCode(HttpStatusCode.OK)
responseType<ExampleResponse>()
description("Will return whether or not the user is real 😱")
}
}
}
}
```
In this case, the generated path will be `/api/list/{name}/page/{page}`, combining the route prefix with the path in the
resource.
{% hint style="danger" %}
If you try to map a class that is not annotated with the ktor `@Resource` annotation, you will get a runtime exception!
{% endhint %}