GithubHelp home page GithubHelp logo

algolia / algoliasearch-client-kotlin Goto Github PK

View Code? Open in Web Editor NEW
59.0 57.0 23.0 5.09 MB

⚡️ A fully-featured and blazing-fast Kotlin/Android API client to interact with Algolia.

Home Page: https://www.algolia.com/doc/api-client/getting-started/install/kotlin/

License: MIT License

Kotlin 99.99% Dockerfile 0.01%
algolia kotlin search-engine algolia-api api-client coroutines

algoliasearch-client-kotlin's Introduction

Algolia for Kotlin

The perfect starting point to integrate Algolia within your Kotlin project

Latest version Licence

DocumentationCommunity ForumStack OverflowReport a bugFAQSupport

✨ Features

  • The Kotlin client is compatible with Kotlin 1.6 and higher.
  • It is compatible with Kotlin project on the JVM, such as backend and Android applications.
  • It relies on the open source Kotlin libraries for seamless integration into Kotlin projects:
  • The Kotlin client integrates the actual Algolia documentation in each source file: Request parameters, response fields, methods and concepts; all are documented and link to the corresponding url of the Algolia doc website.
  • The client is thread-safe. You can use SearchClient, AnalyticsClient, and InsightsClient in a multithreaded environment.

💡 Getting Started

Install the Kotlin client by adding the following dependency to your gradle.build file:

repositories {
   mavenCentral()
}

dependencies {
   implementation "com.algolia:algoliasearch-client-kotlin:$kotlin_client_version"
}

Also, choose and add to your dependencies one of Ktor http client engines. Alternatively, you can use algoliasearch-client-kotlin-bom.
For full documentation, visit the Algolia Kotlin API Client.

ℹ️ Please follow the migration guide to migrate from 1.x to the latest version.

Coroutines

All methods performing HTTP calls in the Kotlin client are suspending functions. This means these functions can only be called from a coroutine.

In the example below, a coroutine is launched in the main thread. The context is switched to a thread pool to perform the search HTTP call off the main thread. The response can be manipulated from the main thread.

class Searcher : CoroutineScope {

    override val coroutineContext = Job()

    fun search() {
        launch(Dispatchers.Main) {
            val response = withContext(Dispatchers.Default) { index.search() }
        }
    }
}

The developer is responsible for implementing the asynchronous logic that matches their specific requirements. The Kotlin client doesn't execute HTTP calls on any particular thread, it is up to the developer to define it explicitly using coroutines. Learn more about coroutines.

Waiting for operations

Waiting for an asynchronous server task is made available via a function literal with receiver.

Use the apply or run functions on your index or client.

index.apply {
    setSettings(Settings()).wait()
}
client.run {
    multipleBatchObjects(listOf<BatchOperationIndex>()).waitAll()
}

The wait functions are suspending, and should only be called from a coroutine.

Type safety

Response and parameters objects are typed to provide extensive compile time safety coverage.

Example for creating a Client instance without mixing the application ID and the API key.

val appID = ApplicationID("YourApplicationID")
val apiKey = APIKey("YourAdminAPIKey")

val client = ClientSearch(appID, apiKey)

Example for attributes:

val color = Attribute("color")
val category = Attribute("category")

Query(
  attributesToRetrieve = listOf(color, category)
)

Sealed class are used to represent enumerated types. It allows to quickly discover possible values for each type thanks to IDE autocomplete support. All sealed class have an Other class case for avoiding runtime crashes in case of unforeseen value.

val query = Query()

query.sortFacetsBy = SortFacetsBy.Count
// query.sortFacetsBy = SortFacetsBy.Alpha
// query.sortFacetsBy = SortFacetsBy.Other("unforeseen value")

R8 / Proguard rules

If you use this library in an Android project which uses R8, there is nothing you have to do. The specific rules are already bundled into the JAR, which can be interpreted by R8 automatically.

If however, you don’t use R8 you have to apply the rules from this file.

Guides

❓ Troubleshooting

Encountering an issue? Before reaching out to support, we recommend heading to our FAQ where you will find answers for the most common issues and gotchas with the client.

Use the Dockerfile

If you want to contribute to this project without installing all its dependencies, you can use our Docker image. Please check our dedicated guide to learn more.

📄 License

Algolia Kotlin API Client is an open-sourced software licensed under the MIT license.

algoliasearch-client-kotlin's People

Contributors

aallam avatar anderstechno avatar ant-hem avatar aseure avatar b95505017 avatar benoitperrot avatar dependabot[bot] avatar fluf22 avatar maxv148 avatar plnech avatar q-litzler avatar renovate[bot] avatar robertmogos avatar sarahdayan avatar spinach avatar tyrwzl avatar vladislavfitz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

algoliasearch-client-kotlin's Issues

feat(settings): customNormalization

Please add the following parameter to indexSettings and the related CTS test.

Schema modification in indexSettings

"customNormalization" : map<string, map<string,string>>

Example:

 "customNormalization": { "default": {"ä": "ae", "ü": "ue"} }

feat(query_rules): filterPromotes parameter

Please add the filterPromotes parameter to the QR Schema.

Query Rule schema
 {
    "objectID": ...,
    "condition": {...},
    "consequence": {
        "promote": [...],
+        "filterPromotes": true|false,
     }
 }

Validation
The new field is optional, and must be a Boolean if provided.

test: old indices are not removed from our testing application

While investigating old indices not being removed from our testing application, I've discovered two issues with the testing indices of the client:

  1. nit: the date format is wrong (2019-06-05-17-46-49 instead of 2019-06-05_17-46-49)
  2. the old indices seem to be still present

Here is a list of the indices I found out today for instance (I've already removed them to clean our application a bit)

kotlin-2019-03-28-16-54-50-quentinlitzler-snippet
kotlin-2019-03-28-16-54-50-quentinlitzler-snippet_copy
kotlin-2019-03-28-16-55-01-quentinlitzler-snippet
kotlin-2019-03-28-16-55-01-quentinlitzler-snippet_copy
kotlin-2019-03-28-16-55-40-quentinlitzler-snippet
kotlin-2019-03-28-16-55-40-quentinlitzler-snippet_copy
kotlin-2019-03-28-16-55-53-quentinlitzler-snippet
kotlin-2019-03-28-16-55-53-quentinlitzler-snippet_copy
kotlin-2019-03-28-16-57-11-quentinlitzler-snippet
kotlin-2019-03-28-16-57-11-quentinlitzler-snippet_copy
kotlin-2019-03-28-16-57-25-quentinlitzler-snippet
kotlin-2019-03-28-16-57-25-quentinlitzler-snippet_copy
kotlin-2019-03-28-17-00-01-quentinlitzler-snippet
kotlin-2019-03-28-17-00-01-quentinlitzler-snippet_copy
kotlin-2019-03-28-17-00-12-quentinlitzler-snippet
kotlin-2019-03-28-17-00-12-quentinlitzler-snippet_copy
kotlin-2019-03-28-17-11-56-quentinlitzler-snippet
kotlin-2019-03-28-17-11-56-quentinlitzler-snippet_copy
kotlin-2019-03-28-17-12-10-quentinlitzler-snippet
kotlin-2019-03-28-17-12-10-quentinlitzler-snippet_copy
kotlin-2019-03-29-15-58-53-quentinlitzler-snippet
kotlin-2019-03-29-15-59-37-quentinlitzler-snippet
kotlin-2019-03-29-15-59-59-quentinlitzler-snippet
kotlin-2019-03-29-16-01-31-quentinlitzler-snippet
kotlin-2019-03-29-16-02-25-quentinlitzler-snippet
kotlin-2019-03-29-16-04-56-quentinlitzler-snippet
kotlin-2019-03-29-16-05-33-quentinlitzler-snippet
kotlin-2019-03-29-16-06-14-quentinlitzler-snippet
kotlin-2019-03-29-16-11-26-quentinlitzler-snippet
kotlin-2019-03-29-16-11-35-quentinlitzler-snippet
kotlin-2019-03-29-16-18-18-quentinlitzler-snippet
kotlin-2019-03-29-16-31-00-quentinlitzler-snippet
kotlin-2019-03-29-16-33-36-quentinlitzler-snippet
kotlin-2019-03-29-17-00-14-quentinlitzler-snippet
kotlin-2019-03-29-17-46-23-quentinlitzler-snippet
kotlin-2019-03-29-17-46-38-quentinlitzler-snippet
kotlin-2019-03-29-17-48-24-quentinlitzler-snippet
kotlin-2019-04-01-16-28-46-quentinlitzler-snippet
kotlin-2019-04-01-16-29-25-quentinlitzler-snippet
kotlin-2019-04-01-16-29-25-quentinlitzler-snippet_copy
kotlin-2019-04-01-16-29-34-quentinlitzler-snippet
kotlin-2019-04-01-16-29-34-quentinlitzler-snippet_copy
kotlin-2019-04-01-16-29-58-quentinlitzler-snippet
kotlin-2019-04-01-16-29-59-quentinlitzler-snippet
kotlin-2019-04-01-16-30-00-quentinlitzler-snippet
kotlin-2019-04-01-16-30-01-quentinlitzler-snippet
kotlin-2019-04-01-16-30-02-quentinlitzler-snippet
kotlin-2019-04-01-16-30-02-quentinlitzler-snippet_copy
kotlin-2019-04-01-16-30-03-quentinlitzler-snippet
kotlin-2019-04-01-16-30-04-quentinlitzler-snippet
kotlin-2019-04-01-16-30-05-quentinlitzler-snippet
kotlin-2019-04-01-16-30-09-quentinlitzler-snippet
kotlin-2019-04-01-16-30-10-quentinlitzler-snippet
kotlin-2019-04-01-16-30-11-quentinlitzler-snippet
kotlin-2019-04-01-16-30-12-quentinlitzler-snippet
kotlin-2019-04-01-16-30-13-quentinlitzler-snippet
kotlin-2019-04-01-16-30-18-quentinlitzler-snippet
kotlin-2019-04-01-16-30-19-quentinlitzler-snippet
kotlin-2019-04-01-16-30-28-quentinlitzler-snippet
kotlin-2019-04-01-16-30-30-quentinlitzler-snippet
kotlin-2019-04-01-16-30-32-quentinlitzler-snippet
kotlin-2019-04-01-16-30-34-quentinlitzler-snippet
kotlin-2019-04-01-16-30-35-quentinlitzler-snippet
kotlin-2019-04-01-16-30-38-quentinlitzler-snippet
kotlin-2019-04-01-16-30-39-quentinlitzler-snippet
kotlin-2019-04-01-16-30-41-quentinlitzler-snippet
kotlin-2019-04-01-16-30-43-quentinlitzler-snippet
kotlin-2019-04-01-16-30-44-quentinlitzler-snippet
kotlin-2019-04-01-16-30-45-quentinlitzler-snippet
kotlin-2019-04-01-16-30-46-quentinlitzler-snippet
kotlin-2019-04-01-16-30-47-quentinlitzler-snippet
kotlin-2019-04-01-16-30-48-quentinlitzler-snippet
kotlin-2019-04-01-16-30-50-quentinlitzler-snippet
kotlin-2019-04-01-16-30-52-quentinlitzler-snippet
kotlin-2019-04-01-16-30-54-quentinlitzler-snippet
kotlin-2019-04-01-16-30-55-quentinlitzler-snippet
kotlin-2019-04-01-16-30-57-quentinlitzler-snippet
kotlin-2019-04-01-16-30-59-quentinlitzler-snippet
kotlin-2019-04-01-16-31-00-quentinlitzler-snippet
kotlin-2019-04-01-16-31-02-quentinlitzler-snippet
kotlin-2019-04-01-16-31-03-quentinlitzler-snippet
kotlin-2019-04-01-16-31-04-quentinlitzler-snippet
kotlin-2019-04-01-16-31-05-quentinlitzler-snippet
kotlin-2019-04-01-16-31-08-quentinlitzler-snippet
kotlin-2019-04-01-16-31-10-quentinlitzler-snippet
kotlin-2019-04-01-16-31-12-quentinlitzler-snippet
kotlin-2019-04-01-16-31-14-quentinlitzler-snippet
kotlin-2019-04-01-16-31-16-quentinlitzler-snippet
kotlin-2019-04-01-16-31-18-quentinlitzler-snippet
kotlin-2019-04-01-16-31-19-quentinlitzler-snippet
kotlin-2019-04-01-16-31-21-quentinlitzler-snippet
kotlin-2019-04-01-16-31-23-quentinlitzler-snippet
kotlin-2019-04-01-16-31-24-quentinlitzler-snippet
kotlin-2019-04-01-16-31-27-quentinlitzler-snippet
kotlin-2019-04-01-16-31-28-quentinlitzler-snippet
kotlin-2019-04-01-16-31-30-quentinlitzler-snippet
kotlin-2019-04-01-16-31-32-quentinlitzler-snippet
kotlin-2019-04-01-16-31-34-quentinlitzler-snippet
kotlin-2019-04-01-16-31-35-quentinlitzler-snippet
kotlin-2019-04-01-16-31-36-quentinlitzler-snippet
kotlin-2019-04-01-16-31-37-quentinlitzler-snippet
kotlin-2019-04-01-16-31-38-quentinlitzler-snippet
kotlin-2019-04-01-16-31-39-quentinlitzler-snippet
kotlin-2019-04-01-16-31-40-quentinlitzler-snippet
kotlin-2019-04-01-16-31-41-quentinlitzler-snippet
kotlin-2019-04-01-16-31-42-quentinlitzler-snippet
kotlin-2019-04-01-16-31-43-quentinlitzler-snippet
kotlin-2019-04-01-16-31-46-quentinlitzler-snippet
kotlin-2019-04-01-16-31-48-quentinlitzler-snippet
kotlin-2019-04-01-16-31-50-quentinlitzler-snippet
kotlin-2019-04-01-16-31-52-quentinlitzler-snippet
kotlin-2019-04-01-16-31-55-quentinlitzler-snippet
kotlin-2019-04-01-16-31-57-quentinlitzler-snippet
kotlin-2019-04-01-16-31-58-quentinlitzler-snippet
kotlin-2019-04-01-16-32-00-quentinlitzler-snippet
kotlin-2019-04-01-16-32-02-quentinlitzler-snippet
kotlin-2019-04-01-16-32-03-quentinlitzler-snippet
kotlin-2019-04-01-16-32-05-quentinlitzler-snippet
kotlin-2019-04-01-16-32-07-quentinlitzler-snippet
kotlin-2019-04-01-16-32-08-quentinlitzler-snippet
kotlin-2019-04-01-16-32-09-quentinlitzler-snippet
kotlin-2019-04-01-16-32-12-quentinlitzler-snippet
kotlin-2019-04-01-16-32-17-quentinlitzler-snippet
kotlin-2019-04-01-16-32-21-quentinlitzler-snippet
kotlin-2019-04-01-17-07-38-quentinlitzler-snippet
kotlin-2019-04-02-11-06-32-benoitperrot-helper
kotlin-2019-04-02-11-06-36-benoitperrot-indexing
kotlin-2019-04-02-11-06-52-benoitperrot-secured_api_keys
kotlin-2019-04-02-11-06-52-benoitperrot-secured_api_keys_dev
kotlin-2019-04-02-11-07-05-benoitperrot-index_batching
kotlin-2019-04-02-11-07-12-benoitperrot-search
kotlin-2019-04-02-11-07-17-benoitperrot-multiple_operations
kotlin-2019-04-02-11-07-17-benoitperrot-multiple_operations_dev
kotlin-2019-04-02-11-07-20-benoitperrot-synonyms
kotlin-2019-04-02-11-07-32-benoitperrot-rules
kotlin-2019-04-02-11-07-43-benoitperrot-insights
kotlin-2019-04-02-11-08-02-benoitperrot-settings
kotlin-2019-04-02-11-08-10-benoitperrot-copy_index
kotlin-2019-04-02-11-08-17-benoitperrot-aa_testing
kotlin-2019-04-02-11-08-44-benoitperrot-ab_testing
kotlin-2019-04-02-11-08-44-benoitperrot-ab_testing_dev
kotlin-2019-04-02-11-09-06-benoitperrot-replacing
kotlin-2019-04-02-11-09-19-benoitperrot-disjunctive
kotlin-2019-04-03-14-33-12-pln-snippet
kotlin-2019-04-29-08-50-36-pln-disjunctive
kotlin-2019-04-29-08-50-44-pln-synonyms
kotlin-2019-04-29-08-50-59-pln-indexing
kotlin-2019-04-29-08-51-19-pln-rules
kotlin-2019-04-29-08-51-33-pln-index_batching
kotlin-2019-04-29-08-52-09-pln-insights
kotlin-2019-04-29-08-52-30-pln-helper
kotlin-2019-04-29-08-52-38-pln-ab_testing
kotlin-2019-04-29-08-52-38-pln-ab_testing_dev
kotlin-2019-04-29-08-53-06-pln-aa_testing
kotlin-2019-04-29-08-53-21-pln-replacing
kotlin-2019-04-29-08-53-39-pln-multiple_operations
kotlin-2019-04-29-08-53-39-pln-multiple_operations_dev
kotlin-2019-04-29-08-53-49-pln-copy_index
kotlin-2019-04-30-09-55-21-pln-secured_api_keys
kotlin-2019-04-30-09-55-21-pln-secured_api_keys_dev
kotlin-2019-04-30-09-55-38-pln-search
kotlin-2019-04-30-09-55-47-pln-settings
kotlin-2019-05-02-15-32-34-circleci-indexing
kotlin-2019-05-02-15-33-07-circleci-ab_testing
kotlin-2019-05-02-15-33-07-circleci-ab_testing_dev
kotlin-2019-05-02-15-33-31-circleci-secured_api_keys
kotlin-2019-05-02-15-33-31-circleci-secured_api_keys_dev
kotlin-2019-05-02-15-33-42-circleci-synonyms
kotlin-2019-05-02-15-34-04-circleci-search
kotlin-2019-05-02-15-34-08-circleci-index_batching
kotlin-2019-05-02-15-34-16-circleci-replacing
kotlin-2019-05-02-15-34-28-circleci-rules
kotlin-2019-05-02-15-34-41-circleci-multiple_operations
kotlin-2019-05-02-15-34-41-circleci-multiple_operations_dev
kotlin-2019-05-02-15-34-51-circleci-settings
kotlin-2019-05-02-15-35-10-circleci-insights
kotlin-2019-05-02-15-35-16-circleci-copy_index
kotlin-2019-05-02-15-35-16-circleci-copy_index_full_copy
kotlin-2019-05-02-15-35-16-circleci-copy_index_rules
kotlin-2019-05-02-15-35-16-circleci-copy_index_settings
kotlin-2019-05-02-15-35-16-circleci-copy_index_synonyms
kotlin-2019-05-02-15-35-26-circleci-aa_testing
kotlin-2019-05-02-15-35-45-circleci-disjunctive
kotlin-2019-05-02-15-36-04-circleci-helper
kotlin-2019-06-30-20-16-53-quentinlitzler-hierarchical
kotlin-2019-06-30-20-27-33-root-hierarchical
kotlin-2019-07-05-17-43-13-quentinlitzler-secured_api_keys
kotlin-2019-07-05-17-43-13-quentinlitzler-secured_api_keys_dev
kotlin-2019-07-05-17-43-22-quentinlitzler-aa_testing
kotlin-2019-07-05-17-43-31-quentinlitzler-ab_testing
kotlin-2019-07-05-17-43-31-quentinlitzler-ab_testing_dev
kotlin-2019-07-05-17-44-25-quentinlitzler-index_batching
kotlin-2019-07-05-17-44-54-quentinlitzler-helper
kotlin-2019-07-05-17-45-00-quentinlitzler-copy_index
kotlin-2019-07-05-17-45-00-quentinlitzler-copy_index_full_copy
kotlin-2019-07-05-17-45-00-quentinlitzler-copy_index_rules
kotlin-2019-07-05-17-45-00-quentinlitzler-copy_index_settings
kotlin-2019-07-05-17-45-00-quentinlitzler-copy_index_synonyms
kotlin-2019-07-05-17-45-30-quentinlitzler-disjunctive
kotlin-2019-07-05-17-45-39-quentinlitzler-indexing
kotlin-2019-07-05-17-45-58-quentinlitzler-insights
kotlin-2019-07-05-17-46-11-quentinlitzler-multiple_operations
kotlin-2019-07-05-17-46-11-quentinlitzler-multiple_operations_dev
kotlin-2019-07-05-17-46-23-quentinlitzler-replacing
kotlin-2019-07-05-17-46-36-quentinlitzler-rules
kotlin-2019-07-05-17-46-49-quentinlitzler-search
kotlin-2019-07-05-17-46-57-quentinlitzler-settings
kotlin-2019-07-05-17-47-07-quentinlitzler-synonyms
kotlin-2019-07-08-08-05-04-root-rules
kotlin-2019-07-08-08-05-20-root-indexing
kotlin-2019-07-08-08-05-36-root-settings
kotlin-2019-07-08-08-05-52-root-disjunctive
kotlin-2019-07-08-08-06-15-root-secured_api_keys
kotlin-2019-07-08-08-06-15-root-secured_api_keys_dev
kotlin-2019-07-08-08-06-29-root-aa_testing
kotlin-2019-07-08-08-06-40-root-index_batching
kotlin-2019-07-08-08-07-03-root-helper
kotlin-2019-07-08-08-07-09-root-insights
kotlin-2019-07-08-08-07-43-root-synonyms
kotlin-2019-07-08-08-07-55-root-copy_index
kotlin-2019-07-08-08-07-55-root-copy_index_full_copy
kotlin-2019-07-08-08-07-55-root-copy_index_rules
kotlin-2019-07-08-08-07-55-root-copy_index_settings
kotlin-2019-07-08-08-07-55-root-copy_index_synonyms
kotlin-2019-07-08-08-08-05-root-ab_testing
kotlin-2019-07-08-08-08-05-root-ab_testing_dev
kotlin-2019-07-08-08-08-30-root-search
kotlin-2019-07-08-08-08-37-root-replacing
kotlin-2019-07-08-08-08-48-root-multiple_operations
kotlin-2019-07-08-08-08-48-root-multiple_operations_dev

feat: add contextual rules

TL;DR: The condition field on rules is now optional.

Actions required:

  • Update the cts with the information on : #71

  • On strongly typed clients, update types in query rules, as the condition field in rules is now optional

  • Python test suite update

# feat(search): explain decompounding at query time

Please add the following modifications to both query and searchReponse objects

Addition to existing JSON schemas

Query: new optional parameter explain (or not new if Query Rules v2 was already implemented)

{
  "explain": string[]?
}

SearchResponse: new explain response field (or not new if Query Rules v2 was already implemented)

        "explain": {
            "match": {
                "alternatives": [
                    {
                        "type": string,
                        "words": string[],
                        "typos": int,
                        "offset": int,
                        "length": int
                    }
                 ]
            }
         }

Handle `autoGenerateObjectIDIfNotExist` parameter for `replaceAllObjects()` method

The autoGenerateObjectIDIfNotExist boolean parameter is for now only valid in
the context of the saveObjects() method. As pointed out by @julienpa, it would
make sense to also accepts it as a valid parameter of replaceAllObjects().

For backward-compatiblity, let's make sure the default behavior of calling
replaceAllObjects() without the autoGenerateObjectIDIfNotExist parameter is
still considered as if it was set to false.

Add Android target

Simple Android apps can currently import and use the jvm version of the library, but in a multiplatform context, it's easier to just import the "root" library and let the multiplatform plugin use the gradle metadata to import all needed target.

During this process, the plugin will look for android and/or android-debug targets, and not jvm. That's why android releases are required.

New method: GetSecuredApiKeyRemainingValidity

Summary

When a secured API keys expire, search breaks. The current workaround is more complex
than it needs to be.

The options for developers using Algolia require, at every place where a search
operation is performed, catching an operation error, identify it as a
"ValidUntil" error, then regenerate the API key, and perform the search
operation again.

The idea is to define a method which tells if a SecuredAPIKey
is expired or not without making a single call to Algolia's API.

References

feat(API): introducing the Recommendation client

Context

The personalization strategy endpoint will migrate from the Search API to the Recommendation API.

The consequences of the breaking changes are:

  • In search_client both methods get_personalization_strategy and set_personalization_strategy must be deprecated.
  • API Clients have to introduce a new recommendation client.

Recommendation client implementation

Endpoint

https://recommendation.{region}.algolia.com where region can be us or eu.

Please note that as for the current analytics_client the region should be
settable when instantiating the client.

Route

The route will be /1/strategies/personalization and support the following HTTP methods GET, POST, OPTIONS.

  • get_personalization_strategy -> GET : /1/strategies/personalization
  • set_personalization_strategy -> POST : /1/strategies/personalization

recommendation_client interface

interface recommendation_client {

    function get_personalization_strategy(opts: request_options)
    return get_strategy_response

    function set_personalization_strategy(set_strategy_request: strategy, opts: request_options)
    return set_strategy_response
}

Objects

struct set_strategy_request {
    eventsScoring: events_scoring[]
    facetsScoring: facets_scoring[]
    personalizationImpact: int
}
struct events_scoring {
    eventName: string
    eventType: string
    score: int
}
struct facets_scoring {
    facetName: string
    score: int
}

Responses

struct get_strategy_response {
    eventsScoring: events_scoring[]
    facetsScoring: facets_scoring[]
    personalizationImpact: int
}
struct set_strategy_response {
    status: int
    message: string
}

For more details regarding the implementation please see the specfication PR.

Documentatioin

Current

No documentation about how to setup a new client

I just see put "this on gradle"

   implementation "io.ktor:ktor-client-android:$ktor_version"

Expected

Some kind of text explaining that like:

"You just need to put this gradle depe ndency and the library will configure automatically to use the client"

Also what is the ktor version I should use?

feat: add enableABTest as SearchParameter

Summary

Add the enableABTest query-time only parameter. Defaults to true so that A/B tests are applied by default. Can be set to false to disable A/B tests at query time.

"enableABTest" : true

feat(mcm): new method has_pending_mapping

Please add the following method to search_client

function has_pending_mappings(retrieve_mappings: boolean = false, opts: request_options) 
return has_pending_mappings_response

struct has_pending_mappings_response {
	pending: boolean,
	clusters: map<string, string[]>
}
{
  "method": "GET",
  "url": "/1/clusters/mapping/pending?getClusters={retrieve_mappings}",
  "hostType": "read"
}

Naming of Facet/Filter classes

I find the current naming of the Facet class confusing. Trying to understand why it exposes a highlighted value, I realized that it only happens when doing a SearchForFacetValues: when returned in a normal search response, the field facets can only hold "A mapping of each facet name to the corresponding facet counts."

With that in mind, I propose we rename Facet to FacetValue to clarify what it is: a mapping of a facet name to a count, eventually highlighted.

Likewise, it's a bit weird to talk about FilterFacet or FilterTag when our docs describe Facet Filters, Tag Filters, etc: I propose we use the same names and rename FilterFacet -> FacetFilter, RangeValue-> NumericRange, FilterTag-> TagFilter

Add -> similarQuery as SearchParameters

Allows a search for similar objects, but the query has to be constructed on your end and included alongside an empty query. The similarQuery should be made from the tags and keywords of the relevant object.

similarQuery is a String and a SearchParameters.

API Feature - Implement GZIP for POST/PUT

The engine is introducing a new feature allowing to optionally compress request
payloads (ie. POST/PUT body, http or https).

To test it:

Perform a saveObject with the content encoded with GZIP
Don't forget to add: "Content-Encoding: gzip" as a header.

We will discuss a specification for a more detailed implementation.
Like adding a enableGZIP flag in client's configuration.

No virtual method getResponsePipeline()

Getting the following runtime error:

java.lang.NoSuchMethodError: No virtual method getResponsePipeline()Lio/ktor/client/response/HttpResponsePipeline; in class Lio/ktor/client/HttpClient

using the following gradle setup

implementation "com.algolia:algoliasearch-client-kotlin-jvm:1.2.1"
implementation "io.ktor:ktor-client-okhttp:1.3.0"

and declaring like this

ClientSearch(
	ConfigurationSearch(
		applicationID = appID,
		apiKey = apiKey,
		engine = OkHttp.create {
		}
	)
)

Thanks for any help :)

feat: add method assignUserIDs

TL;DR: Add method MCM related method -> assignUserIDs and update the CTS accordingly.

Actions required:

  1. Add method SearchClient::assignUserIDs just like is specified here:

Signature:
function assign_user_ids(userIDs: []string, clusterName: string, opts: request_options) return created_response

The created_response is the same as assign_user_id.

Request:

{
  "method": "POST",
  "url": "/1/clusters/mapping/batch",
  "hostType": "write",
  "body": {
    "cluster": cluster,
    "users": userIDs
  }
}
  1. Update the CTS as specified here: https://github.com/algolia/algoliasearch-client-specs-internal/pull/75/files.

Full details: https://github.com/algolia/algoliasearch-client-specs-internal/issues/69.

Add support for iOS

Hi,

We at Wizbii have been using a custom client implementing the Algolia REST API in a multiplatform context for some time now. It "supports" the JVM, Android and iOS, but is very barebone and lacks most Algolia features. We implemented the bare minimum we needed.

We would like to migrate to the official Kotlin client, but for that we need it to support the different iOS platforms (arm64 and x86_64, arm32 would probably be nice too).

Here are two Gists demonstrating iOS build in multiplatform: https://gist.github.com/Ribesg/95a172ceb2177d74cf5b15993d40092e

Thanks

Check automaticRadius type in search response is string

A user of the Go client reported
on support that they had issue while the Go client was deserializing the
automaticRadius field of a geo search query.

The Algolia documentation says
the type of automaticRadius is a string but, as of today, the written type
annotation is marked to float.

Let's make sure that this field is correctly typed as a string (and not a
float), as it should.

For the record, to make automaticRadius in a search response, you need to
perform a search query with:

  • with a geo parameter such as aroundLatLng
  • without any aroundRadius search parameter
  • have records in your index that will match the geo query, so they need to
    have a _geoloc attribute

Make ClientDate constructor internal

ClientDate doesn't throw an exception in else case, to avoid crashing in case of malformed date format.

Making the constructor internal would make it more consistent with this design, to avoid external use.

Received bad status code: 403 Forbidden. Expected status code < 300.

When using IS-kotlin within sample, using an API Key that doesn't have ACL for the given indexName, we get this error:

Stacktrace
03-13 15:21:09.929 23665-23685/com.algolia.instantsearch.android.sample E/AndroidRuntime: FATAL EXCEPTION: DefaultDispatcher-worker-3
    Process: com.algolia.instantsearch.android.sample, PID: 23665
    io.ktor.client.features.BadResponseStatusException: Received bad status code: 403 Forbidden. Expected status code < 300.
        at io.ktor.client.features.ExpectSuccess$Companion$install$1.invokeSuspend(ExpectSuccess.kt:22)
        at io.ktor.client.features.ExpectSuccess$Companion$install$1.invoke(Unknown Source:14)
        at io.ktor.util.pipeline.SuspendFunctionGun.loop(PipelineContext.kt:278)
        at io.ktor.util.pipeline.SuspendFunctionGun.access$loop(PipelineContext.kt:63)
        at io.ktor.util.pipeline.SuspendFunctionGun.proceed(PipelineContext.kt:137)
        at io.ktor.util.pipeline.SuspendFunctionGun.execute(PipelineContext.kt:157)
        at io.ktor.util.pipeline.Pipeline.execute(Pipeline.kt:23)
        at io.ktor.client.call.HttpClientCall.receive(HttpClientCall.kt:55)
        at com.algolia.search.endpoint.EndpointSearchImpl$search$2.invokeSuspend(EndpointSearchImpl.kt:161)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:32)
        at io.ktor.util.pipeline.SuspendFunctionGun.resumeRootWith(PipelineContext.kt:211)
        at io.ktor.util.pipeline.SuspendFunctionGun.loop(PipelineContext.kt:168)
        at io.ktor.util.pipeline.SuspendFunctionGun.access$loop(PipelineContext.kt:63)
        at io.ktor.util.pipeline.SuspendFunctionGun$continuation$1.resumeWith(PipelineContext.kt:118)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:45)
        at io.ktor.util.pipeline.SuspendFunctionGun.resumeRootWith(PipelineContext.kt:211)
        at io.ktor.util.pipeline.SuspendFunctionGun.loop(PipelineContext.kt:168)
        at io.ktor.util.pipeline.SuspendFunctionGun.access$loop(PipelineContext.kt:63)
        at io.ktor.util.pipeline.SuspendFunctionGun$continuation$1.resumeWith(PipelineContext.kt:118)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:45)
        at io.ktor.util.pipeline.SuspendFunctionGun.resumeRootWith(PipelineContext.kt:211)
        at io.ktor.util.pipeline.SuspendFunctionGun.loop(PipelineContext.kt:168)
        at io.ktor.util.pipeline.SuspendFunctionGun.access$loop(PipelineContext.kt:63)
        at io.ktor.util.pipeline.SuspendFunctionGun$continuation$1.resumeWith(PipelineContext.kt:118)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:45)
        at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:233)
        at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:594)
        at kotlinx.coroutines.scheduling.CoroutineScheduler.access$runSafely(CoroutineScheduler.kt:60)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:742)
03-13 15:21:10.772 23665-23687/com.algolia.instantsearch.android.sample D/EGL_emulation: eglMakeCurrent: 0xe9085420: ver 2 0 (tinfo 0xe9083490)

Scrolling the Logcat, the logs of the client contain a clearer message passed from the API:

03-13 15:21:09.852 23665-23698/com.algolia.instantsearch.android.sample I/System.out: HttpClient: RESPONSE: 403 Forbidden
03-13 15:21:09.853 23665-23698/com.algolia.instantsearch.android.sample I/System.out: HttpClient: METHOD: HttpMethod(value=POST)
03-13 15:21:09.865 23665-23698/com.algolia.instantsearch.android.sample I/System.out: HttpClient: FROM: https://latency-dsn.algolia.net/1/indexes/test/query
03-13 15:21:09.868 23665-23698/com.algolia.instantsearch.android.sample I/System.out: HttpClient: HEADERS
03-13 15:21:09.870 23665-23698/com.algolia.instantsearch.android.sample I/System.out: HttpClient: -> access-control-allow-origin: *
    HttpClient: -> cache-control: no-cache
03-13 15:21:09.871 23665-23698/com.algolia.instantsearch.android.sample I/System.out: HttpClient: -> connection: keep-alive
    HttpClient: -> content-disposition: inline; filename=a.txt
03-13 15:21:09.877 23665-23698/com.algolia.instantsearch.android.sample I/System.out: HttpClient: -> content-length: 62
    HttpClient: -> content-type: application/json; charset=UTF-8
    HttpClient: -> date: Wed, 13 Mar 2019 14:21:10 GMT
    HttpClient: -> server: nginx
    HttpClient: -> timing-allow-origin: *
03-13 15:21:09.878 23665-23698/com.algolia.instantsearch.android.sample I/System.out: HttpClient: -> x-content-type-options: nosniff
03-13 15:21:09.885 23665-23698/com.algolia.instantsearch.android.sample I/System.out: HttpClient: BODY Content-Type: application/json; charset=UTF-8
    HttpClient: BODY START
03-13 15:21:09.893 23665-23698/com.algolia.instantsearch.android.sample I/System.out: HttpClient: {"message":"Index not allowed with this API key","status":403}
03-13 15:21:09.894 23665-23698/com.algolia.instantsearch.android.sample I/System.out: HttpClient: BODY END

Can we surface the error's message to the end-user, instead of the cryptic Expected status code < 300? 🙂

Some `add` methods actually do `put`

Some methods, like on the FilterState, are called add but would replace an existing object. Let's rename them to put to be semantically correct :)

New Query Rule parameter

Summary

A new field can be used in the condition part of a Query Rule. It's called
alternatives and currently it's a boolean. However, this parameter may
transform into JSON object in the future, as documented in the specifications,
which means that if the API client is statically-typed, please encapsulate the
boolean value into a new Alternatives structure or class with custom
serializer/deserializer to make this change non-breaking when we will have to
implement it. The Go implementation linked bellow is providing such a structure
for instance.

To test this parameter, simply pass the alternatives=true into the
query_edits rule of the integration test of the CTS, if implemented, as
written in the CTS PR or add it to any query rule in your integration test
otherwise.

References

Expose Raw for usage in IS

I'd like to type Variant to IS's connectSearcherMultiQuery:

fun RefinementModel<Facet>.connectSearcherMultiQuery(
    searcher: SearcherMultiQuery,
    attribute: Attribute,
    variant: Variant = Variant(attribute.raw)
) { ...}

We can do it either by exposing Raw here, to be used in the dependent package; or by duplicating/reimplementing the Raw logic in IS.
Considering the risk of abuse is insignificant, I'd rather do the former.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.