commonize url query parameters encoding/decoding

This commit is contained in:
2020-08-31 00:29:34 +06:00
parent 00068a064f
commit 4cc4d3d4ec
6 changed files with 41 additions and 37 deletions
ktor
client
src
commonMain
kotlin
com
insanusmokrassar
postssystem
common
src
commonMain
kotlin
com
insanusmokrassar
postssystem
server
src
jvmMain
kotlin
com
insanusmokrassar
postssystem
utils/repos/ktor
client
src
commonMain
kotlin
com
insanusmokrassar
postssystem
utils
repos
server
src
jvmMain
kotlin
com
insanusmokrassar

@ -4,8 +4,7 @@ import com.insanusmokrassar.postssystem.ktor.standardKtorSerialFormat
import io.ktor.client.HttpClient import io.ktor.client.HttpClient
import io.ktor.client.request.get import io.ktor.client.request.get
import io.ktor.client.request.post import io.ktor.client.request.post
import kotlinx.serialization.DeserializationStrategy import kotlinx.serialization.*
import kotlinx.serialization.SerializationStrategy
typealias BodyPair<T> = Pair<SerializationStrategy<T>, T> typealias BodyPair<T> = Pair<SerializationStrategy<T>, T>
@ -18,6 +17,11 @@ suspend fun <ResultType> HttpClient.uniget(
standardKtorSerialFormat.decodeFromByteArray(resultDeserializer, it) standardKtorSerialFormat.decodeFromByteArray(resultDeserializer, it)
} }
fun <T> SerializationStrategy<T>.encodeUrlQueryValue(value: T) = standardKtorSerialFormat.encodeToHexString(
this,
value
)
suspend fun <BodyType, ResultType> HttpClient.unipost( suspend fun <BodyType, ResultType> HttpClient.unipost(
url: String, url: String,
bodyInfo: BodyPair<BodyType>, bodyInfo: BodyPair<BodyType>,

@ -1,6 +0,0 @@
package com.insanusmokrassar.postssystem.ktor
import kotlinx.serialization.*
fun <T> T.toHex(with: SerializationStrategy<T>) = standardKtorSerialFormat.encodeToHexString(with, this)
fun <T> String.fromHex(with: DeserializationStrategy<T>): T = standardKtorSerialFormat.decodeFromHexString(with, this)

@ -1,14 +1,12 @@
package com.insanusmokrassar.postssystem.ktor.server package com.insanusmokrassar.postssystem.ktor.server
import com.insanusmokrassar.postssystem.ktor.fromHex
import com.insanusmokrassar.postssystem.ktor.standardKtorSerialFormat import com.insanusmokrassar.postssystem.ktor.standardKtorSerialFormat
import io.ktor.application.ApplicationCall import io.ktor.application.ApplicationCall
import io.ktor.http.HttpStatusCode import io.ktor.http.HttpStatusCode
import io.ktor.response.respond import io.ktor.response.respond
import io.ktor.response.respondBytes import io.ktor.response.respondBytes
import io.ktor.util.toByteArray import io.ktor.util.toByteArray
import kotlinx.serialization.DeserializationStrategy import kotlinx.serialization.*
import kotlinx.serialization.SerializationStrategy
suspend fun <T> ApplicationCall.unianswer( suspend fun <T> ApplicationCall.unianswer(
answerSerializer: SerializationStrategy<T>, answerSerializer: SerializationStrategy<T>,
@ -27,18 +25,6 @@ suspend fun <T> ApplicationCall.uniload(
request.receiveChannel().toByteArray() request.receiveChannel().toByteArray()
) )
fun <T> ApplicationCall.uniloadFromQuery(
parameterName: String,
deserializer: DeserializationStrategy<T>
): T? = getQueryParameter(parameterName) ?.fromHex(deserializer)
suspend fun <T> ApplicationCall.uniloadFromQueryOrSendError(
parameterName: String,
deserializer: DeserializationStrategy<T>
): T? = uniloadFromQuery(parameterName, deserializer) ?: null.also {
respond(HttpStatusCode.BadRequest, "Request query parameters must contains $parameterName")
}
suspend fun ApplicationCall.getParameterOrSendError( suspend fun ApplicationCall.getParameterOrSendError(
field: String field: String
) = parameters[field].also { ) = parameters[field].also {
@ -58,3 +44,22 @@ suspend fun ApplicationCall.getQueryParameterOrSendError(
respond(HttpStatusCode.BadRequest, "Request query parameters must contains $field") respond(HttpStatusCode.BadRequest, "Request query parameters must contains $field")
} }
} }
fun <T> ApplicationCall.decodeUrlQueryValue(
field: String,
deserializer: DeserializationStrategy<T>
) = getQueryParameter(field) ?.let {
standardKtorSerialFormat.decodeFromHexString(
deserializer,
it
)
}
fun <T> ApplicationCall.decodeUrlQueryValueOrSendError(
field: String,
deserializer: DeserializationStrategy<T>
) = decodeUrlQueryValue(field, deserializer).also {
if (it == null) {
respond(HttpStatusCode.BadRequest, "Request query parameters must contains $field")
}
}

@ -1,6 +1,7 @@
package com.insanusmokrassar.postssystem.utils.repos.ktor.client.crud package com.insanusmokrassar.postssystem.utils.repos.ktor.client.crud
import com.insanusmokrassar.postssystem.ktor.* import com.insanusmokrassar.postssystem.ktor.*
import com.insanusmokrassar.postssystem.ktor.client.encodeUrlQueryValue
import com.insanusmokrassar.postssystem.ktor.client.uniget import com.insanusmokrassar.postssystem.ktor.client.uniget
import com.insanusmokrassar.postssystem.utils.common.pagination.Pagination import com.insanusmokrassar.postssystem.utils.common.pagination.Pagination
import com.insanusmokrassar.postssystem.utils.common.pagination.PaginationResult import com.insanusmokrassar.postssystem.utils.common.pagination.PaginationResult
@ -29,7 +30,7 @@ class KtorReadStandardCrudRepo<ObjectType, IdType> (
baseUrl, baseUrl,
getByIdRouting, getByIdRouting,
mapOf( mapOf(
"id" to id.toHex(idsSerializer) "id" to idsSerializer.encodeUrlQueryValue(id)
) )
), ),
objectsSerializerNullable objectsSerializerNullable
@ -40,7 +41,7 @@ class KtorReadStandardCrudRepo<ObjectType, IdType> (
baseUrl, baseUrl,
containsRouting, containsRouting,
mapOf( mapOf(
"id" to id.toHex(idsSerializer) "id" to idsSerializer.encodeUrlQueryValue(id)
) )
), ),
Boolean.serializer() Boolean.serializer()

@ -28,7 +28,7 @@ fun <ObjectType, IdType> Route.configureReadStandardCrudRepoRoutes(
} }
get(getByIdRouting) { get(getByIdRouting) {
val id = call.uniloadFromQueryOrSendError( val id = call.decodeUrlQueryValueOrSendError(
"id", "id",
idsSerializer idsSerializer
) ?: return@get ) ?: return@get
@ -40,7 +40,7 @@ fun <ObjectType, IdType> Route.configureReadStandardCrudRepoRoutes(
} }
get(containsRouting) { get(containsRouting) {
val id = call.uniloadFromQueryOrSendError( val id = call.decodeUrlQueryValueOrSendError(
"id", "id",
idsSerializer idsSerializer
) ?: return@get ) ?: return@get

@ -22,11 +22,11 @@ fun <Key, Value> Route.configureOneToManyReadKeyValueRepoRoutes(
get(getRoute) { get(getRoute) {
val pagination = call.request.queryParameters.extractPagination val pagination = call.request.queryParameters.extractPagination
val key = call.uniloadFromQueryOrSendError( val key = call.decodeUrlQueryValueOrSendError(
keyParameterName, keyParameterName,
keySerializer keySerializer
) ?: return@get ) ?: return@get
val reversed = call.uniloadFromQuery( val reversed = call.decodeUrlQueryValue(
reversedParameterName, reversedParameterName,
Boolean.serializer() Boolean.serializer()
) ?: false ) ?: false
@ -39,7 +39,7 @@ fun <Key, Value> Route.configureOneToManyReadKeyValueRepoRoutes(
get(keysRoute) { get(keysRoute) {
val pagination = call.request.queryParameters.extractPagination val pagination = call.request.queryParameters.extractPagination
val reversed = call.uniloadFromQuery( val reversed = call.decodeUrlQueryValue(
reversedParameterName, reversedParameterName,
Boolean.serializer() Boolean.serializer()
) ?: false ) ?: false
@ -51,10 +51,10 @@ fun <Key, Value> Route.configureOneToManyReadKeyValueRepoRoutes(
} }
get(containsByKeyRoute) { get(containsByKeyRoute) {
val key = standardKtorSerialFormat.decodeFromHexString( val key = call.decodeUrlQueryValueOrSendError(
keySerializer, keyParameterName,
call.getQueryParameterOrSendError(keyParameterName) ?: return@get keySerializer
) ) ?: return@get
call.unianswer( call.unianswer(
Boolean.serializer(), Boolean.serializer(),
@ -63,11 +63,11 @@ fun <Key, Value> Route.configureOneToManyReadKeyValueRepoRoutes(
} }
get(containsByKeyValueRoute) { get(containsByKeyValueRoute) {
val key = call.uniloadFromQueryOrSendError( val key = call.decodeUrlQueryValueOrSendError(
keyParameterName, keyParameterName,
keySerializer keySerializer
) ?: return@get ) ?: return@get
val value = call.uniloadFromQueryOrSendError( val value = call.decodeUrlQueryValueOrSendError(
valueParameterName, valueParameterName,
valueSealizer valueSealizer
) ?: return@get ) ?: return@get
@ -79,7 +79,7 @@ fun <Key, Value> Route.configureOneToManyReadKeyValueRepoRoutes(
} }
get(countByKeyRoute) { get(countByKeyRoute) {
val key = call.uniloadFromQueryOrSendError( val key = call.decodeUrlQueryValueOrSendError(
keyParameterName, keyParameterName,
keySerializer keySerializer
) ?: return@get ) ?: return@get