> For the complete documentation index, see [llms.txt](https://bkbn.gitbook.io/kompendium/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://bkbn.gitbook.io/kompendium/index-1/notarized_resources.md).

# Notarized Resources

The Ktor Resources API allows users to define their routes in a type-safe manner.

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.

```kotlin
dependencies {
  implementation("io.bkbn:kompendium-resources:$version")
}
```

### NotarizedResources

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() {
  install(Resources)
  install(NotarizedApplication()) {
    spec = baseSpec
  }
  install(NotarizedResources()) {
    resources = mapOf(
      Listing::class to NotarizedResources.ResourceMetadata(
        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 😱")
          }
        }
      ),
    )
  }
}
```

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.

{% 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 %}
