add crud repo server and change a lot of different things

This commit is contained in:
InsanusMokrassar 2020-08-25 15:55:47 +06:00
parent 14d6915282
commit b94417b77d
16 changed files with 339 additions and 77 deletions

View File

@ -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",

View File

@ -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",

View File

@ -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)

View File

@ -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(

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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")
}
}

View File

@ -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 {

View File

@ -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',

View File

@ -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>

View File

@ -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)

View File

@ -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()
)
}

View File

@ -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')
}
}
}
}

View File

@ -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)
)
}
}

View File

@ -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)
}
}

View File

@ -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
)
)
}
}