Skip to content

Upgrade to Ktor 2.0 #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@ repositories {
}

dependencies {
implementation("io.ktor:ktor-client-core:1.6.8")
implementation("io.ktor:ktor-client-cio:1.6.8")
implementation("io.ktor:ktor-client-serialization:1.6.8")
implementation("io.ktor:ktor-client-logging:1.6.8")
implementation(platform("io.ktor:ktor-bom:2.0.0"))

implementation("io.ktor:ktor-client-core")
implementation("io.ktor:ktor-client-cio")
implementation("io.ktor:ktor-client-content-negotiation")
implementation("io.ktor:ktor-serialization-kotlinx-json")
implementation("io.ktor:ktor-client-logging")

implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.3.2")
implementation("ch.qos.logback:logback-classic:1.2.11")
Expand Down
30 changes: 16 additions & 14 deletions src/main/kotlin/sh/nemo/meilisearch/apis/Documents.kt
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package sh.nemo.meilisearch.apis

import io.ktor.client.call.body
import io.ktor.client.request.delete
import io.ktor.client.request.get
import io.ktor.client.request.parameter
import io.ktor.client.request.post
import io.ktor.client.request.put
import io.ktor.client.request.setBody
import sh.nemo.meilisearch.Meilisearch
import sh.nemo.meilisearch.responses.ChangeResponse

Expand All @@ -13,35 +15,35 @@ suspend inline fun <reified T> Meilisearch.getDocuments(
offset: Int = 0,
limit: Int = 20,
attributesToRetrieve: String = "*"
) = this.client.get<List<T>>("/indexes/$indexUid/documents") {
): List<T> = this.client.get("/indexes/$indexUid/documents") {
parameter("offset", offset)
parameter("limit", limit)
parameter("attributesToRetrieve", attributesToRetrieve)
}
}.body()

suspend inline fun <reified T> Meilisearch.addDocuments(
indexUid: String,
documents: List<T>,
primaryKey: String? = null
) = this.client.post<ChangeResponse>("/indexes/$indexUid/documents") {
body = documents
): ChangeResponse = this.client.post("/indexes/$indexUid/documents") {
setBody(documents)
primaryKey?.let { parameter("primaryKey", it) }
}
}.body()

suspend inline fun <reified T> Meilisearch.updateDocuments(
indexUid: String,
documents: List<T>,
primaryKey: String? = null
) = this.client.put<ChangeResponse>("/indexes/$indexUid/documents") {
body = documents
): ChangeResponse = this.client.put("/indexes/$indexUid/documents") {
setBody(documents)
primaryKey?.let { parameter("primaryKey", it) }
}
}.body()

suspend inline fun <reified T> Meilisearch.getDocument(indexUid: String, documentId: String) =
this.client.get<T>("/indexes/$indexUid/documents/$documentId")
suspend inline fun <reified T> Meilisearch.getDocument(indexUid: String, documentId: String): T =
this.client.get("/indexes/$indexUid/documents/$documentId").body()

suspend fun Meilisearch.deleteAllDocuments(indexUid: String) =
this.client.delete<ChangeResponse>("/indexes/$indexUid/documents")
suspend fun Meilisearch.deleteAllDocuments(indexUid: String): ChangeResponse =
this.client.delete("/indexes/$indexUid/documents").body()

suspend fun Meilisearch.deleteDocument(indexUid: String, documentId: String) =
this.client.delete<ChangeResponse>("/indexes/$indexUid/documents/$documentId")
suspend fun Meilisearch.deleteDocument(indexUid: String, documentId: String): ChangeResponse =
this.client.delete("/indexes/$indexUid/documents/$documentId").body()
3 changes: 2 additions & 1 deletion src/main/kotlin/sh/nemo/meilisearch/apis/Health.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package sh.nemo.meilisearch.apis

import io.ktor.client.call.body
import io.ktor.client.request.get
import sh.nemo.meilisearch.Meilisearch
import sh.nemo.meilisearch.responses.HealthResponse

suspend fun Meilisearch.health() = this.client.get<HealthResponse>("/health")
suspend fun Meilisearch.health(): HealthResponse = this.client.get("/health").body()
24 changes: 13 additions & 11 deletions src/main/kotlin/sh/nemo/meilisearch/apis/Indexes.kt
Original file line number Diff line number Diff line change
@@ -1,27 +1,29 @@
package sh.nemo.meilisearch.apis

import io.ktor.client.call.body
import io.ktor.client.request.delete
import io.ktor.client.request.get
import io.ktor.client.request.post
import io.ktor.client.request.put
import io.ktor.client.request.setBody
import sh.nemo.meilisearch.Meilisearch
import sh.nemo.meilisearch.requests.IndexCreateRequest
import sh.nemo.meilisearch.requests.IndexUpdateRequest
import sh.nemo.meilisearch.responses.ChangeResponse
import sh.nemo.meilisearch.responses.IndexResponse

suspend fun Meilisearch.listIndexes() = this.client.get<List<IndexResponse>>("/indexes")
suspend fun Meilisearch.listIndexes(): List<IndexResponse> = this.client.get("/indexes").body()

suspend fun Meilisearch.createIndex(uid: String, primaryKey: String? = null) =
this.client.post<ChangeResponse>("/indexes") {
body = IndexCreateRequest(uid, primaryKey)
}
suspend fun Meilisearch.createIndex(uid: String, primaryKey: String? = null): ChangeResponse =
this.client.post("/indexes") {
setBody(IndexCreateRequest(uid, primaryKey))
}.body()

suspend fun Meilisearch.getIndex(uid: String) = this.client.get<IndexResponse>("/indexes/$uid")
suspend fun Meilisearch.getIndex(uid: String): IndexResponse = this.client.get("/indexes/$uid").body()

suspend fun Meilisearch.updateIndexPrimaryKey(uid: String, primaryKey: String? = null) =
this.client.put<ChangeResponse>("/indexes/$uid") {
body = IndexUpdateRequest(primaryKey)
}
suspend fun Meilisearch.updateIndexPrimaryKey(uid: String, primaryKey: String? = null): ChangeResponse =
this.client.put("/indexes/$uid") {
setBody(IndexUpdateRequest(primaryKey))
}.body()

suspend fun Meilisearch.deleteIndex(uid: String) = this.client.delete<ChangeResponse>("/indexes/$uid")
suspend fun Meilisearch.deleteIndex(uid: String): ChangeResponse = this.client.delete("/indexes/$uid").body()
25 changes: 14 additions & 11 deletions src/main/kotlin/sh/nemo/meilisearch/apis/Keys.kt
Original file line number Diff line number Diff line change
@@ -1,38 +1,41 @@
package sh.nemo.meilisearch.apis

import io.ktor.client.call.body
import io.ktor.client.request.delete
import io.ktor.client.request.get
import io.ktor.client.request.patch
import io.ktor.client.request.post
import io.ktor.client.request.setBody
import kotlinx.datetime.Instant
import sh.nemo.meilisearch.Meilisearch
import sh.nemo.meilisearch.requests.KeyUpsertRequest
import sh.nemo.meilisearch.responses.KeyResponse
import sh.nemo.meilisearch.responses.KeysResponse

suspend fun Meilisearch.listKeys() = this.client.get<KeysResponse>("/keys").results
suspend fun Meilisearch.listKeys(): List<KeyResponse> = this.client.get("/keys").body<KeysResponse>().results

suspend fun Meilisearch.createKey(
description: String? = null,
actions: List<String> = emptyList(),
indexes: List<String> = emptyList(),
expiresAt: Instant? = null,
) =
this.client.post<KeyResponse>("/keys") {
body = KeyUpsertRequest(description, actions, indexes, expiresAt)
}
): KeyResponse =
this.client.post("/keys") {
setBody(KeyUpsertRequest(description, actions, indexes, expiresAt))
}.body()

suspend fun Meilisearch.getKey(key: String) = this.client.get<KeyResponse>("/keys/$key")
suspend fun Meilisearch.getKey(key: String): KeyResponse = this.client.get("/keys/$key").body()
suspend fun Meilisearch.getKey2(key: String) = this.client.get("/keys/$key")

suspend fun Meilisearch.updateKey(
key: String,
description: String? = null,
actions: List<String> = emptyList(),
indexes: List<String> = emptyList(),
expiresAt: Instant? = null,
) =
this.client.patch<KeyResponse>("/keys/$key") {
body = KeyUpsertRequest(description, actions, indexes, expiresAt)
}
): KeyResponse =
this.client.patch("/keys/$key") {
setBody(KeyUpsertRequest(description, actions, indexes, expiresAt))
}.body()

suspend fun Meilisearch.deleteKey(key: String) = this.client.delete<Unit>("/keys/$key")
suspend fun Meilisearch.deleteKey(key: String) = this.client.delete("/keys/$key").body<Unit>()
34 changes: 19 additions & 15 deletions src/main/kotlin/sh/nemo/meilisearch/apis/Search.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package sh.nemo.meilisearch.apis

import io.ktor.client.call.body
import io.ktor.client.request.post
import io.ktor.client.request.setBody
import sh.nemo.meilisearch.Meilisearch
import sh.nemo.meilisearch.requests.SearchRequest
import sh.nemo.meilisearch.responses.SearchResponse
Expand All @@ -18,19 +20,21 @@ suspend inline fun <reified T> Meilisearch.search(
attributesToHighlight: List<String>? = null,
matches: Boolean = false,
sort: String? = null
) =
this.client.post<SearchResponse<T>>("/indexes/$indexUid/search") {
body = SearchRequest(
query,
offset,
limit,
filter,
facetsDistribution,
attributesToRetrieve,
attributesToCrop,
cropLength,
attributesToHighlight,
matches,
sort,
): SearchResponse<T> =
this.client.post("/indexes/$indexUid/search") {
setBody(
SearchRequest(
query,
offset,
limit,
filter,
facetsDistribution,
attributesToRetrieve,
attributesToCrop,
cropLength,
attributesToHighlight,
matches,
sort,
)
)
}
}.body()
13 changes: 7 additions & 6 deletions src/main/kotlin/sh/nemo/meilisearch/apis/Tasks.kt
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
package sh.nemo.meilisearch.apis

import io.ktor.client.call.body
import io.ktor.client.request.get
import kotlinx.datetime.Clock
import kotlinx.datetime.Instant
import sh.nemo.meilisearch.Meilisearch
import sh.nemo.meilisearch.responses.TaskResponse

suspend fun Meilisearch.listTasks() = this.client.get<List<TaskResponse>>("/tasks")
suspend fun Meilisearch.listTasks(): List<TaskResponse> = this.client.get("/tasks").body()

suspend fun Meilisearch.getTask(taskUid: String) = this.client.get<TaskResponse>("/tasks/$taskUid")
suspend fun Meilisearch.getTask(taskUid: String): TaskResponse = this.client.get("/tasks/$taskUid").body()

suspend fun Meilisearch.listTasksByIndex(indexUid: String) =
this.client.get<List<TaskResponse>>("/indexes/$indexUid/tasks")
suspend fun Meilisearch.listTasksByIndex(indexUid: String): List<TaskResponse> =
this.client.get("/indexes/$indexUid/tasks").body()

suspend fun Meilisearch.getTaskByIndex(indexUid: String, taskUid: String) =
this.client.get<TaskResponse>("/indexes/$indexUid/tasks/$taskUid")
suspend fun Meilisearch.getTaskByIndex(indexUid: String, taskUid: String): TaskResponse =
this.client.get("/indexes/$indexUid/tasks/$taskUid").body()

suspend fun Meilisearch.waitForTask(taskUid: String) = waitForTask(taskUid, 5000, 50)

Expand Down
29 changes: 14 additions & 15 deletions src/main/kotlin/sh/nemo/meilisearch/http/HttpClient.kt
Original file line number Diff line number Diff line change
@@ -1,27 +1,26 @@
package sh.nemo.meilisearch.http

import io.ktor.client.HttpClient
import io.ktor.client.call.receive
import io.ktor.client.features.ClientRequestException
import io.ktor.client.features.HttpResponseValidator
import io.ktor.client.features.defaultRequest
import io.ktor.client.features.json.JsonFeature
import io.ktor.client.features.json.serializer.KotlinxSerializer
import io.ktor.client.features.logging.Logging
import io.ktor.client.call.body
import io.ktor.client.plugins.ClientRequestException
import io.ktor.client.plugins.HttpResponseValidator
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
import io.ktor.client.plugins.defaultRequest
import io.ktor.client.plugins.logging.Logging
import io.ktor.client.request.header
import io.ktor.client.request.host
import io.ktor.client.request.port
import io.ktor.http.ContentType
import io.ktor.http.HttpHeaders
import io.ktor.http.HttpStatusCode
import kotlinx.serialization.json.Json
import io.ktor.serialization.kotlinx.json.json
import sh.nemo.meilisearch.Meilisearch
import sh.nemo.meilisearch.exceptions.ResourceNotFound
import sh.nemo.meilisearch.responses.ErrorResponse

internal fun httpClient(config: Meilisearch.MeilisearchClientConfig) = HttpClient {
install(JsonFeature) {
serializer = KotlinxSerializer(config.json)
expectSuccess = true

install(ContentNegotiation) {
json(config.json)
}

install(Logging)
Expand All @@ -34,9 +33,9 @@ internal fun httpClient(config: Meilisearch.MeilisearchClientConfig) = HttpClien
}

HttpResponseValidator {
handleResponseException { exception ->
if (exception !is ClientRequestException) return@handleResponseException
val error = exception.response.receive<ErrorResponse>()
handleResponseExceptionWithRequest { exception, _ ->
if (exception !is ClientRequestException) return@handleResponseExceptionWithRequest
val error = exception.response.body<ErrorResponse>()
when (exception.response.status) {
HttpStatusCode.NotFound -> throw ResourceNotFound(error.message)
}
Expand Down