aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--server/core/build.gradle.kts4
-rw-r--r--server/core/src/main/kotlin/moe/nea/ledger/server/core/Application.kt11
-rw-r--r--server/swagger/src/main/kotlin/moe/nea/ledger/server/core/api/docs.kt27
3 files changed, 38 insertions, 4 deletions
diff --git a/server/core/build.gradle.kts b/server/core/build.gradle.kts
index deee068..f254df1 100644
--- a/server/core/build.gradle.kts
+++ b/server/core/build.gradle.kts
@@ -2,6 +2,7 @@ plugins {
kotlin("jvm")
kotlin("plugin.serialization")
application
+ id("com.github.gmazzo.buildconfig")
}
@@ -29,3 +30,6 @@ application {
"-Dledger.databasefolder=${project(":mod").file("run/money-ledger").absoluteFile}")
mainClass.set("moe.nea.ledger.server.core.ApplicationKt")
}
+buildConfig {
+ packageName("moe.nea.ledger.gen")
+}
diff --git a/server/core/src/main/kotlin/moe/nea/ledger/server/core/Application.kt b/server/core/src/main/kotlin/moe/nea/ledger/server/core/Application.kt
index 56492db..eef43d6 100644
--- a/server/core/src/main/kotlin/moe/nea/ledger/server/core/Application.kt
+++ b/server/core/src/main/kotlin/moe/nea/ledger/server/core/Application.kt
@@ -12,11 +12,14 @@ import io.ktor.server.routing.route
import io.ktor.server.routing.routing
import kotlinx.serialization.json.Json
import moe.nea.ledger.database.Database
+import moe.nea.ledger.gen.BuildConfig
import moe.nea.ledger.server.core.api.Documentation
import moe.nea.ledger.server.core.api.Info
+import moe.nea.ledger.server.core.api.Server
import moe.nea.ledger.server.core.api.apiRouting
import moe.nea.ledger.server.core.api.openApiDocsJson
import moe.nea.ledger.server.core.api.openApiUi
+import moe.nea.ledger.server.core.api.setApiRoot
import java.io.File
fun main(args: Array<String>) {
@@ -30,7 +33,10 @@ fun Application.module() {
info = Info(
"Ledger Analysis Server",
"Your local API for loading ledger data",
- "TODO: buildconfig"
+ BuildConfig.VERSION
+ )
+ servers.add(
+ Server("http://localhost:8080/api", "Your Local Server")
)
}
install(ContentNegotiation) {
@@ -44,8 +50,9 @@ fun Application.module() {
database.loadAndUpgrade()
routing {
route("/api") {
- this.apiRouting(database)
+ setApiRoot()
get { call.respondRedirect("/openapi/") }
+ apiRouting(database)
}
route("/api.json") {
openApiDocsJson()
diff --git a/server/swagger/src/main/kotlin/moe/nea/ledger/server/core/api/docs.kt b/server/swagger/src/main/kotlin/moe/nea/ledger/server/core/api/docs.kt
index fd63f81..5d222ee 100644
--- a/server/swagger/src/main/kotlin/moe/nea/ledger/server/core/api/docs.kt
+++ b/server/swagger/src/main/kotlin/moe/nea/ledger/server/core/api/docs.kt
@@ -7,6 +7,8 @@ import io.ktor.http.content.OutgoingContent
import io.ktor.http.defaultForFilePath
import io.ktor.server.application.ApplicationCallPipeline
import io.ktor.server.application.BaseApplicationPlugin
+import io.ktor.server.application.host
+import io.ktor.server.application.port
import io.ktor.server.response.respond
import io.ktor.server.response.respondText
import io.ktor.server.routing.HttpMethodRouteSelector
@@ -239,6 +241,12 @@ class Documentation(config: Configuration) {
override fun install(pipeline: ApplicationCallPipeline, configure: Configuration.() -> Unit): Documentation {
val config = Configuration().also(configure)
+ if (config.servers.isEmpty()) {
+ config.servers.add(Server(
+ "http://${pipeline.environment.config.host}:${pipeline.environment.config.port}",
+ "Server",
+ ))
+ }
val plugin = Documentation(config)
return plugin
}
@@ -246,6 +254,9 @@ class Documentation(config: Configuration) {
val info = config.info
var root: RoutingNode? = null
+ private set
+ val servers: List<Server> = config.servers
+
private val documentationNodes = mutableMapOf<DocumentationPath, DocumentationContext>()
fun createDocumentationNode(endpoint: DocumentationEndpoint) =
documentationNodes.getOrPut(endpoint.path) { DocumentationContext(endpoint.path) }
@@ -254,8 +265,7 @@ class Documentation(config: Configuration) {
private val openApiJson by lazy {
OpenApiModel(
info = info,
- // TODO: generate server list better
- servers = listOf(Server("http://localhost:8080", "Local Server")),
+ servers = servers,
paths = documentationNodes.map {
OpenApiPath(it.key.path) to it.value.intoJson()
}.toMap()
@@ -266,12 +276,18 @@ class Documentation(config: Configuration) {
return openApiJson
}
+ fun setRootNode(routingNode: RoutingNode) {
+ require(documentationNodes.isEmpty()) { "Cannot set API root node after routes have been documented: ${documentationNodes.keys}" }
+ this.root = routingNode
+ }
+
class Configuration {
var info: Info = Info(
title = "Example API Docs",
description = "Missing description",
version = "0.0.0"
)
+ val servers: MutableList<Server> = mutableListOf()
}
}
@@ -282,3 +298,10 @@ fun Route.docs(block: DocumentationOperationContext.() -> Unit) {
block(node)
}
+/**
+ * Mark this current routing node as API route. Note that this will not apply retroactively and all api requests must be declared relative to this one.
+ */
+fun Route.setApiRoot() {
+ plugin(Documentation).setRootNode(this as RoutingNode)
+}
+