add ktor standard realisation of crud repo

This commit is contained in:
InsanusMokrassar 2020-08-25 14:46:44 +06:00
parent fbae8cac93
commit 14d6915282
12 changed files with 343 additions and 10 deletions

View File

@ -18,19 +18,18 @@ class ReadPostsRepoKtorClient(
private val baseUrl: String,
private val client: HttpClient = HttpClient()
) : ReadPostsRepo {
override suspend fun getPostsIds(): Set<PostId> = client.get<ByteArray>(
"$baseUrl/$getPostsIdsRoute"
).let {
standardKtorSerialFormat.decodeFromByteArray(postIdsSerializer, it)
}
override suspend fun getPostsIds(): Set<PostId> = client.uniget(
buildStandardUrl(baseUrl, getPostsIdsRoute),
postIdsSerializer
)
override suspend fun getPostById(id: PostId): RegisteredPost? = client.uniget(
"$baseUrl/$getPostByIdRoute/$id",
buildStandardUrl(baseUrl, "$getPostByIdRoute/$id"),
RegisteredPost.serializer().nullable
)
override suspend fun getPostsByContent(id: ContentId): List<RegisteredPost> = client.uniget(
"$baseUrl/$getPostsByContentRoute/$id",
buildStandardUrl(baseUrl, "$getPostsByContentRoute/$id"),
registeredPostsListSerializer
)
@ -39,14 +38,18 @@ class ReadPostsRepoKtorClient(
to: DateTime,
pagination: Pagination
): PaginationResult<RegisteredPost> = client.uniget(
"$baseUrl/$getPostsByCreatingDatesRoute".includeQueryParams(
buildStandardUrl(
baseUrl,
getPostsByCreatingDatesRoute,
(from to to).asFromToUrlPart + pagination.asUrlQueryParts
),
registeredPostsPaginationResultSerializer
)
override suspend fun getPostsByPagination(pagination: Pagination): PaginationResult<RegisteredPost> = client.uniget(
"$baseUrl/$getPostsByPaginationRoute".includeQueryParams(
buildStandardUrl(
baseUrl,
getPostsByCreatingDatesRoute,
pagination.asUrlQueryParts
),
registeredPostsPaginationResultSerializer

View File

@ -13,7 +13,7 @@ import kotlinx.coroutines.flow.channelFlow
* @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 <reified T> HttpClient.createStandardWebsocketFlow(
inline fun <T> HttpClient.createStandardWebsocketFlow(
url: String,
crossinline checkReconnection: (Throwable?) -> Boolean = { true },
crossinline conversation: suspend (ByteArray) -> T

View File

@ -0,0 +1,9 @@
package com.insanusmokrassar.postssystem.ktor
fun buildStandardUrl(
basePart: String,
subpart: String,
parameters: QueryParams = emptyMap()
) = "$basePart/$subpart".includeQueryParams(
parameters
)

View File

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

View File

@ -0,0 +1,74 @@
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()
js (BOTH) {
browser()
nodejs()
}
sourceSets {
commonMain {
dependencies {
implementation kotlin('stdlib')
api projectByName("postssystem.utils.repos.ktor.common")
api projectByName("postssystem.ktor.client")
}
}
commonTest {
dependencies {
implementation kotlin('test-common')
implementation kotlin('test-annotations-common')
}
}
jvmMain {
dependencies {
implementation kotlin('stdlib-jdk8')
}
}
jvmTest {
dependencies {
implementation kotlin('test-junit')
}
}
jsMain {
dependencies {
implementation kotlin('stdlib-js')
}
}
jsTest {
dependencies {
implementation kotlin('test-js')
implementation kotlin('test-junit')
}
}
}
}

View File

@ -0,0 +1,49 @@
package com.insanusmokrassar.postssystem.utils.repos.ktor.client
import com.insanusmokrassar.postssystem.ktor.*
import com.insanusmokrassar.postssystem.ktor.client.uniget
import com.insanusmokrassar.postssystem.utils.common.pagination.Pagination
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.client.HttpClient
import kotlinx.serialization.KSerializer
import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.encodeToHexString
class KtorReadStandardCrudRepo<ObjectType, IdType> (
private val baseUrl: String,
private val client: HttpClient = HttpClient(),
private val objectsSerializer: KSerializer<ObjectType>,
private val objectsSerializerNullable: KSerializer<ObjectType?>,
private val idsSerializer: KSerializer<IdType>
) : ReadStandardCRUDRepo<ObjectType, IdType> {
private val paginationResultSerializer = PaginationResult.serializer(objectsSerializer)
override suspend fun getByPagination(pagination: Pagination): PaginationResult<ObjectType> = client.uniget(
buildStandardUrl(baseUrl, getByPaginationRouting, pagination.asUrlQueryParts),
paginationResultSerializer
)
override suspend fun getById(id: IdType): ObjectType? = client.uniget(
buildStandardUrl(
baseUrl,
getByIdRouting,
mapOf(
"id" to standardKtorSerialFormat.encodeToHexString(idsSerializer, id)
)
),
objectsSerializerNullable
)
override suspend fun contains(id: IdType): Boolean = client.uniget(
buildStandardUrl(
baseUrl,
containsRouting,
mapOf(
"id" to standardKtorSerialFormat.encodeToHexString(idsSerializer, id)
)
),
Boolean.serializer()
)
}

View File

@ -0,0 +1,30 @@
package com.insanusmokrassar.postssystem.utils.repos.ktor.client
import com.insanusmokrassar.postssystem.utils.repos.*
import io.ktor.client.HttpClient
import kotlinx.serialization.KSerializer
class KtorStandardCrudRepo<ObjectType, IdType, InputValue> (
baseUrl: String,
baseSubpart: String,
client: HttpClient,
objectsSerializer: KSerializer<ObjectType>,
objectsNullableSerializer: KSerializer<ObjectType?>,
inputsSerializer: KSerializer<InputValue>,
idsSerializer: KSerializer<IdType>
) : StandardCRUDRepo<ObjectType, IdType, InputValue>,
ReadStandardCRUDRepo<ObjectType, IdType> by KtorReadStandardCrudRepo(
"$baseUrl/$baseSubpart",
client,
objectsSerializer,
objectsNullableSerializer,
idsSerializer
),
WriteStandardCRUDRepo<ObjectType, IdType, InputValue> by KtorWriteStandardCrudRepo(
"$baseUrl/$baseSubpart",
client,
objectsSerializer,
objectsNullableSerializer,
inputsSerializer,
idsSerializer
)

View File

@ -0,0 +1,67 @@
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,
private val client: HttpClient = HttpClient(),
private val objectsSerializer: KSerializer<ObjectType>,
private val objectsNullableSerializer: KSerializer<ObjectType?>,
private val inputsSerializer: KSerializer<InputValue>,
private val idsSerializer: KSerializer<IdType>
) : WriteStandardCRUDRepo<ObjectType, IdType, InputValue> {
private val listObjectsSerializer = ListSerializer(objectsSerializer)
private val listInputSerializer = ListSerializer(inputsSerializer)
private val listIdsSerializer = ListSerializer(idsSerializer)
private val inputUpdateSerializer = TemporalInputObjectForUpdate.serializer(
idsSerializer,
inputsSerializer
)
private val listInputUpdateSerializer = ListSerializer(inputUpdateSerializer)
override val newObjectsFlow: Flow<ObjectType> = client.createStandardWebsocketFlow(
buildStandardUrl(baseUrl, newObjectsFlowRouting)
) { standardKtorSerialFormat.decodeFromByteArray(objectsSerializer, it) }
override val updatedObjectsFlow: Flow<ObjectType> = client.createStandardWebsocketFlow(
buildStandardUrl(baseUrl, updatedObjectsFlowRouting)
) { standardKtorSerialFormat.decodeFromByteArray(objectsSerializer, it) }
override val deletedObjectsIdsFlow: Flow<IdType> = client.createStandardWebsocketFlow(
buildStandardUrl(baseUrl, deletedObjectsIdsFlowRouting)
) { standardKtorSerialFormat.decodeFromByteArray(idsSerializer, it) }
override suspend fun create(vararg values: InputValue): List<ObjectType> = client.unipost(
buildStandardUrl(baseUrl, createRouting),
BodyPair(listInputSerializer, values.toList()),
listObjectsSerializer
)
override suspend fun update(id: IdType, value: InputValue): ObjectType? = client.unipost(
buildStandardUrl(baseUrl, updateRouting),
BodyPair(inputUpdateSerializer, TemporalInputObjectForUpdate(id, value)),
objectsNullableSerializer
)
override suspend fun update(vararg values: UpdatedValuePair<IdType, InputValue>): List<ObjectType> = client.unipost(
buildStandardUrl(baseUrl, updateManyRouting),
BodyPair(listInputUpdateSerializer, values.map { TemporalInputObjectForUpdate(it.first, it.second) }),
listObjectsSerializer
)
override suspend fun deleteById(vararg ids: IdType) = client.unipost(
buildStandardUrl(baseUrl, deleteByIdRouting),
BodyPair(listIdsSerializer, ids.toList()),
Unit.serializer()
)
}

View File

@ -0,0 +1,74 @@
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()
js (BOTH) {
browser()
nodejs()
}
sourceSets {
commonMain {
dependencies {
implementation kotlin('stdlib')
api projectByName("postssystem.utils.repos.common")
api projectByName("postssystem.ktor.common")
}
}
commonTest {
dependencies {
implementation kotlin('test-common')
implementation kotlin('test-annotations-common')
}
}
jvmMain {
dependencies {
implementation kotlin('stdlib-jdk8')
}
}
jvmTest {
dependencies {
implementation kotlin('test-junit')
}
}
jsMain {
dependencies {
implementation kotlin('stdlib-js')
}
}
jsTest {
dependencies {
implementation kotlin('test-js')
implementation kotlin('test-junit')
}
}
}
}

View File

@ -0,0 +1,6 @@
package com.insanusmokrassar.postssystem.utils.repos.ktor.common
const val getByPaginationRouting = "getByPagination"
const val getByIdRouting = "getById"
const val containsRouting = "contains"
const val getAllRouting = "getAll"

View File

@ -0,0 +1,10 @@
package com.insanusmokrassar.postssystem.utils.repos.ktor.common
const val newObjectsFlowRouting = "newObjectsFlow"
const val updatedObjectsFlowRouting = "updatedObjectsFlow"
const val deletedObjectsIdsFlowRouting = "deletedObjectsIdsFlow"
const val createRouting = "create"
const val updateRouting = "update"
const val updateManyRouting = "updateMany"
const val deleteByIdRouting = "deleteById"

View File

@ -0,0 +1,9 @@
package com.insanusmokrassar.postssystem.utils.repos.ktor.common
import kotlinx.serialization.Serializable
@Serializable
data class TemporalInputObjectForUpdate<IdType, InputValue>(
val id: IdType,
val input: InputValue
)