Skip to content

Commit

Permalink
Start work on ktor
Browse files Browse the repository at this point in the history
  • Loading branch information
alexstaeding committed Aug 10, 2023
1 parent 92e0b35 commit 51afbff
Show file tree
Hide file tree
Showing 22 changed files with 250 additions and 8 deletions.
20 changes: 20 additions & 0 deletions app/web/backend/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,26 @@
plugins {
id("kotlin-jvm.base-conventions")
alias(libs.plugins.kotlin.serialization)
alias(libs.plugins.ktor)
}

dependencies {
commonMainImplementation(project(":guestbook-kotlin-app-web"))
commonMainImplementation(project(":guestbook-kotlin-db"))
jvmMainImplementation(libs.bundles.ktor.server)
jvmMainRuntimeOnly(libs.logging.impl)
}

application {
mainClass = "guestbook.MainKt"
}

tasks {
val runDir = file("build/run")
withType<JavaExec> {
doFirst {
runDir.mkdirs()
}
workingDir = runDir
}
}
44 changes: 44 additions & 0 deletions app/web/backend/src/jvmMain/kotlin/guestbook/ApplicationModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package guestbook

import guestbook.http.routeSession
import io.ktor.serialization.kotlinx.json.json
import io.ktor.server.application.Application
import io.ktor.server.application.install
import io.ktor.server.plugins.contentnegotiation.ContentNegotiation
import io.ktor.server.resources.Resources
import io.ktor.server.routing.routing
import io.ktor.server.sessions.SessionStorageMemory
import io.ktor.server.sessions.Sessions
import io.ktor.server.sessions.cookie
import kotlinx.serialization.json.Json

@Suppress("unused") // Referenced in application.conf
fun Application.applicationModule() {
println("Starting backend...")
install(ContentNegotiation) {
// TODO: protobuf
json(
Json {
encodeDefaults = false
ignoreUnknownKeys = true
},
)
}
// install type-safe routing
install(Resources)

install(Sessions) {
cookie<String>(
name = "user_session",
storage = SessionStorageMemory(),
) {
println("Test: ${sessionIdProvider()}")
}
}

routing {
routeSession()
}

println("Backend started!")
}
5 changes: 5 additions & 0 deletions app/web/backend/src/jvmMain/kotlin/guestbook/Main.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package guestbook

import io.ktor.server.netty.EngineMain

fun main(args: Array<String>) = EngineMain.main(args)
5 changes: 5 additions & 0 deletions app/web/backend/src/jvmMain/kotlin/guestbook/UserSession.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package guestbook

data class UserSession(
val id: String,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package guestbook.http

import io.ktor.server.routing.Route
import io.ktor.server.routing.route

fun Route.registerGuestbookRoutes() {
route("/api/guestbook") {

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package guestbook.http

import io.ktor.server.application.call
import io.ktor.server.response.respond
import io.ktor.server.routing.Route
import io.ktor.server.routing.get
import org.sourcegrade.kontour.DomainEntity
import org.sourcegrade.kontour.Repository

fun <E : DomainEntity> Route.routeGetAll(
repository: Repository<E, *>,
) {
get {
call.respond(repository)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package guestbook.http

import io.ktor.server.application.call
import io.ktor.server.routing.Route
import io.ktor.server.routing.get
import io.ktor.server.sessions.sessionId

fun Route.routeSession() {
get("/api/v1/session") {
println("Session ID: ${call.sessionId}")
}
}
9 changes: 9 additions & 0 deletions app/web/backend/src/jvmMain/resources/application.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
ktor {
development = true
deployment {
port = 80
}
application {
modules = [ guestbook.ApplicationModuleKt.applicationModule ]
}
}
27 changes: 27 additions & 0 deletions app/web/backend/src/jvmMain/resources/log4j2.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console">
<PatternLayout disableAnsi="false">
<pattern>%highlight{[%d{yy-MMM-dd HH:mm:ss}] [%p] - %m%n%throwable}{INFO=white}</pattern>
</PatternLayout>
</Console>
<RollingRandomAccessFile name="File" fileName="logs/latest.log"
filePattern="logs/%d{yyyy-MM-dd}-%i.log.gz"
immediateFlush="false">
<PatternLayout>
<pattern>[%d{yy-MMM-dd HH:mm:ss}] [%p] - %m%n%throwable</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy/>
<OnStartupTriggeringPolicy/>
</Policies>
</RollingRandomAccessFile>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console"/>
<AppenderRef ref="File"/>
</Root>
</Loggers>
</Configuration>
8 changes: 8 additions & 0 deletions app/web/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
plugins {
id("kotlin-jvm.base-conventions")
id("kotlin-js.base-conventions")
alias(libs.plugins.kotlin.serialization)
}

dependencies {
commonMainApi(project(":guestbook-kotlin-domain"))
commonMainApi(libs.redux)
commonMainApi(libs.ktor.resources)
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@ fun kotlinw(target: String): String =
"org.jetbrains.kotlin-wrappers:kotlin-$target"

dependencies {
commonMainImplementation(project(":guestbook-kotlin-domain"))
commonMainImplementation(project(":guestbook-kotlin-app-web"))

commonMainImplementation(libs.bundles.ktor.client)
commonMainImplementation(libs.redux)
jsMainImplementation(enforcedPlatform(kotlinw("wrappers-bom:1.0.0-pre.605")))

jsMainImplementation(kotlinw("react"))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package guestbook.http

import io.ktor.client.HttpClient
import org.sourcegrade.kontour.Creates
import org.sourcegrade.kontour.DomainEntity
import org.sourcegrade.kontour.Repository
import org.sourcegrade.kontour.UUID

class ClientRepository<E : DomainEntity, C : Creates<E>>(
val httpClient: HttpClient,
) : Repository<E, C> {
override suspend fun countAll(): Long {
TODO("Not yet implemented")
}

override suspend fun deleteById(id: UUID): Boolean {
TODO("Not yet implemented")
}

override suspend fun exists(id: UUID): Boolean {
TODO("Not yet implemented")
}

override suspend fun create(item: C): E {
TODO("Not yet implemented")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,11 @@ import mui.material.CssBaseline
import mui.material.PaletteMode
import mui.material.styles.ThemeProvider
import mui.material.styles.createTheme
import mui.system.sx
import org.sourcegrade.kontour.Crypto
import react.FC
import react.Props
import react.create
import react.dom.client.createRoot
import react.router.RouterProvider
import react.router.dom.HashRouter
import web.dom.document
import web.html.HTML.div

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package guestbook.ui.page

import guestbook.domain.Guestbook
import guestbook.ui.component.GuestbookBox
import guestbook.web.HomeState
import mui.material.Button
import mui.material.ButtonVariant
import mui.material.Grid
Expand All @@ -18,6 +19,9 @@ import web.cssom.Display
import web.cssom.px
import web.cssom.rem

val store = HomeState.createStore()
val unsubscribe = store.subscribe { println(store.state) }

val guestbooks = listOf(
Guestbook(
id = Crypto.randomUUID(),
Expand Down
File renamed without changes.
37 changes: 37 additions & 0 deletions app/web/src/commonMain/kotlin/guestbook.web/HomeState.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package guestbook.web

import guestbook.domain.Guestbook
import org.reduxkotlin.threadsafe.createTypedThreadSafeStore

data class HomeState(
val pageSize: Int = 10,
val offset: Long = 0,
val guestbooks: List<Guestbook> = emptyList(),
) {
companion object {
fun createStore() = createTypedThreadSafeStore(::reduce, HomeState())

private fun createInitialState(): HomeState {
TODO()
}

private fun reduce(state: HomeState, action: HomeAction): HomeState = when (action) {
is HomeAction.NextPage -> state.copy(offset = state.offset + state.pageSize)
is HomeAction.PreviousPage -> state.copy(offset = state.offset - state.pageSize)
is HomeAction.GoToPage -> state.copy(offset = action.offset)
is HomeAction.SetPageSize -> state.copy(pageSize = action.pageSize)
is HomeAction.AddGuestbook -> state.copy(guestbooks = state.guestbooks + action.guestbook)
}
}
}

sealed interface HomeAction {

// pagination
data object NextPage : HomeAction
data object PreviousPage : HomeAction
data class GoToPage(val offset: Long) : HomeAction
data class SetPageSize(val pageSize: Int) : HomeAction

data class AddGuestbook(val guestbook: Guestbook) : HomeAction
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package guestbook.web.http

import io.ktor.resources.Resource

@Resource("/api/v1/guestbook")
class GuestbookRoute {
@Resource("{id}")
class ById(val id: String)
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ object GuestbookRepositoryImpl : GuestbookRepository {
}
}

override suspend fun getById(id: UUID): Guestbook? {
return newSuspendedTransaction {
createJoin()
.select { GuestbookTable.id eq id }
.toGuestbook()
}
}

override suspend fun exists(id: UUID): Boolean {
return newSuspendedTransaction {
GuestbookTable.select { GuestbookTable.id eq id }.count() > 0
Expand Down
9 changes: 7 additions & 2 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[versions]
kotlin = "1.9.0"
ktor = "2.3.0"
ktor = "2.3.3"
log4j = "2.20.0"

[libraries]
exposed-bom = "org.jetbrains.exposed:exposed-bom:0.41.1"
Expand All @@ -10,6 +11,7 @@ exposed-jdbc = { module = "org.jetbrains.exposed:exposed-jdbc" }
exposed-java-time = { module = "org.jetbrains.exposed:exposed-java-time" }
kontour = "org.sourcegrade:kontour-domain:0.1.0-SNAPSHOT"
kotlinx-serialization = "org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.0"
ktor-resources = { module = "io.ktor:ktor-resources", version.ref = "ktor" }
ktor-client-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktor" }
ktor-client-js = { module = "io.ktor:ktor-client-js", version.ref = "ktor" }
ktor-client-resources = { module = "io.ktor:ktor-client-resources", version.ref = "ktor" }
Expand All @@ -21,13 +23,16 @@ ktor-server-netty = { module = "io.ktor:ktor-server-netty", version.ref = "ktor"
ktor-server-resources = { module = "io.ktor:ktor-server-resources", version.ref = "ktor" }
ktor-server-sessions = { module = "io.ktor:ktor-server-sessions", version.ref = "ktor" }
ktor-server-status-pages = { module = "io.ktor:ktor-server-status-pages", version.ref = "ktor" }
logging-impl = { module = "org.apache.logging.log4j:log4j-slf4j-impl", version.ref = "log4j" }
logging-core = { module = "org.apache.logging.log4j:log4j-core", version.ref = "log4j" }
redux = "org.reduxkotlin:redux-kotlin-threadsafe:0.6.1"

[bundles]
exposed = ["exposed-core", "exposed-dao", "exposed-jdbc", "exposed-java-time"]
ktor-client = ["ktor-serialization", "ktor-client-resources"]
ktor-server = ["ktor-server-auth", "ktor-server-content-negotiation", "ktor-server-cors", "ktor-server-netty", "ktor-server-resources", "ktor-server-sessions", "ktor-server-status-pages"]
ktor-server = ["ktor-serialization", "ktor-server-auth", "ktor-server-content-negotiation", "ktor-server-cors", "ktor-server-netty", "ktor-server-resources", "ktor-server-sessions", "ktor-server-status-pages"]

[plugins]
kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
ktor = { id = "io.ktor.plugin", version.ref = "ktor" }
2 changes: 1 addition & 1 deletion settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ rootProject.name = "guestbook-kotlin"
sequenceOf(
"app-web",
"app-web-backend",
"app-web-ui",
"app-web-frontend",
"db",
"domain",
).forEach {
Expand Down

0 comments on commit 51afbff

Please sign in to comment.