UnifiedRouter

This commit is contained in:
InsanusMokrassar 2020-11-27 14:35:00 +06:00
parent 26d5f5a5f5
commit ab11e28bf7
23 changed files with 536 additions and 281 deletions

View File

@ -5,10 +5,14 @@
* `Ktor`
* `Client`
* New class `UnifiedRequester`
* `Server`
* New class `UnifiedRouter`
* `Repos`
* `Ktor`
* `Client`
* Rewriting of all clients on new `UnifiedRequester`
* `Server`
* Rewriting of all clients on new `UnifiedRouter`
## 0.4.6

View File

@ -8,7 +8,6 @@ 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.BinaryFormat
import kotlinx.serialization.DeserializationStrategy
/**
@ -66,7 +65,7 @@ inline fun <T> HttpClient.createStandardWebsocketFlow(
url: String,
crossinline checkReconnection: (Throwable?) -> Boolean = { true },
deserializer: DeserializationStrategy<T>,
serialFormat: BinaryFormat = standardKtorSerialFormat
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat
) = createStandardWebsocketFlow(
url,
checkReconnection

View File

@ -10,7 +10,7 @@ typealias BodyPair<T> = Pair<SerializationStrategy<T>, T>
class UnifiedRequester(
private val client: HttpClient = HttpClient(),
private val serialFormat: BinaryFormat = standardKtorSerialFormat
private val serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat
) {
suspend fun <ResultType> uniget(
url: String,

View File

@ -33,10 +33,11 @@ fun <T> Route.includeWebsocketHandling(
fun <T> Route.includeWebsocketHandling(
suburl: String,
flow: Flow<T>,
serializer: SerializationStrategy<T>
serializer: SerializationStrategy<T>,
serialFormat: StandardKtorSerialFormat
) = includeWebsocketHandling(
suburl,
flow
) {
standardKtorSerialFormat.encodeDefault(serializer, it)
serialFormat.encodeDefault(serializer, it)
}

View File

@ -3,12 +3,87 @@ package dev.inmo.micro_utils.ktor.server
import dev.inmo.micro_utils.coroutines.safely
import dev.inmo.micro_utils.ktor.common.*
import io.ktor.application.ApplicationCall
import io.ktor.application.call
import io.ktor.http.ContentType
import io.ktor.http.HttpStatusCode
import io.ktor.request.receive
import io.ktor.response.respond
import io.ktor.response.respondBytes
import kotlinx.serialization.DeserializationStrategy
import kotlinx.serialization.SerializationStrategy
import io.ktor.routing.Route
import io.ktor.util.pipeline.PipelineContext
import kotlinx.coroutines.flow.Flow
import kotlinx.serialization.*
class UnifiedRouter(
private val serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat,
private val serialFormatContentType: ContentType = standardKtorSerialFormatContentType
) {
fun <T> Route.includeWebsocketHandling(
suburl: String,
flow: Flow<T>,
serializer: SerializationStrategy<T>
) = includeWebsocketHandling(suburl, flow, serializer, serialFormat)
suspend fun <T> PipelineContext<*, ApplicationCall>.unianswer(
answerSerializer: SerializationStrategy<T>,
answer: T
) {
call.respondBytes (
serialFormat.encodeDefault(answerSerializer, answer),
serialFormatContentType
)
}
suspend fun <T> PipelineContext<*, ApplicationCall>.uniload(
deserializer: DeserializationStrategy<T>
) = safely {
serialFormat.decodeDefault(
deserializer,
call.receive()
)
}
suspend fun PipelineContext<*, ApplicationCall>.getParameterOrSendError(
field: String
) = call.parameters[field].also {
if (it == null) {
call.respond(HttpStatusCode.BadRequest, "Request must contains $field")
}
}
fun PipelineContext<*, ApplicationCall>.getQueryParameter(
field: String
) = call.request.queryParameters[field]
suspend fun PipelineContext<*, ApplicationCall>.getQueryParameterOrSendError(
field: String
) = getQueryParameter(field).also {
if (it == null) {
call.respond(HttpStatusCode.BadRequest, "Request query parameters must contains $field")
}
}
fun <T> PipelineContext<*, ApplicationCall>.decodeUrlQueryValue(
field: String,
deserializer: DeserializationStrategy<T>
) = getQueryParameter(field) ?.let {
serialFormat.decodeHex(
deserializer,
it
)
}
suspend fun <T> PipelineContext<*, ApplicationCall>.decodeUrlQueryValueOrSendError(
field: String,
deserializer: DeserializationStrategy<T>
) = decodeUrlQueryValue(field, deserializer).also {
if (it == null) {
call.respond(HttpStatusCode.BadRequest, "Request query parameters must contains $field")
}
}
}
val defaultUnifiedRouter = UnifiedRouter()
suspend fun <T> ApplicationCall.unianswer(
answerSerializer: SerializationStrategy<T>,

View File

@ -1,13 +1,11 @@
package dev.inmo.micro_utils.repos.ktor.client.crud
import dev.inmo.micro_utils.ktor.client.*
import dev.inmo.micro_utils.ktor.common.buildStandardUrl
import dev.inmo.micro_utils.ktor.common.standardKtorSerialFormat
import dev.inmo.micro_utils.ktor.common.*
import dev.inmo.micro_utils.pagination.*
import dev.inmo.micro_utils.repos.ReadStandardCRUDRepo
import dev.inmo.micro_utils.repos.ktor.common.crud.*
import io.ktor.client.HttpClient
import kotlinx.serialization.BinaryFormat
import kotlinx.serialization.KSerializer
import kotlinx.serialization.builtins.serializer
@ -26,7 +24,7 @@ class KtorReadStandardCrudRepo<ObjectType, IdType> (
objectsSerializer: KSerializer<ObjectType>,
objectsSerializerNullable: KSerializer<ObjectType?>,
idsSerializer: KSerializer<IdType>,
serialFormat: BinaryFormat = standardKtorSerialFormat
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat
) : this (
baseUrl, UnifiedRequester(client, serialFormat), objectsSerializer, objectsSerializerNullable, idsSerializer
)

View File

@ -1,10 +1,10 @@
package dev.inmo.micro_utils.repos.ktor.client.crud
import dev.inmo.micro_utils.ktor.client.UnifiedRequester
import dev.inmo.micro_utils.ktor.common.StandardKtorSerialFormat
import dev.inmo.micro_utils.ktor.common.standardKtorSerialFormat
import dev.inmo.micro_utils.repos.*
import io.ktor.client.HttpClient
import kotlinx.serialization.BinaryFormat
import kotlinx.serialization.KSerializer
class KtorStandardCrudRepo<ObjectType, IdType, InputValue> (
@ -39,7 +39,7 @@ class KtorStandardCrudRepo<ObjectType, IdType, InputValue> (
objectsNullableSerializer: KSerializer<ObjectType?>,
inputsSerializer: KSerializer<InputValue>,
idsSerializer: KSerializer<IdType>,
serialFormat: BinaryFormat = standardKtorSerialFormat
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat
) : this(
baseUrl, baseSubpart, UnifiedRequester(client, serialFormat), objectsSerializer, objectsNullableSerializer, inputsSerializer, idsSerializer
)

View File

@ -1,14 +1,12 @@
package dev.inmo.micro_utils.repos.ktor.client.crud
import dev.inmo.micro_utils.ktor.client.*
import dev.inmo.micro_utils.ktor.common.buildStandardUrl
import dev.inmo.micro_utils.ktor.common.standardKtorSerialFormat
import dev.inmo.micro_utils.ktor.common.*
import dev.inmo.micro_utils.repos.UpdatedValuePair
import dev.inmo.micro_utils.repos.WriteStandardCRUDRepo
import dev.inmo.micro_utils.repos.ktor.common.crud.*
import io.ktor.client.HttpClient
import kotlinx.coroutines.flow.Flow
import kotlinx.serialization.BinaryFormat
import kotlinx.serialization.KSerializer
import kotlinx.serialization.builtins.*
@ -36,7 +34,7 @@ class KtorWriteStandardCrudRepo<ObjectType, IdType, InputValue> (
objectsSerializerNullable: KSerializer<ObjectType?>,
inputsSerializer: KSerializer<InputValue>,
idsSerializer: KSerializer<IdType>,
serialFormat: BinaryFormat = standardKtorSerialFormat
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat
) : this (
baseUrl, UnifiedRequester(client, serialFormat), objectsSerializer, objectsSerializerNullable, inputsSerializer, idsSerializer
)

View File

@ -1,8 +1,7 @@
package dev.inmo.micro_utils.repos.ktor.client.key_value
import dev.inmo.micro_utils.ktor.client.*
import dev.inmo.micro_utils.ktor.common.buildStandardUrl
import dev.inmo.micro_utils.ktor.common.standardKtorSerialFormat
import dev.inmo.micro_utils.ktor.common.*
import dev.inmo.micro_utils.pagination.*
import dev.inmo.micro_utils.repos.ReadStandardKeyValueRepo
import dev.inmo.micro_utils.repos.ktor.common.key_value.*
@ -24,7 +23,7 @@ class KtorReadStandardKeyValueRepo<Key, Value> (
keySerializer: KSerializer<Key>,
valueSerializer: KSerializer<Value>,
valueNullableSerializer: KSerializer<Value?>,
serialFormat: BinaryFormat = standardKtorSerialFormat
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat
) : this (
baseUrl, UnifiedRequester(client, serialFormat), keySerializer, valueSerializer, valueNullableSerializer
)

View File

@ -1,6 +1,7 @@
package dev.inmo.micro_utils.repos.ktor.client.key_value
import dev.inmo.micro_utils.ktor.client.UnifiedRequester
import dev.inmo.micro_utils.ktor.common.StandardKtorSerialFormat
import dev.inmo.micro_utils.ktor.common.standardKtorSerialFormat
import dev.inmo.micro_utils.repos.*
import io.ktor.client.HttpClient
@ -34,6 +35,6 @@ class KtorStandartKeyValueRepo<K, V> (
keySerializer: KSerializer<K>,
valueSerializer: KSerializer<V>,
valueNullableSerializer: KSerializer<V?>,
serialFormat: BinaryFormat = standardKtorSerialFormat
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat
) : this(baseUrl, baseSubpart, UnifiedRequester(client, serialFormat), keySerializer, valueSerializer, valueNullableSerializer)
}

View File

@ -1,13 +1,11 @@
package dev.inmo.micro_utils.repos.ktor.client.key_value
import dev.inmo.micro_utils.ktor.client.*
import dev.inmo.micro_utils.ktor.common.buildStandardUrl
import dev.inmo.micro_utils.ktor.common.standardKtorSerialFormat
import dev.inmo.micro_utils.ktor.common.*
import dev.inmo.micro_utils.repos.WriteStandardKeyValueRepo
import dev.inmo.micro_utils.repos.ktor.common.key_value.*
import io.ktor.client.HttpClient
import kotlinx.coroutines.flow.Flow
import kotlinx.serialization.BinaryFormat
import kotlinx.serialization.KSerializer
import kotlinx.serialization.builtins.*
@ -25,7 +23,7 @@ class KtorWriteStandardKeyValueRepo<K, V> (
client: HttpClient,
keySerializer: KSerializer<K>,
valueSerializer: KSerializer<V>,
serialFormat: BinaryFormat = standardKtorSerialFormat
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat
) : this (
baseUrl, UnifiedRequester(client, serialFormat), keySerializer, valueSerializer
)

View File

@ -1,10 +1,10 @@
package dev.inmo.micro_utils.repos.ktor.client.one_to_many
import dev.inmo.micro_utils.ktor.client.UnifiedRequester
import dev.inmo.micro_utils.ktor.common.StandardKtorSerialFormat
import dev.inmo.micro_utils.ktor.common.standardKtorSerialFormat
import dev.inmo.micro_utils.repos.*
import io.ktor.client.HttpClient
import kotlinx.serialization.BinaryFormat
import kotlinx.serialization.KSerializer
class KtorOneToManyKeyValueRepo<Key, Value>(
@ -32,6 +32,6 @@ class KtorOneToManyKeyValueRepo<Key, Value>(
client: HttpClient,
keySerializer: KSerializer<Key>,
valueSerializer: KSerializer<Value>,
serialFormat: BinaryFormat = standardKtorSerialFormat
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat
) : this (baseUrl, baseSubpart, UnifiedRequester(client, serialFormat), keySerializer, valueSerializer)
}

View File

@ -1,8 +1,7 @@
package dev.inmo.micro_utils.repos.ktor.client.one_to_many
import dev.inmo.micro_utils.ktor.client.*
import dev.inmo.micro_utils.ktor.common.buildStandardUrl
import dev.inmo.micro_utils.ktor.common.standardKtorSerialFormat
import dev.inmo.micro_utils.ktor.common.*
import dev.inmo.micro_utils.pagination.*
import dev.inmo.micro_utils.repos.ReadOneToManyKeyValueRepo
import dev.inmo.micro_utils.repos.ktor.common.keyParameterName
@ -10,7 +9,6 @@ import dev.inmo.micro_utils.repos.ktor.common.one_to_many.*
import dev.inmo.micro_utils.repos.ktor.common.reversedParameterName
import dev.inmo.micro_utils.repos.ktor.common.valueParameterName
import io.ktor.client.HttpClient
import kotlinx.serialization.BinaryFormat
import kotlinx.serialization.KSerializer
import kotlinx.serialization.builtins.serializer
@ -28,7 +26,7 @@ class KtorReadOneToManyKeyValueRepo<Key, Value> (
client: HttpClient,
keySerializer: KSerializer<Key>,
valueSerializer: KSerializer<Value>,
serialFormat: BinaryFormat = standardKtorSerialFormat
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat
) : this (baseUrl, UnifiedRequester(client, serialFormat), keySerializer, valueSerializer)
override suspend fun get(k: Key, pagination: Pagination, reversed: Boolean): PaginationResult<Value> = unifiedRequester.uniget(

View File

@ -1,13 +1,11 @@
package dev.inmo.micro_utils.repos.ktor.client.one_to_many
import dev.inmo.micro_utils.ktor.client.*
import dev.inmo.micro_utils.ktor.common.buildStandardUrl
import dev.inmo.micro_utils.ktor.common.standardKtorSerialFormat
import dev.inmo.micro_utils.ktor.common.*
import dev.inmo.micro_utils.repos.WriteOneToManyKeyValueRepo
import dev.inmo.micro_utils.repos.ktor.common.one_to_many.*
import io.ktor.client.HttpClient
import kotlinx.coroutines.flow.Flow
import kotlinx.serialization.BinaryFormat
import kotlinx.serialization.KSerializer
import kotlinx.serialization.builtins.*
@ -25,7 +23,7 @@ class KtorWriteOneToManyKeyValueRepo<Key, Value> (
client: HttpClient,
keySerializer: KSerializer<Key>,
valueSerializer: KSerializer<Value>,
serialFormat: BinaryFormat = standardKtorSerialFormat
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat
) : this (
baseUrl, UnifiedRequester(client, serialFormat), keySerializer, valueSerializer
)

View File

@ -1,12 +1,14 @@
package dev.inmo.micro_utils.repos.ktor.server.crud
import dev.inmo.micro_utils.ktor.server.decodeUrlQueryValueOrSendError
import dev.inmo.micro_utils.ktor.server.unianswer
import dev.inmo.micro_utils.ktor.common.StandardKtorSerialFormat
import dev.inmo.micro_utils.ktor.common.standardKtorSerialFormat
import dev.inmo.micro_utils.ktor.server.*
import dev.inmo.micro_utils.pagination.PaginationResult
import dev.inmo.micro_utils.pagination.extractPagination
import dev.inmo.micro_utils.repos.ReadStandardCRUDRepo
import dev.inmo.micro_utils.repos.ktor.common.crud.*
import io.ktor.application.call
import io.ktor.http.ContentType
import io.ktor.routing.Route
import io.ktor.routing.get
import kotlinx.serialization.KSerializer
@ -16,47 +18,65 @@ fun <ObjectType, IdType> Route.configureReadStandardCrudRepoRoutes(
originalRepo: ReadStandardCRUDRepo<ObjectType, IdType>,
objectsSerializer: KSerializer<ObjectType>,
objectsNullableSerializer: KSerializer<ObjectType?>,
idsSerializer: KSerializer<IdType>
idsSerializer: KSerializer<IdType>,
unifiedRouter: UnifiedRouter
) {
val paginationResultSerializer = PaginationResult.serializer(objectsSerializer)
get(getByPaginationRouting) {
val pagination = call.request.queryParameters.extractPagination
unifiedRouter.apply {
val pagination = call.request.queryParameters.extractPagination
call.unianswer(
paginationResultSerializer,
originalRepo.getByPagination(pagination)
)
unianswer(
paginationResultSerializer,
originalRepo.getByPagination(pagination)
)
}
}
get(getByIdRouting) {
val id = call.decodeUrlQueryValueOrSendError(
"id",
idsSerializer
) ?: return@get
unifiedRouter.apply {
val id = decodeUrlQueryValueOrSendError(
"id",
idsSerializer
) ?: return@get
call.unianswer(
objectsNullableSerializer,
originalRepo.getById(id)
)
unianswer(
objectsNullableSerializer,
originalRepo.getById(id)
)
}
}
get(containsRouting) {
val id = call.decodeUrlQueryValueOrSendError(
"id",
idsSerializer
) ?: return@get
unifiedRouter.apply {
val id = decodeUrlQueryValueOrSendError(
"id",
idsSerializer
) ?: return@get
call.unianswer(
Boolean.serializer(),
originalRepo.contains(id)
)
unianswer(
Boolean.serializer(),
originalRepo.contains(id)
)
}
}
get(countRouting) {
call.unianswer(
Long.serializer(),
originalRepo.count()
)
unifiedRouter.apply {
unianswer(
Long.serializer(),
originalRepo.count()
)
}
}
}
inline fun <ObjectType, IdType> Route.configureReadStandardCrudRepoRoutes(
originalRepo: ReadStandardCRUDRepo<ObjectType, IdType>,
objectsSerializer: KSerializer<ObjectType>,
objectsNullableSerializer: KSerializer<ObjectType?>,
idsSerializer: KSerializer<IdType>,
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat,
serialFormatContentType: ContentType = standardKtorSerialFormatContentType
) = configureReadStandardCrudRepoRoutes(originalRepo, objectsSerializer, objectsNullableSerializer, idsSerializer, UnifiedRouter(serialFormat, serialFormatContentType))

View File

@ -1,6 +1,11 @@
package dev.inmo.micro_utils.repos.ktor.server.crud
import dev.inmo.micro_utils.ktor.common.StandardKtorSerialFormat
import dev.inmo.micro_utils.ktor.common.standardKtorSerialFormat
import dev.inmo.micro_utils.ktor.server.UnifiedRouter
import dev.inmo.micro_utils.ktor.server.standardKtorSerialFormatContentType
import dev.inmo.micro_utils.repos.StandardCRUDRepo
import io.ktor.http.ContentType
import io.ktor.routing.Route
import io.ktor.routing.route
import kotlinx.serialization.KSerializer
@ -11,10 +16,24 @@ fun <ObjectType, IdType, InputValue> Route.configureStandardCrudRepoRoutes(
objectsSerializer: KSerializer<ObjectType>,
objectsNullableSerializer: KSerializer<ObjectType?>,
inputsSerializer: KSerializer<InputValue>,
idsSerializer: KSerializer<IdType>
idsSerializer: KSerializer<IdType>,
unifiedRouter: UnifiedRouter
) {
route(baseSubpart) {
configureReadStandardCrudRepoRoutes(originalRepo, objectsSerializer, objectsNullableSerializer, idsSerializer)
configureWriteStandardCrudRepoRoutes(originalRepo, objectsSerializer, objectsNullableSerializer, inputsSerializer, idsSerializer)
configureReadStandardCrudRepoRoutes(originalRepo, objectsSerializer, objectsNullableSerializer, idsSerializer, unifiedRouter)
configureWriteStandardCrudRepoRoutes(originalRepo, objectsSerializer, objectsNullableSerializer, inputsSerializer, idsSerializer, unifiedRouter)
}
}
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>,
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat,
serialFormatContentType: ContentType = standardKtorSerialFormatContentType
) = configureStandardCrudRepoRoutes(
baseSubpart, originalRepo, objectsSerializer, objectsNullableSerializer, inputsSerializer, idsSerializer, UnifiedRouter(serialFormat, serialFormatContentType)
)

View File

@ -1,9 +1,12 @@
package dev.inmo.micro_utils.repos.ktor.server.crud
import dev.inmo.micro_utils.ktor.common.StandardKtorSerialFormat
import dev.inmo.micro_utils.ktor.common.standardKtorSerialFormat
import dev.inmo.micro_utils.ktor.server.*
import dev.inmo.micro_utils.repos.WriteStandardCRUDRepo
import dev.inmo.micro_utils.repos.ktor.common.crud.*
import io.ktor.application.call
import io.ktor.http.ContentType
import io.ktor.routing.Route
import io.ktor.routing.post
import kotlinx.serialization.KSerializer
@ -14,7 +17,8 @@ fun <ObjectType, IdType, InputValue> Route.configureWriteStandardCrudRepoRoutes(
objectsSerializer: KSerializer<ObjectType>,
objectsNullableSerializer: KSerializer<ObjectType?>,
inputsSerializer: KSerializer<InputValue>,
idsSerializer: KSerializer<IdType>
idsSerializer: KSerializer<IdType>,
unifiedRouter: UnifiedRouter
) {
val listObjectsSerializer = ListSerializer(objectsSerializer)
val listInputSerializer = ListSerializer(inputsSerializer)
@ -25,58 +29,80 @@ fun <ObjectType, IdType, InputValue> Route.configureWriteStandardCrudRepoRoutes(
)
val listInputUpdateSerializer = ListSerializer(inputUpdateSerializer)
includeWebsocketHandling(
newObjectsFlowRouting,
originalRepo.newObjectsFlow,
objectsSerializer
)
includeWebsocketHandling(
updatedObjectsFlowRouting,
originalRepo.updatedObjectsFlow,
objectsSerializer
)
includeWebsocketHandling(
deletedObjectsIdsFlowRouting,
originalRepo.deletedObjectsIdsFlow,
idsSerializer
)
unifiedRouter.apply {
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)
unifiedRouter.apply {
unianswer(
listObjectsSerializer,
originalRepo.create(
uniload(listInputSerializer)
)
)
)
}
}
post(updateRouting) {
val (id, input) = call.uniload(inputUpdateSerializer)
call.unianswer(
objectsNullableSerializer,
originalRepo.update(
id, input
unifiedRouter.apply {
val (id, input) = uniload(inputUpdateSerializer)
unianswer(
objectsNullableSerializer,
originalRepo.update(
id, input
)
)
)
}
}
post(updateManyRouting) {
val updates = call.uniload(listInputUpdateSerializer)
call.unianswer(
listObjectsSerializer,
originalRepo.update(
updates
unifiedRouter.apply {
val updates = uniload(listInputUpdateSerializer)
unianswer(
listObjectsSerializer,
originalRepo.update(
updates
)
)
)
}
}
post(deleteByIdRouting) {
val ids = call.uniload(listIdsSerializer)
call.unianswer(
Unit.serializer(),
originalRepo.deleteById(
ids
unifiedRouter.apply {
val ids = uniload(listIdsSerializer)
unianswer(
Unit.serializer(),
originalRepo.deleteById(
ids
)
)
)
}
}
}
fun <ObjectType, IdType, InputValue> Route.configureWriteStandardCrudRepoRoutes(
originalRepo: WriteStandardCRUDRepo<ObjectType, IdType, InputValue>,
objectsSerializer: KSerializer<ObjectType>,
objectsNullableSerializer: KSerializer<ObjectType?>,
inputsSerializer: KSerializer<InputValue>,
idsSerializer: KSerializer<IdType>,
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat,
serialFormatContentType: ContentType = standardKtorSerialFormatContentType
) = configureWriteStandardCrudRepoRoutes(
originalRepo, objectsSerializer, objectsNullableSerializer, inputsSerializer, idsSerializer, UnifiedRouter(serialFormat, serialFormatContentType)
)

View File

@ -1,16 +1,22 @@
package dev.inmo.micro_utils.repos.ktor.server.key_value
import dev.inmo.micro_utils.ktor.common.StandardKtorSerialFormat
import dev.inmo.micro_utils.ktor.common.standardKtorSerialFormat
import dev.inmo.micro_utils.ktor.server.UnifiedRouter
import dev.inmo.micro_utils.ktor.server.standardKtorSerialFormatContentType
import dev.inmo.micro_utils.repos.StandardKeyValueRepo
import io.ktor.http.ContentType
import io.ktor.routing.Route
import io.ktor.routing.route
import kotlinx.serialization.KSerializer
fun <K, V> Route.configureStandartKeyValueRepoRoutes(
fun <K, V> Route.configureStandardKeyValueRepoRoutes(
baseSubpart: String,
originalRepo: StandardKeyValueRepo<K, V>,
keySerializer: KSerializer<K>,
valueSerializer: KSerializer<V>,
valueNullableSerializer: KSerializer<V?>,
unifiedRouter: UnifiedRouter
) {
route(baseSubpart) {
configureReadStandartKeyValueRepoRoutes(
@ -18,11 +24,23 @@ fun <K, V> Route.configureStandartKeyValueRepoRoutes(
keySerializer,
valueSerializer,
valueNullableSerializer,
unifiedRouter
)
configureWriteStandartKeyValueRepoRoutes(
configureWriteStandardKeyValueRepoRoutes(
originalRepo,
keySerializer,
valueSerializer,
unifiedRouter
)
}
}
}
fun <K, V> Route.configureStandartKeyValueRepoRoutes(
baseSubpart: String,
originalRepo: StandardKeyValueRepo<K, V>,
keySerializer: KSerializer<K>,
valueSerializer: KSerializer<V>,
valueNullableSerializer: KSerializer<V?>,
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat,
serialFormatContentType: ContentType = standardKtorSerialFormatContentType
) = configureStandardKeyValueRepoRoutes(baseSubpart, originalRepo, keySerializer, valueSerializer, valueNullableSerializer, UnifiedRouter(serialFormat, serialFormatContentType))

View File

@ -1,5 +1,7 @@
package dev.inmo.micro_utils.repos.ktor.server.key_value
import dev.inmo.micro_utils.ktor.common.StandardKtorSerialFormat
import dev.inmo.micro_utils.ktor.common.standardKtorSerialFormat
import dev.inmo.micro_utils.ktor.server.*
import dev.inmo.micro_utils.pagination.PaginationResult
import dev.inmo.micro_utils.pagination.extractPagination
@ -7,6 +9,7 @@ import dev.inmo.micro_utils.repos.ReadStandardKeyValueRepo
import dev.inmo.micro_utils.repos.ktor.common.key_value.*
import dev.inmo.micro_utils.repos.ktor.common.valueParameterName
import io.ktor.application.call
import io.ktor.http.ContentType
import io.ktor.routing.Route
import io.ktor.routing.get
import kotlinx.serialization.KSerializer
@ -17,62 +20,84 @@ fun <K, V> Route.configureReadStandartKeyValueRepoRoutes (
keySerializer: KSerializer<K>,
valueSerializer: KSerializer<V>,
valueNullableSerializer: KSerializer<V?>,
unifiedRouter: UnifiedRouter
) {
get(getRoute) {
val key = call.decodeUrlQueryValueOrSendError(
keyParameterName,
keySerializer
) ?: return@get
unifiedRouter.apply {
val key = decodeUrlQueryValueOrSendError(
keyParameterName,
keySerializer
) ?: return@get
call.unianswer(
valueNullableSerializer,
originalRepo.get(key)
)
unianswer(
valueNullableSerializer,
originalRepo.get(key)
)
}
}
get(valuesRoute) {
val parination = call.request.queryParameters.extractPagination;
val reversed = call.decodeUrlQueryValueOrSendError(
reversedParameterName,
Boolean.serializer()
) ?: return@get
unifiedRouter.apply {
val parination = call.request.queryParameters.extractPagination;
val reversed = decodeUrlQueryValueOrSendError(
reversedParameterName,
Boolean.serializer()
) ?: return@get
call.unianswer(
PaginationResult.serializer(valueSerializer),
originalRepo.values(parination, reversed)
)
unianswer(
PaginationResult.serializer(valueSerializer),
originalRepo.values(parination, reversed)
)
}
}
get(keysRoute) {
val parination = call.request.queryParameters.extractPagination;
val reversed = call.decodeUrlQueryValueOrSendError(
reversedParameterName,
Boolean.serializer()
) ?: return@get
val value = call.decodeUrlQueryValue(valueParameterName, valueSerializer)
unifiedRouter.apply {
val parination = call.request.queryParameters.extractPagination;
val reversed = decodeUrlQueryValueOrSendError(
reversedParameterName,
Boolean.serializer()
) ?: return@get
val value = decodeUrlQueryValue(valueParameterName, valueSerializer)
call.unianswer(
PaginationResult.serializer(keySerializer),
value ?.let { originalRepo.keys(value, parination, reversed) } ?: originalRepo.keys(parination, reversed)
)
unianswer(
PaginationResult.serializer(keySerializer),
value?.let { originalRepo.keys(value, parination, reversed) } ?: originalRepo.keys(parination, reversed)
)
}
}
get(containsRoute) {
val key = call.decodeUrlQueryValueOrSendError(
keyParameterName,
keySerializer
) ?: return@get
unifiedRouter.apply {
val key = decodeUrlQueryValueOrSendError(
keyParameterName,
keySerializer
) ?: return@get
call.unianswer(
Boolean.serializer(),
originalRepo.contains(key)
)
unianswer(
Boolean.serializer(),
originalRepo.contains(key)
)
}
}
get(countRoute) {
call.unianswer(
Long.serializer(),
originalRepo.count()
)
unifiedRouter.apply {
unianswer(
Long.serializer(),
originalRepo.count()
)
}
}
}
}
inline fun <K, V> Route.configureReadStandartKeyValueRepoRoutes (
originalRepo: ReadStandardKeyValueRepo<K, V>,
keySerializer: KSerializer<K>,
valueSerializer: KSerializer<V>,
valueNullableSerializer: KSerializer<V?>,
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat,
serialFormatContentType: ContentType = standardKtorSerialFormatContentType
) = configureReadStandartKeyValueRepoRoutes(
originalRepo, keySerializer, valueSerializer, valueNullableSerializer, UnifiedRouter(serialFormat, serialFormatContentType)
)

View File

@ -1,44 +1,61 @@
package dev.inmo.micro_utils.repos.ktor.server.key_value
import dev.inmo.micro_utils.ktor.common.StandardKtorSerialFormat
import dev.inmo.micro_utils.ktor.common.standardKtorSerialFormat
import dev.inmo.micro_utils.ktor.server.*
import dev.inmo.micro_utils.repos.WriteStandardKeyValueRepo
import dev.inmo.micro_utils.repos.ktor.common.key_value.*
import io.ktor.application.call
import io.ktor.http.ContentType
import io.ktor.routing.Route
import io.ktor.routing.post
import kotlinx.serialization.KSerializer
import kotlinx.serialization.builtins.*
fun <K, V> Route.configureWriteStandardKeyValueRepoRoutes (
originalRepo: WriteStandardKeyValueRepo<K, V>,
keySerializer: KSerializer<K>,
valueSerializer: KSerializer<V>,
unifiedRouter: UnifiedRouter
) {
val keyValueMapSerializer = MapSerializer(keySerializer, valueSerializer)
val keysListSerializer = ListSerializer(keySerializer)
unifiedRouter.apply {
includeWebsocketHandling(
onNewValueRoute,
originalRepo.onNewValue,
PairSerializer(keySerializer, valueSerializer)
)
includeWebsocketHandling(
onValueRemovedRoute,
originalRepo.onValueRemoved,
keySerializer
)
}
post(setRoute) {
unifiedRouter.apply {
val toSet = uniload(
keyValueMapSerializer
)
unianswer(Unit.serializer(), originalRepo.set(toSet))
}
}
post(unsetRoute) {
unifiedRouter.apply {
val toUnset = uniload(keysListSerializer)
unianswer(Unit.serializer(), originalRepo.unset(toUnset))
}
}
}
fun <K, V> Route.configureWriteStandartKeyValueRepoRoutes (
originalRepo: WriteStandardKeyValueRepo<K, V>,
keySerializer: KSerializer<K>,
valueSerializer: KSerializer<V>,
) {
val keyValueMapSerializer = MapSerializer(keySerializer, valueSerializer)
val keysListSerializer = ListSerializer(keySerializer)
includeWebsocketHandling(
onNewValueRoute,
originalRepo.onNewValue,
PairSerializer(keySerializer, valueSerializer)
)
includeWebsocketHandling(
onValueRemovedRoute,
originalRepo.onValueRemoved,
keySerializer
)
post(setRoute) {
val toSet = call.uniload(
keyValueMapSerializer
)
call.unianswer(Unit.serializer(), originalRepo.set(toSet))
}
post(unsetRoute) {
val toUnset = call.uniload(keysListSerializer)
call.unianswer(Unit.serializer(), originalRepo.unset(toUnset))
}
}
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat,
serialFormatContentType: ContentType = standardKtorSerialFormatContentType
) = configureWriteStandardKeyValueRepoRoutes(originalRepo, keySerializer, valueSerializer, UnifiedRouter(serialFormat, serialFormatContentType))

View File

@ -1,6 +1,11 @@
package dev.inmo.micro_utils.repos.ktor.server.one_to_many
import dev.inmo.micro_utils.ktor.common.StandardKtorSerialFormat
import dev.inmo.micro_utils.ktor.common.standardKtorSerialFormat
import dev.inmo.micro_utils.ktor.server.UnifiedRouter
import dev.inmo.micro_utils.ktor.server.standardKtorSerialFormatContentType
import dev.inmo.micro_utils.repos.OneToManyKeyValueRepo
import io.ktor.http.ContentType
import io.ktor.routing.Route
import io.ktor.routing.route
import kotlinx.serialization.KSerializer
@ -9,10 +14,22 @@ fun <Key, Value> Route.configureOneToManyKeyValueRepoRoutes(
baseSubpart: String,
originalRepo: OneToManyKeyValueRepo<Key, Value>,
keySerializer: KSerializer<Key>,
valueSealizer: KSerializer<Value>,
valueSerializer: KSerializer<Value>,
unifiedRouter: UnifiedRouter
) {
route(baseSubpart) {
configureOneToManyReadKeyValueRepoRoutes(originalRepo, keySerializer, valueSealizer)
configureOneToManyWriteKeyValueRepoRoutes(originalRepo, keySerializer, valueSealizer)
configureOneToManyReadKeyValueRepoRoutes(originalRepo, keySerializer, valueSerializer, unifiedRouter)
configureOneToManyWriteKeyValueRepoRoutes(originalRepo, keySerializer, valueSerializer, unifiedRouter)
}
}
}
fun <Key, Value> Route.configureOneToManyKeyValueRepoRoutes(
baseSubpart: String,
originalRepo: OneToManyKeyValueRepo<Key, Value>,
keySerializer: KSerializer<Key>,
valueSerializer: KSerializer<Value>,
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat,
serialFormatContentType: ContentType = standardKtorSerialFormatContentType
) = configureOneToManyKeyValueRepoRoutes(
baseSubpart, originalRepo, keySerializer, valueSerializer, UnifiedRouter(serialFormat, serialFormatContentType)
)

View File

@ -1,5 +1,7 @@
package dev.inmo.micro_utils.repos.ktor.server.one_to_many
import dev.inmo.micro_utils.ktor.common.StandardKtorSerialFormat
import dev.inmo.micro_utils.ktor.common.standardKtorSerialFormat
import dev.inmo.micro_utils.ktor.server.*
import dev.inmo.micro_utils.pagination.PaginationResult
import dev.inmo.micro_utils.pagination.extractPagination
@ -10,6 +12,7 @@ import dev.inmo.micro_utils.repos.ktor.common.one_to_many.*
import dev.inmo.micro_utils.repos.ktor.common.valueParameterName
import dev.inmo.micro_utils.repos.ktor.common.reversedParameterName
import io.ktor.application.call
import io.ktor.http.ContentType
import io.ktor.routing.Route
import io.ktor.routing.get
import kotlinx.serialization.KSerializer
@ -18,89 +21,110 @@ import kotlinx.serialization.builtins.serializer
fun <Key, Value> Route.configureOneToManyReadKeyValueRepoRoutes(
originalRepo: ReadOneToManyKeyValueRepo<Key, Value>,
keySerializer: KSerializer<Key>,
valueSealizer: KSerializer<Value>,
valueSerializer: KSerializer<Value>,
unifiedRouter: UnifiedRouter
) {
val paginationKeyResult = PaginationResult.serializer(keySerializer)
val paginationValueResult = PaginationResult.serializer(valueSealizer)
val paginationValueResult = PaginationResult.serializer(valueSerializer)
get(getRoute) {
val pagination = call.request.queryParameters.extractPagination
val key = call.decodeUrlQueryValueOrSendError(
keyParameterName,
keySerializer
) ?: return@get
val reversed = call.decodeUrlQueryValue(
reversedParameterName,
Boolean.serializer()
) ?: false
unifiedRouter.apply {
val pagination = call.request.queryParameters.extractPagination
val key = decodeUrlQueryValueOrSendError(
keyParameterName,
keySerializer
) ?: return@get
val reversed = decodeUrlQueryValue(
reversedParameterName,
Boolean.serializer()
) ?: false
call.unianswer(
paginationValueResult,
originalRepo.get(key, pagination, reversed)
)
unianswer(
paginationValueResult,
originalRepo.get(key, pagination, reversed)
)
}
}
get(keysRoute) {
val pagination = call.request.queryParameters.extractPagination
val reversed = call.decodeUrlQueryValue(
reversedParameterName,
Boolean.serializer()
) ?: false
val value: Value? = call.decodeUrlQueryValue(
valueParameterName,
valueSealizer
)
unifiedRouter.apply {
val pagination = call.request.queryParameters.extractPagination
val reversed = decodeUrlQueryValue(
reversedParameterName,
Boolean.serializer()
) ?: false
val value: Value? = decodeUrlQueryValue(
valueParameterName,
valueSerializer
)
call.unianswer(
paginationKeyResult,
value ?.let { originalRepo.keys(value, pagination, reversed) } ?: originalRepo.keys(pagination, reversed)
)
unianswer(
paginationKeyResult,
value?.let { originalRepo.keys(value, pagination, reversed) } ?: originalRepo.keys(pagination, reversed)
)
}
}
get(containsByKeyRoute) {
val key = call.decodeUrlQueryValueOrSendError(
keyParameterName,
keySerializer
) ?: return@get
unifiedRouter.apply {
val key = decodeUrlQueryValueOrSendError(
keyParameterName,
keySerializer
) ?: return@get
call.unianswer(
Boolean.serializer(),
originalRepo.contains(key)
)
unianswer(
Boolean.serializer(),
originalRepo.contains(key)
)
}
}
get(containsByKeyValueRoute) {
val key = call.decodeUrlQueryValueOrSendError(
keyParameterName,
keySerializer
) ?: return@get
val value = call.decodeUrlQueryValueOrSendError(
valueParameterName,
valueSealizer
) ?: return@get
unifiedRouter.apply {
val key = decodeUrlQueryValueOrSendError(
keyParameterName,
keySerializer
) ?: return@get
val value = decodeUrlQueryValueOrSendError(
valueParameterName,
valueSerializer
) ?: return@get
call.unianswer(
Boolean.serializer(),
originalRepo.contains(key, value)
)
unianswer(
Boolean.serializer(),
originalRepo.contains(key, value)
)
}
}
get(countByKeyRoute) {
val key = call.decodeUrlQueryValueOrSendError(
keyParameterName,
keySerializer
) ?: return@get
unifiedRouter.apply {
val key = decodeUrlQueryValueOrSendError(
keyParameterName,
keySerializer
) ?: return@get
call.unianswer(
Long.serializer(),
originalRepo.count(key)
)
unianswer(
Long.serializer(),
originalRepo.count(key)
)
}
}
get(countRoute) {
call.unianswer(
Long.serializer(),
originalRepo.count()
)
unifiedRouter.apply {
unianswer(
Long.serializer(),
originalRepo.count()
)
}
}
}
}
inline fun <Key, Value> Route.configureOneToManyReadKeyValueRepoRoutes(
originalRepo: ReadOneToManyKeyValueRepo<Key, Value>,
keySerializer: KSerializer<Key>,
valueSerializer: KSerializer<Value>,
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat,
serialFormatContentType: ContentType = standardKtorSerialFormatContentType
) = configureOneToManyReadKeyValueRepoRoutes(originalRepo, keySerializer, valueSerializer, UnifiedRouter(serialFormat, serialFormatContentType))

View File

@ -1,9 +1,12 @@
package dev.inmo.micro_utils.repos.ktor.server.one_to_many
import dev.inmo.micro_utils.ktor.common.StandardKtorSerialFormat
import dev.inmo.micro_utils.ktor.common.standardKtorSerialFormat
import dev.inmo.micro_utils.ktor.server.*
import dev.inmo.micro_utils.repos.WriteOneToManyKeyValueRepo
import dev.inmo.micro_utils.repos.ktor.common.one_to_many.*
import io.ktor.application.call
import io.ktor.http.ContentType
import io.ktor.routing.Route
import io.ktor.routing.post
import kotlinx.serialization.KSerializer
@ -13,61 +16,78 @@ fun <Key, Value> Route.configureOneToManyWriteKeyValueRepoRoutes(
originalRepo: WriteOneToManyKeyValueRepo<Key, Value>,
keySerializer: KSerializer<Key>,
valueSerializer: KSerializer<Value>,
unifiedRouter: UnifiedRouter
) {
val keyValueSerializer = PairSerializer(keySerializer, valueSerializer)
val keyValueMapSerializer = MapSerializer(keySerializer, ListSerializer(valueSerializer))
includeWebsocketHandling(
onNewValueRoute,
originalRepo.onNewValue,
keyValueSerializer
)
includeWebsocketHandling(
onValueRemovedRoute,
originalRepo.onValueRemoved,
keyValueSerializer
)
includeWebsocketHandling(
onDataClearedRoute,
originalRepo.onDataCleared,
keySerializer
)
unifiedRouter.apply {
includeWebsocketHandling(
onNewValueRoute,
originalRepo.onNewValue,
keyValueSerializer
)
includeWebsocketHandling(
onValueRemovedRoute,
originalRepo.onValueRemoved,
keyValueSerializer
)
includeWebsocketHandling(
onDataClearedRoute,
originalRepo.onDataCleared,
keySerializer
)
}
post(addRoute) {
val obj = call.uniload(keyValueMapSerializer)
unifiedRouter.apply {
val obj = uniload(keyValueMapSerializer)
call.unianswer(
Unit.serializer(),
originalRepo.add(obj)
)
unianswer(
Unit.serializer(),
originalRepo.add(obj)
)
}
}
post(removeRoute) {
val obj = call.uniload(
keyValueMapSerializer
)
unifiedRouter.apply {
val obj = uniload(keyValueMapSerializer)
call.unianswer(
Unit.serializer(),
originalRepo.remove(obj),
)
unianswer(
Unit.serializer(),
originalRepo.remove(obj),
)
}
}
post(clearRoute) {
val key = call.uniload(keySerializer)
unifiedRouter.apply {
val key = uniload(keySerializer)
call.unianswer(
Unit.serializer(),
originalRepo.clear(key),
)
unianswer(
Unit.serializer(),
originalRepo.clear(key),
)
}
}
post(setRoute) {
val obj = call.uniload(keyValueMapSerializer)
unifiedRouter.apply {
val obj = uniload(keyValueMapSerializer)
call.unianswer(
Unit.serializer(),
originalRepo.set(obj)
)
unianswer(
Unit.serializer(),
originalRepo.set(obj)
)
}
}
}
}
fun <Key, Value> Route.configureOneToManyWriteKeyValueRepoRoutes(
originalRepo: WriteOneToManyKeyValueRepo<Key, Value>,
keySerializer: KSerializer<Key>,
valueSerializer: KSerializer<Value>,
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat,
serialFormatContentType: ContentType = standardKtorSerialFormatContentType
) = configureOneToManyWriteKeyValueRepoRoutes(originalRepo, keySerializer, valueSerializer, UnifiedRouter(serialFormat, serialFormatContentType))