add server realization of post repos

This commit is contained in:
2020-08-14 12:06:37 +06:00
parent 27c06d7d9a
commit 93bd094823
11 changed files with 187 additions and 16 deletions
core
api
src
commonMain
kotlin
com
insanusmokrassar
postssystem
core
exposed
src
main
kotlin
com
insanusmokrassar
postssystem
ktor
client
src
commonMain
kotlin
com
insanusmokrassar
common
src
commonMain
kotlin
com
insanusmokrassar
postssystem
server
ktor/server/src/jvmMain/kotlin/com/insanusmokrassar/postssystem/ktor/server

@ -21,5 +21,5 @@ interface ReadContentRepo {
/**
* @return all [RegisteredContent] by pages basing on their creation date
*/
suspend fun getContentByPagination(pagination: Pagination): PaginationResult<out RegisteredContent>
suspend fun getContentByPagination(pagination: Pagination): PaginationResult<RegisteredContent>
}

@ -131,7 +131,7 @@ private class ContentRepoDatabaseTable(
select { idColumn.eq(id) }.limit(1).firstOrNull() ?.asRegisteredContent(content)
}
}
override suspend fun getContentByPagination(pagination: Pagination): PaginationResult<out RegisteredContent> {
override suspend fun getContentByPagination(pagination: Pagination): PaginationResult<RegisteredContent> {
return transaction(
db = database
) {

@ -1,18 +1,27 @@
package com.insanusmokrassar.postssystem.core.ktor.client.content
import com.insanusmokrassar.postssystem.core.content.api.*
import com.insanusmokrassar.postssystem.core.ktor.contentRootRoute
import io.ktor.client.HttpClient
import io.ktor.client.features.websocket.WebSockets
class ContentRepoKtorClient(
baseUrl: String,
client: HttpClient = HttpClient {
install(WebSockets)
}
) : ContentRepo, ReadContentRepo by ReadContentRepoKtorClient(
baseUrl,
client
), WriteContentRepo by WriteContentRepoKtorClient(
baseUrl,
client
)
class ContentRepoKtorClient private constructor(
readContentRepo: ReadContentRepo,
writeContentRepo: WriteContentRepo
) : ContentRepo, ReadContentRepo by readContentRepo, WriteContentRepo by writeContentRepo {
constructor(
baseUrl: String,
client: HttpClient = HttpClient {
install(WebSockets)
}
) : this(
ReadContentRepoKtorClient(
"$baseUrl/$contentRootRoute",
client
),
WriteContentRepoKtorClient(
"$baseUrl/$contentRootRoute",
client
)
)
}

@ -27,7 +27,7 @@ class ReadContentRepoKtorClient(
standardKtorSerialFormat.load(RegisteredContent.serializer().nullable, it)
}
override suspend fun getContentByPagination(pagination: Pagination): PaginationResult<out RegisteredContent> = client.get<ByteArray>(
override suspend fun getContentByPagination(pagination: Pagination): PaginationResult<RegisteredContent> = client.get<ByteArray>(
"$baseUrl/$getContentByPaginationRoute".includeQueryParams(
pagination.asUrlQueryParts
)

@ -1,5 +1,7 @@
package com.insanusmokrassar.postssystem.core.ktor
const val contentRootRoute = "content"
const val getContentsIdsRoute = "getContentsIds"
const val getContentByIdRoute = "getContentById"
const val getContentByPaginationRoute = "getContentByPagination"

@ -0,0 +1,26 @@
package com.insanusmokrassar.postssystem.core.ktor.server.content
import com.insanusmokrassar.postssystem.core.content.api.ContentRepo
import com.insanusmokrassar.postssystem.core.ktor.contentRootRoute
import com.insanusmokrassar.postssystem.ktor.server.configurators.ApplicationRoutingConfigurator
import io.ktor.routing.Route
import io.ktor.routing.route
fun Route.configureContentRepoRoutes(
proxyTo: ContentRepo
) {
route(
contentRootRoute
) {
configureReadContentRepoRoutes(proxyTo)
configureWriteContentRepoRoutes(proxyTo)
}
}
class ContentRepoRoutingConfigurator(
private val proxyTo: ContentRepo
) : ApplicationRoutingConfigurator.Element {
override fun Route.invoke() {
configureContentRepoRoutes(proxyTo)
}
}

@ -0,0 +1,55 @@
package com.insanusmokrassar.postssystem.core.ktor.server.content
import com.insanusmokrassar.postssystem.core.content.RegisteredContent
import com.insanusmokrassar.postssystem.core.content.api.ReadContentRepo
import com.insanusmokrassar.postssystem.core.ktor.*
import com.insanusmokrassar.postssystem.ktor.server.configurators.ApplicationRoutingConfigurator
import com.insanusmokrassar.postssystem.ktor.server.extractPagination
import com.insanusmokrassar.postssystem.ktor.server.standardKtorSerialFormatContentType
import com.insanusmokrassar.postssystem.ktor.standardKtorSerialFormat
import io.ktor.application.call
import io.ktor.http.HttpStatusCode
import io.ktor.response.respond
import io.ktor.response.respondBytes
import io.ktor.routing.*
import kotlinx.serialization.builtins.nullable
fun Route.configureReadContentRepoRoutes(
proxyTo: ReadContentRepo
) {
get(getContentsIdsRoute) {
call.respondBytes(
standardKtorSerialFormat.dump(contentIdsSerializer, proxyTo.getContentsIds()),
standardKtorSerialFormatContentType
)
}
get("$getContentByIdRoute/{id}") {
val id = call.parameters["id"].also {
if (it == null) call.respond(HttpStatusCode.BadRequest, "Request must contains id in route")
} ?: return@get
call.respondBytes(
standardKtorSerialFormat.dump(
RegisteredContent.serializer().nullable,
proxyTo.getContentById(id)
),
standardKtorSerialFormatContentType
)
}
get(getContentByPaginationRoute) {
val pagination = call.request.queryParameters.extractPagination
call.respondBytes(
standardKtorSerialFormat.dump(
registeredContentPaginationResultSerializer,
proxyTo.getContentByPagination(pagination)
)
)
}
}
class ReadContentRepoRoutingConfigurator(
private val proxyTo: ReadContentRepo
) : ApplicationRoutingConfigurator.Element {
override fun Route.invoke() {
configureReadContentRepoRoutes(proxyTo)
}
}

@ -0,0 +1,63 @@
package com.insanusmokrassar.postssystem.core.ktor.server.content
import com.insanusmokrassar.postssystem.core.content.*
import com.insanusmokrassar.postssystem.core.content.api.WriteContentRepo
import com.insanusmokrassar.postssystem.core.ktor.*
import com.insanusmokrassar.postssystem.ktor.server.configurators.ApplicationRoutingConfigurator
import com.insanusmokrassar.postssystem.ktor.server.includeWebsocketHandling
import com.insanusmokrassar.postssystem.ktor.server.standardKtorSerialFormatContentType
import com.insanusmokrassar.postssystem.ktor.standardKtorSerialFormat
import io.ktor.application.call
import io.ktor.response.respondBytes
import io.ktor.routing.Route
import io.ktor.routing.post
import io.ktor.util.toByteArray
import kotlinx.serialization.builtins.nullable
import kotlinx.serialization.builtins.serializer
fun Route.configureWriteContentRepoRoutes(
proxyTo: WriteContentRepo
) {
includeWebsocketHandling(contentCreatedFlowRoute, proxyTo.contentCreatedFlow) {
standardKtorSerialFormat.dump(RegisteredContent.serializer(), it)
}
includeWebsocketHandling(contentDeletedFlowRoute, proxyTo.contentDeletedFlow) {
standardKtorSerialFormat.dump(RegisteredContent.serializer(), it)
}
post(registerContentRoute) {
val content = standardKtorSerialFormat.load(
Content.serializer(),
call.request.receiveChannel().toByteArray()
)
val registered = proxyTo.registerContent(content)
call.respondBytes(
standardKtorSerialFormat.dump(
RegisteredContent.serializer().nullable,
registered
),
standardKtorSerialFormatContentType
)
}
post(deleteContentRoute) {
val contentId = standardKtorSerialFormat.load(
ContentId.serializer(),
call.request.receiveChannel().toByteArray()
)
val isDeleted = proxyTo.deleteContent(contentId)
call.respondBytes(
standardKtorSerialFormat.dump(
Boolean.serializer(),
isDeleted
),
standardKtorSerialFormatContentType
)
}
}
class WriteContentRepoRoutingConfigurator(
private val proxyTo: WriteContentRepo
) : ApplicationRoutingConfigurator.Element {
override fun Route.invoke() {
configureWriteContentRepoRoutes(proxyTo)
}
}

@ -0,0 +1,10 @@
package com.insanusmokrassar.postssystem.ktor.server
import com.insanusmokrassar.postssystem.utils.common.pagination.*
import io.ktor.http.Parameters
val Parameters.extractPagination: Pagination
get() = SimplePagination(
get("page") ?.toIntOrNull() ?: 0,
get("size") ?.toIntOrNull() ?: defaultMediumPageSize
)

@ -1,6 +1,7 @@
package com.insanusmokrassar.postssystem.ktor.server.configurators
import io.ktor.application.*
import io.ktor.routing.Route
import io.ktor.routing.Routing
import kotlinx.serialization.ContextualSerialization
import kotlinx.serialization.Serializable
@ -9,7 +10,7 @@ import kotlinx.serialization.Serializable
class ApplicationRoutingConfigurator(
private val elements: List<@ContextualSerialization Element>
) : KtorApplicationConfigurator {
interface Element { operator fun Routing.invoke() }
interface Element { operator fun Route.invoke() }
override fun Application.configure() {
try {

@ -0,0 +1,5 @@
package com.insanusmokrassar.postssystem.ktor.server
import io.ktor.http.ContentType
val standardKtorSerialFormatContentType = ContentType.Application.Cbor