https://github.com/kingg22/deezer-client-kt
Unofficial Kotlin Multiplatform client for Deezer public API
https://github.com/kingg22/deezer-client-kt
api-client deezer deezer-api java kotlin kotlin-multiplatform
Last synced: 3 months ago
JSON representation
Unofficial Kotlin Multiplatform client for Deezer public API
- Host: GitHub
- URL: https://github.com/kingg22/deezer-client-kt
- Owner: kingg22
- License: agpl-3.0
- Created: 2025-07-27T20:53:10.000Z (10 months ago)
- Default Branch: main
- Last Pushed: 2026-02-27T22:36:55.000Z (3 months ago)
- Last Synced: 2026-02-28T03:38:36.043Z (3 months ago)
- Topics: api-client, deezer, deezer-api, java, kotlin, kotlin-multiplatform
- Language: Kotlin
- Homepage: https://kingg22.github.io/deezer-client-kt/
- Size: 964 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- License: LICENSE.txt
Awesome Lists containing this project
README
# 🎧 Unofficial Deezer Client KMP
[](https://www.jetbrains.com/kotlin-multiplatform/)
[](https://ktor.io/)
[](https://github.com/kingg22/ktorgen)
[](https://mvnrepository.com/artifact/io.github.kingg22/deezer-client-kt)
[](https://mvnrepository.com/artifact/io.github.kingg22/deezer-client-kt)
[](https://github.com/kingg22/deezer-client-kt/blob/main/LICENSE.txt)
[](https://github.com/kingg22/deezer-client-kt/commits/main/)
A Kotlin Multiplatform client for Deezer’s official REST API.
Using [Ktor Client](https://ktor.io/).
Supports Android (min SDK 24 / JVM 8+), JVM Java, Kotlin/JVM, Kotlin/JS, Kotlin/WasmJs.
> [!TIP]
>
> It's recommended to configure [Content Encoding](https://ktor.io/docs/client-content-encoding.html)
> to reduce the size of the response.
>
> If you consume a lot of images, consider using [Caching](https://ktor.io/docs/client-caching.html)
## 🛠️ Instalación
- Android **minSdk Version 24**
- JVM target **Java 8+** / Kotlin JVM 1.8
[](https://mvnrepository.com/artifact/io.github.kingg22/deezer-client-kt)
**Gradle**
```kotlin
// common main
implementation("io.github.kingg22:deezer-client-kt:")
```
**Maven**
```xml
io.github.kingg22
deezer-client-kt-jvm
current-version
```
**Install a Ktor client engine**, [see detail](https://ktor.io/docs/client-engines.html).
[](https://mvnrepository.com/artifact/io.ktor/ktor-client-core)
Example with CIO (Coroutines based):
Gradle
```kotlin
implementation("io.ktor:ktor-client-cio:$ktor_version")
```
Maven
```xml
io.ktor
ktor-client-cio-jvm
${ktor_version}
```
## 🧪 Usage
- ✅ Kotlin
```kotlin
val httpClient = HttpClient {
install(DeezerClientPlugin)
// Others configuration
}
val client = DeezerApiClient(httpClient)
val artist: Artist = client.artists.getById(27) // suspend fun
println("Artist: ${artist.name}") // Artist: Daft Punk
```
- ⚠️ Java (Blocking)
```java
public class Test {
static void main(String[] args) {
final HttpClient httpClient = HttpClientKt.HttpClient(CIO.INSTANCE.create(unused -> null), builder -> {
builder.install(DeezerClientPlugin.INSTANCE, unused -> null);
// Other configuration
return null;
});
final var client = new DeezerApiJavaClient(httpClient);
final Artist artist = client.artists.getById(27);
System.out.println("Artist: " + artist.getName()); // Artist: Daft Punk
}
}
```
- ✅ Java (CompletableFuture)
```java
import java.util.concurrent.CompletableFuture;
public class Test {
static void main(String[] args) {
final HttpClient httpClient = HttpClientKt.HttpClient(CIO.INSTANCE.create(unused -> null), builder -> {
builder.install(DeezerClientPlugin.INSTANCE, unused -> null);
// Other configuration
return null;
});
final var client = new DeezerApiJavaClient(httpClient);
final CompletableFuture future = client.artists.getByIdFuture(27);
future.whenComplete((artist, err) -> {
if (err != null) err.printStackTrace();
else System.out.println("Artist: " + artist.getName()); // Artist: Daft Punk
});
}
}
```
#### Paginated Response
**Kotlin**
```kotlin
val client: DeezerApiClient // use the same client in the app
val result: PaginatedResponse = client.searches.search("eminem")
checkNotNull(result.next)
val nextPage: PaginatedResponse = checkNotNull(tested.fetchNext(client, expand=true))
// because the next is not null, fetchNext don't return null
// expand means the previous data (List) going to expand with the new response
// fetchNext is an extension function*
```
**Java**
```java
import java.util.concurrent.CompletableFuture;
public class Test {
static void main(String[] args) {
final DeezerApiJavaClient client; // use the same client in the app
final PaginatedResponse response = client.searches.search("eminem");
// Blocking
final PaginatedResponse nextPage = response.fetchNext(client, Track.class, /* expand */ true);
// async
final CompletableFuture> nextPageFuture =
response.fetchNextFuture(client, Track.class, /* expand */ true);
// Null type is the same, but in java isn't a mandatory check, is recommended!
}
}
```
#### Reloading resources
**Kotlin**
```kotlin
val client: DeezerApiClient // use the same client in the app
val episode: Episode = client.episodes.getById(526673645) // suspend fun
// after do things ...
val freshEpisode: Episode = episode.reload(client) // suspend fun
```
**Java** (_Needs explicit cast, because of abstract Resource_)
```java
import java.util.concurrent.CompletableFuture;
class Test {
static void main(String[] args) {
final DeezerApiJavaClient client = "";// use the same client in the app
final Episode episode = client.episodes.getById(526673645);
final Episode freshEpisode = (Episode) episode.reload(client); // blocking
final CompletableFuture freshEpisodeFuture =
(CompletableFuture) episode.reloadFuture(client); // async
}
}
```
#### Advanced search
**Kotlin**
```kotlin
import io.github.kingg22.deezer.client.api.objects.SearchOrder
import io.github.kingg22.deezer.client.api.routes.SearchRoutes.Companion.buildAdvancedQuery
import io.github.kingg22.deezer.client.api.routes.SearchRoutes.Companion.setStrict
import kotlin.time.Duration.Companion.minutes
val client: DeezerApiClient // use the same client in the app
val query = buildAdvancedQuery { // DSL builder
artist = "eminem"
durationMin = 1.minutes
}
client.searches.searchPlaylist(query, strict = setString(true))
client.searches.searchTrack(
q = buildAdvancedQuery(q = "Not Afraid", artist = "eminem"), // function
order = SearchOrder.RANKING,
limit = 15,
index = 10,
)
```
**Java**
```java
import static io.github.kingg22.deezer.client.api.routes.SearchRoutes.buildAdvancedQuery;
import static io.github.kingg22.deezer.client.api.routes.SearchRoutes.setStrict;
public class Test {
static void main(String[] args) {
final DeezerApiJavaClient client = "";// use the same client in the app
client.searches.searchAlbum(
/* q =*/ buildAdvancedQuery(/* q = */ "King") // Only access to Java builder style
.artist("eminem")
.build(),
/* strict = */ setStrict(true),
/* order = */ SearchOrder.RATING_DESC,
/* index = */ 10,
/* limit = */ 15
);
}
}
```
**_Why not data class?_**
[Read more about this here](https://kotlinlang.org/docs/api-guidelines-backward-compatibility.html#avoid-using-data-classes-in-your-api).
I take the decision to use class with [Poko](https://github.com/drewhamilton/Poko) because immutability is guaranteed and equals are generated.
The idea of this api client is stateless, fetch what u need, and that's it.
### 🆚 Differences between kotlin and java versions
- Kotlin can't access to the java version and viceversa
- ~~Kotlin extensions vs. an external object with static methods (helpers / utility class)~~
- Java can't access some kotlin specific like DSL, reified types, suspend methods, function with kotlin duration
- Java wrappers of kotlin stuffs, so kotlin is a priority and dictates the route
- Java needs to use kotlin datetime LocalDate and LocalDateTime when get dates :/
- _Similitude_ kotlin suspend and java blocking it **reads** the same >_<
## 🛣 Roadmap
- [ ] Support authenticated endpoints (user edit, user playlist edit, etc.)
- [ ] OAuth flow and token refresh support
### ⛓️💥 Dependencies
- [ktor-client-content-negotiation-json](https://ktor.io/docs/client-serialization.html#k53369_158) with kotlinx-serialization
- [ktor-client-logging](https://ktor.io/docs/client-logging.html).
- [kotlinx-datetime](https://github.com/Kotlin/kotlinx-datetime) for java is not supported easy less,
but can use long as seconds in some cases.
- [Poko](https://github.com/drewhamilton/Poko) and [KtorGen](https://github.com/kingg22/ktorgen) in compile time.
### 📃 References
- [Deezer Developer API](https://developers.deezer.com/api/)
## 🐞 Issue Guidelines
Please include one of the following types in your issue title or description:
- Serialization error – e.g. the JSON response missing required field, non-nullable property, etc.
- Missing field in response – field present in official API but absent in models (or extra non‑official data)
- Others
Also state if the issue refers to an official Deezer change or unofficial additional field.
### 🤝 Contributions
We welcome contributions if:
- Code is written in Kotlin
- Uses the official Deezer API (no scraping or unofficial endpoints)
- Includes at least one test with a sample JSON response
Please fork, open PRs, and ensure tests pass.
## 📄 License
Licensed under AGPL-3.0 — contributions must respect [Deezer API Terms & Conditions](https://developers.deezer.com/termsofuse), including attribution and rate‑limit policies.