add crud repo server and change a lot of different things

This commit is contained in:
2020-08-25 15:55:47 +06:00
parent 14d6915282
commit b94417b77d
16 changed files with 339 additions and 77 deletions
core/ktor
client
src
commonMain
kotlin
com
insanusmokrassar
server
src
main
kotlin
com
insanusmokrassar
ktor
client
src
commonMain
kotlin
com
insanusmokrassar
postssystem
server
src
jvmMain
kotlin
com
insanusmokrassar
tests
src
test
kotlin
com
insanusmokrassar
postssystem
settings.gradle
utils/repos
common
src
commonMain
kotlin
com
insanusmokrassar
postssystem
exposed
src
main
kotlin
com
insanusmokrassar
postssystem
ktor
client
src
commonMain
kotlin
com
insanusmokrassar
postssystem
utils
server
build.gradle
src
jvmMain
kotlin

@ -4,7 +4,6 @@ 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.client.*
import com.insanusmokrassar.postssystem.ktor.standardKtorSerialFormat
import io.ktor.client.HttpClient
import kotlinx.coroutines.flow.Flow
import kotlinx.serialization.builtins.nullable
@ -15,16 +14,14 @@ class WriteContentRepoKtorClient(
private val client: HttpClient = HttpClient()
) : WriteContentRepo {
override val contentCreatedFlow: Flow<RegisteredContent> = client.createStandardWebsocketFlow(
"$baseUrl/$contentCreatedFlowRoute"
) {
standardKtorSerialFormat.decodeFromByteArray(RegisteredContent.serializer(), it)
}
"$baseUrl/$contentCreatedFlowRoute",
deserializer = RegisteredContent.serializer()
)
override val contentDeletedFlow: Flow<RegisteredContent> = client.createStandardWebsocketFlow(
"$baseUrl/$contentDeletedFlowRoute"
) {
standardKtorSerialFormat.decodeFromByteArray(RegisteredContent.serializer(), it)
}
"$baseUrl/$contentDeletedFlowRoute",
deserializer = RegisteredContent.serializer()
)
override suspend fun registerContent(content: Content): RegisteredContent? = client.unipost(
"$baseUrl/$registerContentRoute",

@ -4,7 +4,6 @@ import com.insanusmokrassar.postssystem.core.ktor.*
import com.insanusmokrassar.postssystem.core.post.*
import com.insanusmokrassar.postssystem.core.post.repo.WritePostsRepo
import com.insanusmokrassar.postssystem.ktor.client.*
import com.insanusmokrassar.postssystem.ktor.standardKtorSerialFormat
import io.ktor.client.HttpClient
import io.ktor.client.features.websocket.WebSockets
import kotlinx.coroutines.flow.Flow
@ -18,20 +17,17 @@ class WritePostsRepoKtorClient (
}
) : WritePostsRepo {
override val postCreatedFlow: Flow<RegisteredPost> = client.createStandardWebsocketFlow(
"$baseUrl/$postCreatedFlowRoute"
) {
standardKtorSerialFormat.decodeFromByteArray(RegisteredPost.serializer(), it)
}
"$baseUrl/$postCreatedFlowRoute",
deserializer = RegisteredPost.serializer()
)
override val postDeletedFlow: Flow<RegisteredPost> = client.createStandardWebsocketFlow(
"$baseUrl/$postDeletedFlowRoute"
) {
standardKtorSerialFormat.decodeFromByteArray(RegisteredPost.serializer(), it)
}
"$baseUrl/$postDeletedFlowRoute",
deserializer = RegisteredPost.serializer()
)
override val postUpdatedFlow: Flow<RegisteredPost> = client.createStandardWebsocketFlow(
"$baseUrl/$postUpdatedFlowRoute"
) {
standardKtorSerialFormat.decodeFromByteArray(RegisteredPost.serializer(), it)
}
"$baseUrl/$postUpdatedFlowRoute",
deserializer = RegisteredPost.serializer()
)
override suspend fun createPost(post: Post): RegisteredPost? = client.unipost(
"$baseUrl/$createPostRoute",

@ -15,12 +15,8 @@ import kotlinx.serialization.builtins.serializer
fun Route.configureWriteContentRepoRoutes(
proxyTo: WriteContentRepo
) {
includeWebsocketHandling(contentCreatedFlowRoute, proxyTo.contentCreatedFlow) {
standardKtorSerialFormat.encodeToByteArray(RegisteredContent.serializer(), it)
}
includeWebsocketHandling(contentDeletedFlowRoute, proxyTo.contentDeletedFlow) {
standardKtorSerialFormat.encodeToByteArray(RegisteredContent.serializer(), it)
}
includeWebsocketHandling(contentCreatedFlowRoute, proxyTo.contentCreatedFlow, RegisteredContent.serializer())
includeWebsocketHandling(contentDeletedFlowRoute, proxyTo.contentDeletedFlow, RegisteredContent.serializer())
post(registerContentRoute) {
val content = call.uniload(Content.serializer())
val registered = proxyTo.registerContent(content)

@ -15,15 +15,9 @@ import kotlinx.serialization.builtins.serializer
fun Route.configureWritePostsRepoRoutes(
proxyTo: WritePostsRepo
) {
includeWebsocketHandling(postCreatedFlowRoute, proxyTo.postCreatedFlow) {
standardKtorSerialFormat.encodeToByteArray(RegisteredPost.serializer(), it)
}
includeWebsocketHandling(postDeletedFlowRoute, proxyTo.postDeletedFlow) {
standardKtorSerialFormat.encodeToByteArray(RegisteredPost.serializer(), it)
}
includeWebsocketHandling(postUpdatedFlowRoute, proxyTo.postUpdatedFlow) {
standardKtorSerialFormat.encodeToByteArray(RegisteredPost.serializer(), it)
}
includeWebsocketHandling(postCreatedFlowRoute, proxyTo.postCreatedFlow, RegisteredPost.serializer())
includeWebsocketHandling(postDeletedFlowRoute, proxyTo.postDeletedFlow, RegisteredPost.serializer())
includeWebsocketHandling(postUpdatedFlowRoute, proxyTo.postUpdatedFlow, RegisteredPost.serializer())
post(createPostRoute) {
call.unianswer(

@ -1,6 +1,7 @@
package com.insanusmokrassar.postssystem.ktor.client
import com.insanusmokrassar.postssystem.ktor.asCorrectWebSocketUrl
import com.insanusmokrassar.postssystem.ktor.standardKtorSerialFormat
import com.insanusmokrassar.postssystem.utils.common.safely
import io.ktor.client.HttpClient
import io.ktor.client.features.websocket.ws
@ -8,6 +9,7 @@ import io.ktor.http.cio.websocket.Frame
import io.ktor.http.cio.websocket.readBytes
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.channelFlow
import kotlinx.serialization.DeserializationStrategy
/**
* @param checkReconnection This lambda will be called when it is required to reconnect to websocket to establish
@ -63,3 +65,19 @@ inline fun <T> HttpClient.createStandardWebsocketFlow(
}
}
}
/**
* @param checkReconnection This lambda will be called when it is required to reconnect to websocket to establish
* connection. Must return true in case if must be reconnected. By default always reconnecting
*/
inline fun <T> HttpClient.createStandardWebsocketFlow(
url: String,
crossinline checkReconnection: (Throwable?) -> Boolean = { true },
deserializer: DeserializationStrategy<T>
) = createStandardWebsocketFlow(
url,
checkReconnection
) {
standardKtorSerialFormat.decodeFromByteArray(deserializer, it)
}

@ -1,12 +1,15 @@
package com.insanusmokrassar.postssystem.ktor.server
import com.insanusmokrassar.postssystem.ktor.CorrectCloseException
import com.insanusmokrassar.postssystem.ktor.standardKtorSerialFormat
import com.insanusmokrassar.postssystem.utils.common.safely
import io.ktor.http.cio.websocket.*
import io.ktor.routing.Route
import io.ktor.websocket.webSocket
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.serialization.DeserializationStrategy
import kotlinx.serialization.SerializationStrategy
private suspend fun DefaultWebSocketSession.checkReceivedAndCloseIfExists() {
if (incoming.poll() != null) {
@ -29,3 +32,14 @@ fun <T> Route.includeWebsocketHandling(
}
}
}
fun <T> Route.includeWebsocketHandling(
suburl: String,
flow: Flow<T>,
serializer: SerializationStrategy<T>
) = includeWebsocketHandling(
suburl,
flow
) {
standardKtorSerialFormat.encodeToByteArray(serializer, it)
}

@ -30,6 +30,14 @@ suspend fun ApplicationCall.getParameterOrSendError(
field: String
) = parameters[field].also {
if (it == null) {
respond(HttpStatusCode.BadRequest, "request must contains $field")
respond(HttpStatusCode.BadRequest, "Request must contains $field")
}
}
suspend fun ApplicationCall.getQueryParameterOrSendError(
field: String
) = request.queryParameters[field].also {
if (it == null) {
respond(HttpStatusCode.BadRequest, "Request query parametersmust contains $field")
}
}

@ -27,9 +27,7 @@ class WebsocketsTest {
val server = createKtorServer(host = "127.0.0.1", port = port) {
install(WebSockets)
routing {
includeWebsocketHandling(suburl, dataFlow) {
standardKtorSerialFormat.encodeToByteArray(Int.serializer(), it)
}
includeWebsocketHandling(suburl, dataFlow, Int.serializer())
}
}.also {
it.start(false)
@ -42,10 +40,9 @@ class WebsocketsTest {
}
val incomingWebsocketFlow = client.createStandardWebsocketFlow(
"$serverUrl/$suburl",
{ false } // always skip reconnection
) {
standardKtorSerialFormat.decodeFromByteArray(Int.serializer(), it)
}
{ false }, // always skip reconnection
deserializer = Int.serializer()
)
var currentlyCheckingData: Int? = null
incomingWebsocketFlow.onEach {

@ -6,6 +6,7 @@ String[] includes = [
':utils:repos:common',
':utils:repos:ktor:common',
':utils:repos:ktor:client',
':utils:repos:ktor:server',
':utils:repos:exposed',
':exposed:commons',

@ -21,11 +21,21 @@ interface WriteStandardCRUDRepo<ObjectType, IdType, InputValueType> : Repo {
val updatedObjectsFlow: Flow<ObjectType>
val deletedObjectsIdsFlow: Flow<IdType>
suspend fun create(vararg values: InputValueType): List<ObjectType>
suspend fun create(values: List<InputValueType>): List<ObjectType>
suspend fun update(id: IdType, value: InputValueType): ObjectType?
suspend fun update(vararg values: UpdatedValuePair<IdType, InputValueType>): List<ObjectType>
suspend fun deleteById(vararg ids: IdType)
suspend fun update(values: List<UpdatedValuePair<IdType, InputValueType>>): List<ObjectType>
suspend fun deleteById(ids: List<IdType>)
}
suspend fun <ObjectType, IdType, InputValueType> WriteStandardCRUDRepo<ObjectType, IdType, InputValueType>.create(
vararg values: InputValueType
): List<ObjectType> = create(values.toList())
suspend fun <ObjectType, IdType, InputValueType> WriteStandardCRUDRepo<ObjectType, IdType, InputValueType>.update(
vararg values: UpdatedValuePair<IdType, InputValueType>
): List<ObjectType> = update(values.toList())
suspend fun <ObjectType, IdType, InputValueType> WriteStandardCRUDRepo<ObjectType, IdType, InputValueType>.deleteById(
vararg ids: IdType
) = deleteById(ids.toList())
interface StandardCRUDRepo<ObjectType, IdType, InputValueType> : ReadStandardCRUDRepo<ObjectType, IdType>,
WriteStandardCRUDRepo<ObjectType, IdType, InputValueType>

@ -27,20 +27,20 @@ abstract class AbstractExposedWriteCRUDRepo<ObjectType, IdType, InputValueType>(
override val deletedObjectsIdsFlow: Flow<IdType> = deleteObjectsIdsChannel.asFlow()
abstract val InsertStatement<Number>.asObject: ObjectType
abstract val selectByIds: SqlExpressionBuilder.(Array<out IdType>) -> Op<Boolean>
abstract val selectByIds: SqlExpressionBuilder.(List<out IdType>) -> Op<Boolean>
protected abstract fun insert(value: InputValueType, it: InsertStatement<Number>)
protected abstract fun update(id: IdType, value: InputValueType, it: UpdateStatement)
protected open suspend fun onBeforeCreate(vararg value: InputValueType) {}
protected open suspend fun onBeforeCreate(value: List<InputValueType>) {}
private fun createWithoutNotification(value: InputValueType): ObjectType {
return transaction(database) {
insert { insert(value, it) }.asObject
}
}
override suspend fun create(vararg values: InputValueType): List<ObjectType> {
onBeforeCreate(*values)
override suspend fun create(values: List<InputValueType>): List<ObjectType> {
onBeforeCreate(values)
return transaction(db = database) {
values.map { value -> createWithoutNotification(value) }
}.also {
@ -50,7 +50,7 @@ abstract class AbstractExposedWriteCRUDRepo<ObjectType, IdType, InputValueType>(
}
}
protected open suspend fun onBeforeUpdate(vararg value: UpdatedValuePair<IdType, InputValueType>) {}
protected open suspend fun onBeforeUpdate(value: List<UpdatedValuePair<IdType, InputValueType>>) {}
private fun updateWithoutNotification(id: IdType, value: InputValueType): ObjectType? {
return transaction(db = database) {
update(
@ -72,15 +72,15 @@ abstract class AbstractExposedWriteCRUDRepo<ObjectType, IdType, InputValueType>(
}
override suspend fun update(id: IdType, value: InputValueType): ObjectType? {
onBeforeUpdate(id to value)
onBeforeUpdate(listOf(id to value))
return updateWithoutNotification(id, value).also {
if (it != null) {
updateObjectsChannel.send(it)
}
}
}
override suspend fun update(vararg values: UpdatedValuePair<IdType, InputValueType>): List<ObjectType> {
onBeforeUpdate(*values)
override suspend fun update(values: List<UpdatedValuePair<IdType, InputValueType>>): List<ObjectType> {
onBeforeUpdate(values)
return (
transaction(db = database) {
values.map { (id, value) -> updateWithoutNotification(id, value) }
@ -93,9 +93,9 @@ abstract class AbstractExposedWriteCRUDRepo<ObjectType, IdType, InputValueType>(
}
}
}
protected open suspend fun onBeforeDelete(vararg ids: IdType) {}
override suspend fun deleteById(vararg ids: IdType) {
onBeforeDelete(*ids)
protected open suspend fun onBeforeDelete(ids: List<IdType>) {}
override suspend fun deleteById(ids: List<IdType>) {
onBeforeDelete(ids)
transaction(db = database) {
deleteWhere(null, null) {
selectByIds(ids)

@ -2,15 +2,12 @@ package com.insanusmokrassar.postssystem.utils.repos.ktor.client
import com.insanusmokrassar.postssystem.ktor.*
import com.insanusmokrassar.postssystem.ktor.client.*
import com.insanusmokrassar.postssystem.utils.common.pagination.Pagination
import com.insanusmokrassar.postssystem.utils.common.pagination.PaginationResult
import com.insanusmokrassar.postssystem.utils.repos.*
import com.insanusmokrassar.postssystem.utils.repos.ktor.common.*
import io.ktor.client.HttpClient
import kotlinx.coroutines.flow.Flow
import kotlinx.serialization.KSerializer
import kotlinx.serialization.builtins.*
import kotlinx.serialization.encodeToHexString
class KtorWriteStandardCrudRepo<ObjectType, IdType, InputValue> (
private val baseUrl: String,
@ -23,45 +20,47 @@ class KtorWriteStandardCrudRepo<ObjectType, IdType, InputValue> (
private val listObjectsSerializer = ListSerializer(objectsSerializer)
private val listInputSerializer = ListSerializer(inputsSerializer)
private val listIdsSerializer = ListSerializer(idsSerializer)
private val inputUpdateSerializer = TemporalInputObjectForUpdate.serializer(
private val inputUpdateSerializer = PairSerializer(
idsSerializer,
inputsSerializer
)
private val listInputUpdateSerializer = ListSerializer(inputUpdateSerializer)
override val newObjectsFlow: Flow<ObjectType> = client.createStandardWebsocketFlow(
buildStandardUrl(baseUrl, newObjectsFlowRouting)
) { standardKtorSerialFormat.decodeFromByteArray(objectsSerializer, it) }
buildStandardUrl(baseUrl, newObjectsFlowRouting),
deserializer = objectsSerializer
)
override val updatedObjectsFlow: Flow<ObjectType> = client.createStandardWebsocketFlow(
buildStandardUrl(baseUrl, updatedObjectsFlowRouting)
) { standardKtorSerialFormat.decodeFromByteArray(objectsSerializer, it) }
buildStandardUrl(baseUrl, updatedObjectsFlowRouting),
deserializer = objectsSerializer
)
override val deletedObjectsIdsFlow: Flow<IdType> = client.createStandardWebsocketFlow(
buildStandardUrl(baseUrl, deletedObjectsIdsFlowRouting)
) { standardKtorSerialFormat.decodeFromByteArray(idsSerializer, it) }
buildStandardUrl(baseUrl, deletedObjectsIdsFlowRouting),
deserializer = idsSerializer
)
override suspend fun create(vararg values: InputValue): List<ObjectType> = client.unipost(
override suspend fun create(values: List<InputValue>): List<ObjectType> = client.unipost(
buildStandardUrl(baseUrl, createRouting),
BodyPair(listInputSerializer, values.toList()),
BodyPair(listInputSerializer, values),
listObjectsSerializer
)
override suspend fun update(id: IdType, value: InputValue): ObjectType? = client.unipost(
buildStandardUrl(baseUrl, updateRouting),
BodyPair(inputUpdateSerializer, TemporalInputObjectForUpdate(id, value)),
BodyPair(inputUpdateSerializer, id to value),
objectsNullableSerializer
)
override suspend fun update(vararg values: UpdatedValuePair<IdType, InputValue>): List<ObjectType> = client.unipost(
override suspend fun update(values: List<UpdatedValuePair<IdType, InputValue>>): List<ObjectType> = client.unipost(
buildStandardUrl(baseUrl, updateManyRouting),
BodyPair(listInputUpdateSerializer, values.map { TemporalInputObjectForUpdate(it.first, it.second) }),
BodyPair(listInputUpdateSerializer, values),
listObjectsSerializer
)
override suspend fun deleteById(vararg ids: IdType) = client.unipost(
override suspend fun deleteById(ids: List<IdType>) = client.unipost(
buildStandardUrl(baseUrl, deleteByIdRouting),
BodyPair(listIdsSerializer, ids.toList()),
BodyPair(listIdsSerializer, ids),
Unit.serializer()
)
}

@ -0,0 +1,64 @@
buildscript {
repositories {
mavenLocal()
jcenter()
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:$gradle_bintray_plugin_version"
}
}
plugins {
id "org.jetbrains.kotlin.multiplatform" version "$kotlin_version"
id "org.jetbrains.kotlin.plugin.serialization" version "$kotlin_version"
}
project.version = "$core_version"
project.group = "com.insanusmokrassar"
repositories {
mavenLocal()
jcenter()
mavenCentral()
maven { url "https://kotlin.bintray.com/kotlinx" }
}
kotlin {
jvm()
sourceSets {
commonMain {
dependencies {
implementation kotlin('stdlib')
api "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlin_coroutines_version"
api projectByName("postssystem.utils.repos.ktor.common")
api projectByName("postssystem.ktor.server")
}
}
commonTest {
dependencies {
implementation kotlin('test-common')
implementation kotlin('test-annotations-common')
}
}
jvmMain {
dependencies {
api "io.ktor:ktor-server:$ktor_version"
api "io.ktor:ktor-server-host-common:$ktor_version"
api "io.ktor:ktor-server-netty:$ktor_version"
api "io.ktor:ktor-websockets:$ktor_version"
}
}
jvmTest {
dependencies {
implementation kotlin('test-junit')
}
}
}
}

@ -0,0 +1,55 @@
package com.insanusmokrassar.postssystem.utils.repos.ktor.server
import com.insanusmokrassar.postssystem.ktor.server.*
import com.insanusmokrassar.postssystem.ktor.standardKtorSerialFormat
import com.insanusmokrassar.postssystem.utils.common.pagination.PaginationResult
import com.insanusmokrassar.postssystem.utils.repos.ReadStandardCRUDRepo
import com.insanusmokrassar.postssystem.utils.repos.ktor.common.*
import io.ktor.application.call
import io.ktor.routing.Route
import io.ktor.routing.get
import kotlinx.serialization.KSerializer
import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.decodeFromHexString
fun <ObjectType, IdType> Route.configureReadStandardCrudRepoRoutes(
originalRepo: ReadStandardCRUDRepo<ObjectType, IdType>,
objectsSerializer: KSerializer<ObjectType>,
objectsNullableSerializer: KSerializer<ObjectType?>,
idsSerializer: KSerializer<IdType>
) {
val paginationResultSerializer = PaginationResult.serializer(objectsSerializer)
get(getByPaginationRouting) {
val pagination = call.request.queryParameters.extractPagination
call.unianswer(
paginationResultSerializer,
originalRepo.getByPagination(pagination)
)
}
get(getByIdRouting) {
val id = standardKtorSerialFormat.decodeFromHexString(
idsSerializer,
call.getQueryParameterOrSendError("id") ?: return@get
)
call.unianswer(
objectsNullableSerializer,
originalRepo.getById(id)
)
}
get(containsRouting) {
val id = standardKtorSerialFormat.decodeFromHexString(
idsSerializer,
call.getQueryParameterOrSendError("id") ?: return@get
)
call.unianswer(
Boolean.serializer(),
originalRepo.contains(id)
)
}
}

@ -0,0 +1,27 @@
package com.insanusmokrassar.postssystem.utils.repos.ktor.server
import com.insanusmokrassar.postssystem.ktor.server.*
import com.insanusmokrassar.postssystem.ktor.standardKtorSerialFormat
import com.insanusmokrassar.postssystem.utils.common.pagination.PaginationResult
import com.insanusmokrassar.postssystem.utils.repos.*
import com.insanusmokrassar.postssystem.utils.repos.ktor.common.*
import io.ktor.application.call
import io.ktor.routing.*
import io.ktor.routing.get
import kotlinx.serialization.KSerializer
import kotlinx.serialization.builtins.*
import kotlinx.serialization.decodeFromHexString
fun <ObjectType, IdType, InputValue> Route.configureStandardCrudRepoRoutes(
baseSubpart: String,
originalRepo: StandardCRUDRepo<ObjectType, IdType, InputValue>,
objectsSerializer: KSerializer<ObjectType>,
objectsNullableSerializer: KSerializer<ObjectType?>,
inputsSerializer: KSerializer<InputValue>,
idsSerializer: KSerializer<IdType>
) {
route(baseSubpart) {
configureReadStandardCrudRepoRoutes(originalRepo, objectsSerializer, objectsNullableSerializer, idsSerializer)
configureWriteStandardCrudRepoRoutes(originalRepo, objectsSerializer, objectsNullableSerializer, inputsSerializer, idsSerializer)
}
}

@ -0,0 +1,86 @@
package com.insanusmokrassar.postssystem.utils.repos.ktor.server
import com.insanusmokrassar.postssystem.ktor.server.*
import com.insanusmokrassar.postssystem.ktor.standardKtorSerialFormat
import com.insanusmokrassar.postssystem.utils.common.pagination.PaginationResult
import com.insanusmokrassar.postssystem.utils.repos.ReadStandardCRUDRepo
import com.insanusmokrassar.postssystem.utils.repos.WriteStandardCRUDRepo
import com.insanusmokrassar.postssystem.utils.repos.ktor.common.*
import io.ktor.application.call
import io.ktor.routing.*
import io.ktor.routing.get
import kotlinx.serialization.KSerializer
import kotlinx.serialization.builtins.*
import kotlinx.serialization.decodeFromHexString
fun <ObjectType, IdType, InputValue> Route.configureWriteStandardCrudRepoRoutes(
originalRepo: WriteStandardCRUDRepo<ObjectType, IdType, InputValue>,
objectsSerializer: KSerializer<ObjectType>,
objectsNullableSerializer: KSerializer<ObjectType?>,
inputsSerializer: KSerializer<InputValue>,
idsSerializer: KSerializer<IdType>
) {
val listObjectsSerializer = ListSerializer(objectsSerializer)
val listInputSerializer = ListSerializer(inputsSerializer)
val listIdsSerializer = ListSerializer(idsSerializer)
val inputUpdateSerializer = PairSerializer(
idsSerializer,
inputsSerializer
)
val listInputUpdateSerializer = ListSerializer(inputUpdateSerializer)
includeWebsocketHandling(
newObjectsFlowRouting,
originalRepo.newObjectsFlow,
objectsSerializer
)
includeWebsocketHandling(
updatedObjectsFlowRouting,
originalRepo.updatedObjectsFlow,
objectsSerializer
)
includeWebsocketHandling(
deletedObjectsIdsFlowRouting,
originalRepo.deletedObjectsIdsFlow,
idsSerializer
)
post(createRouting) {
call.unianswer(
listObjectsSerializer,
originalRepo.create(
call.uniload(listInputSerializer)
)
)
}
post(updateRouting) {
val (id, input) = call.uniload(inputUpdateSerializer)
call.unianswer(
objectsNullableSerializer,
originalRepo.update(
id, input
)
)
}
post(updateManyRouting) {
val updates = call.uniload(listInputUpdateSerializer)
call.unianswer(
listObjectsSerializer,
originalRepo.update(
updates
)
)
}
post(deleteByIdRouting) {
val ids = call.uniload(listIdsSerializer)
call.unianswer(
Unit.serializer(),
originalRepo.deleteById(
ids
)
)
}
}