diff --git a/core/ktor/client/src/commonMain/kotlin/com/insanusmokrassar/postssystem/core/ktor/client/content/WriteContentRepoKtorClient.kt b/core/ktor/client/src/commonMain/kotlin/com/insanusmokrassar/postssystem/core/ktor/client/content/WriteContentRepoKtorClient.kt
index b86bd1b8..822a3996 100644
--- a/core/ktor/client/src/commonMain/kotlin/com/insanusmokrassar/postssystem/core/ktor/client/content/WriteContentRepoKtorClient.kt
+++ b/core/ktor/client/src/commonMain/kotlin/com/insanusmokrassar/postssystem/core/ktor/client/content/WriteContentRepoKtorClient.kt
@@ -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",
diff --git a/core/ktor/client/src/commonMain/kotlin/com/insanusmokrassar/postssystem/core/ktor/client/post/WritePostsRepoKtorClient.kt b/core/ktor/client/src/commonMain/kotlin/com/insanusmokrassar/postssystem/core/ktor/client/post/WritePostsRepoKtorClient.kt
index 9ac42430..d0ff656b 100644
--- a/core/ktor/client/src/commonMain/kotlin/com/insanusmokrassar/postssystem/core/ktor/client/post/WritePostsRepoKtorClient.kt
+++ b/core/ktor/client/src/commonMain/kotlin/com/insanusmokrassar/postssystem/core/ktor/client/post/WritePostsRepoKtorClient.kt
@@ -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",
diff --git a/core/ktor/server/src/main/kotlin/com/insanusmokrassar/postssystem/core/ktor/server/content/WriteContentRepoRoutingConfigurator.kt b/core/ktor/server/src/main/kotlin/com/insanusmokrassar/postssystem/core/ktor/server/content/WriteContentRepoRoutingConfigurator.kt
index a40f3d4e..48ae1e53 100644
--- a/core/ktor/server/src/main/kotlin/com/insanusmokrassar/postssystem/core/ktor/server/content/WriteContentRepoRoutingConfigurator.kt
+++ b/core/ktor/server/src/main/kotlin/com/insanusmokrassar/postssystem/core/ktor/server/content/WriteContentRepoRoutingConfigurator.kt
@@ -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)
diff --git a/core/ktor/server/src/main/kotlin/com/insanusmokrassar/postssystem/core/ktor/server/post/WritePostsRepoRoutingConfigurator.kt b/core/ktor/server/src/main/kotlin/com/insanusmokrassar/postssystem/core/ktor/server/post/WritePostsRepoRoutingConfigurator.kt
index 6a82e2c3..820b6ea2 100644
--- a/core/ktor/server/src/main/kotlin/com/insanusmokrassar/postssystem/core/ktor/server/post/WritePostsRepoRoutingConfigurator.kt
+++ b/core/ktor/server/src/main/kotlin/com/insanusmokrassar/postssystem/core/ktor/server/post/WritePostsRepoRoutingConfigurator.kt
@@ -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(
diff --git a/ktor/client/src/commonMain/kotlin/com/insanusmokrassar/postssystem/ktor/client/FlowsWebsockets.kt b/ktor/client/src/commonMain/kotlin/com/insanusmokrassar/postssystem/ktor/client/FlowsWebsockets.kt
index 656a4abd..0ae3e0c7 100644
--- a/ktor/client/src/commonMain/kotlin/com/insanusmokrassar/postssystem/ktor/client/FlowsWebsockets.kt
+++ b/ktor/client/src/commonMain/kotlin/com/insanusmokrassar/postssystem/ktor/client/FlowsWebsockets.kt
@@ -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)
+}
+
diff --git a/ktor/server/src/jvmMain/kotlin/com/insanusmokrassar/postssystem/ktor/server/FlowsWebsocket.kt b/ktor/server/src/jvmMain/kotlin/com/insanusmokrassar/postssystem/ktor/server/FlowsWebsocket.kt
index 8e86a864..f7c58dca 100644
--- a/ktor/server/src/jvmMain/kotlin/com/insanusmokrassar/postssystem/ktor/server/FlowsWebsocket.kt
+++ b/ktor/server/src/jvmMain/kotlin/com/insanusmokrassar/postssystem/ktor/server/FlowsWebsocket.kt
@@ -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)
+}
diff --git a/ktor/server/src/jvmMain/kotlin/com/insanusmokrassar/postssystem/ktor/server/ServerRoutingShortcuts.kt b/ktor/server/src/jvmMain/kotlin/com/insanusmokrassar/postssystem/ktor/server/ServerRoutingShortcuts.kt
index 5948ac49..59e10dbb 100644
--- a/ktor/server/src/jvmMain/kotlin/com/insanusmokrassar/postssystem/ktor/server/ServerRoutingShortcuts.kt
+++ b/ktor/server/src/jvmMain/kotlin/com/insanusmokrassar/postssystem/ktor/server/ServerRoutingShortcuts.kt
@@ -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")
     }
 }
diff --git a/ktor/tests/src/test/kotlin/com/insanusmokrassar/postssystem/ktor/tests/WebsocketsTest.kt b/ktor/tests/src/test/kotlin/com/insanusmokrassar/postssystem/ktor/tests/WebsocketsTest.kt
index c7278418..618f4e57 100644
--- a/ktor/tests/src/test/kotlin/com/insanusmokrassar/postssystem/ktor/tests/WebsocketsTest.kt
+++ b/ktor/tests/src/test/kotlin/com/insanusmokrassar/postssystem/ktor/tests/WebsocketsTest.kt
@@ -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 {
diff --git a/settings.gradle b/settings.gradle
index f0356ccd..dbb6eb43 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -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',
diff --git a/utils/repos/common/src/commonMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/StandardCRUDRepo.kt b/utils/repos/common/src/commonMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/StandardCRUDRepo.kt
index 26b0f55a..8e78cb93 100644
--- a/utils/repos/common/src/commonMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/StandardCRUDRepo.kt
+++ b/utils/repos/common/src/commonMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/StandardCRUDRepo.kt
@@ -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>
diff --git a/utils/repos/exposed/src/main/kotlin/com/insanusmokrassar/postssystem/utils/repos/exposed/AbstractExposedWriteCRUDRepo.kt b/utils/repos/exposed/src/main/kotlin/com/insanusmokrassar/postssystem/utils/repos/exposed/AbstractExposedWriteCRUDRepo.kt
index a718dfb2..abfbac76 100644
--- a/utils/repos/exposed/src/main/kotlin/com/insanusmokrassar/postssystem/utils/repos/exposed/AbstractExposedWriteCRUDRepo.kt
+++ b/utils/repos/exposed/src/main/kotlin/com/insanusmokrassar/postssystem/utils/repos/exposed/AbstractExposedWriteCRUDRepo.kt
@@ -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)
diff --git a/utils/repos/ktor/client/src/commonMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/client/KtorWriteStandardCrudRepo.kt b/utils/repos/ktor/client/src/commonMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/client/KtorWriteStandardCrudRepo.kt
index 5ce98d23..fdb845e3 100644
--- a/utils/repos/ktor/client/src/commonMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/client/KtorWriteStandardCrudRepo.kt
+++ b/utils/repos/ktor/client/src/commonMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/client/KtorWriteStandardCrudRepo.kt
@@ -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()
     )
 }
diff --git a/utils/repos/ktor/server/build.gradle b/utils/repos/ktor/server/build.gradle
new file mode 100644
index 00000000..cab1a09e
--- /dev/null
+++ b/utils/repos/ktor/server/build.gradle
@@ -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')
+            }
+        }
+    }
+}
diff --git a/utils/repos/ktor/server/src/jvmMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/server/KtorReadStandardCrudRepo.kt b/utils/repos/ktor/server/src/jvmMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/server/KtorReadStandardCrudRepo.kt
new file mode 100644
index 00000000..ffd1a7fd
--- /dev/null
+++ b/utils/repos/ktor/server/src/jvmMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/server/KtorReadStandardCrudRepo.kt
@@ -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)
+        )
+    }
+}
diff --git a/utils/repos/ktor/server/src/jvmMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/server/KtorStandardCrudRepo.kt b/utils/repos/ktor/server/src/jvmMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/server/KtorStandardCrudRepo.kt
new file mode 100644
index 00000000..741006d4
--- /dev/null
+++ b/utils/repos/ktor/server/src/jvmMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/server/KtorStandardCrudRepo.kt
@@ -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)
+    }
+}
diff --git a/utils/repos/ktor/server/src/jvmMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/server/KtorWriteStandardCrudRepo.kt b/utils/repos/ktor/server/src/jvmMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/server/KtorWriteStandardCrudRepo.kt
new file mode 100644
index 00000000..1f7b5973
--- /dev/null
+++ b/utils/repos/ktor/server/src/jvmMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/server/KtorWriteStandardCrudRepo.kt
@@ -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
+            )
+        )
+    }
+}