Skip to content

Java wrapper for the Jikan API V4 - an unofficial MyAnimeList API - with the power of Project Reactor and reactive streams. ⚡ — https://jikan.moe

License

Notifications You must be signed in to change notification settings

SandroHc/reactive-jikan

Repository files navigation

Reactive Jikan

Maven Central GitHub Workflow Codecov

A fast and fully-typed API wrapper for the Jikan API V4, with the power of Project Reactor and reactive streams.

Supported versions

API version reactive-jikan version
V3 1.1.0
V4 2.2.0

Installation

Add the following dependency to your build file.

If using Gradle (build.gradle):

dependencies {
    implementation 'net.sandrohc:reactive-jikan:2.2.0'
}

If using Maven (pom.xml):

<dependency>
    <groupId>net.sandrohc</groupId>
    <artifactId>reactive-jikan</artifactId>
    <version>2.2.0</version>
</dependency>

If you want to use development versions, see: https://jitpack.io/#net.sandrohc/reactive-jikan

Usage

The Reactive Jikan library provides all queries through the Query classes. Once the desired query is created (the QueryFactory can be used to help you navigate through all the available queries), it can be passed to the Jikan instance. Some queries have optional parameters, like the search queries; for more details, please see the javadocs for each query or refer to the official Jikan API documentation.

After the query has been configured with the desired parameters, it can be executed by calling query.execute() (or alternatively jikan.query(yourQuery)). The value returned is a reactive stream of type Mono<T> or Flux<T> depending on the query. The HTTP request is only made once the methods subscribe() or block() are called. For more information on reactive queries, please read the relevant documentation.

Here are some examples on how to use this library:

// Create the Jikan instance with default parameters.
// You can also use the builder, JikanBuilder, to specify custom parameters.
Jikan jikan = new Jikan(); 

// Fetch the anime with ID 1. Returns a single value, a mono.
Anime anime = jikan.query().anime().get(1)
        .execute()
        .block();

// Search for 'sword art online'. Returns a list of values, a flux.
Collection<Anime> results = jikan.query().anime().search()
		.query("sword art online")
		.limit(5)
		.status(AnimeStatus.AIRING)
		.orderBy(AnimeOrderBy.MEMBERS, SortOrder.ASCENDING)
		.execute()
		.collectList()
		.block();

Android

The following changes are necessary to use this library on Android.

Jikan jikan = new Jikan.JikanBuilder()
        .httpClientCustomizer(httpClient -> httpClient.resolver(DefaultAddressResolverGroup.INSTANCE))
        .build();

Caching

Caching comes disabled by default. To enable it, please provide an implementation of JikanCache to the Jikan instance.

The following is an example using Caffeine as the cache library. Beware that Caffeine is not supported in Android!

// build.gradle
dependencies {
	implementation 'com.github.ben-manes.caffeine:caffeine:2.9.3'
}

// App.java
JikanCache jikanCache = new JikanCache() {
    protected final Cache<String, JikanValueHolder> cache = Caffeine.newBuilder().maximumSize(10_000).expireAfter(new JikanExpiry()).build();

    public void put(String key, Object value, OffsetDateTime expires) {
        cache.put(key, new JikanValueHolder(value, expires));
    }

    public Optional<Object> get(String key) {
        return Optional.ofNullable(cache.getIfPresent(key)).map(holder -> holder.value);
    }

    class JikanValueHolder {
        public final Object value;
        public final long expireTime;

        public JikanValueHolder(Object value, OffsetDateTime expires) {
            this.value = value;
            this.expireTime = TimeUnit.SECONDS.toNanos(expires.toEpochSecond());
        }
    }

    class JikanExpiry implements Expiry<String, JikanValueHolder> {
        public long expireAfterCreate(String key, JikanValueHolder value, long currentTime) {
            return value.expireTime;
        }

        public long expireAfterUpdate(String key, JikanValueHolder value, long currentTime, long currentDuration) {
            return currentDuration; // Do not modify expire date
        }

        public long expireAfterRead(String key, JikanValueHolder value, long currentTime, long currentDuration) {
            return currentDuration; // Do not modify expire date
        }
    }
};

Jikan jikan = new Jikan.JikanBuilder()
        .cache(jikanCache)
        .build();

Endpoints

The following is an exhaustive list of all the endpoints and query classes supported by the Reactive Jikan library.

Endpoint Query Result
Anime
/{id} AnimeQuery Anime
/{id}/characters_staff AnimeCharactersAndStaffQuery AnimeCharactersAndStaff
/{id}/episodes/{page} AnimeEpisodesQuery AnimeEpisodes
/{id}/news AnimeNewsQuery AnimeNews
/{id}/pictures AnimePicturesQuery (list) AnimePicture
/{id}/videos AnimeVideosQuery AnimeVideos
/{id}/statistics AnimeStatisticsQuery Stats
/{id}/forum AnimeForumQuery (list) ForumTopic
/{id}/moreinfo AnimeMoreInfoQuery MoreInfo
/{id}/reviews/{page} AnimeReviewsQuery (list) Review
/{id}/recommendations AnimeRecommendationsQuery (list) Recommendation
/{id}/userupdates/{page} AnimeUserUpdatesQuery (list) UserUpdate
Manga
/{id} MangaQuery Manga
/{id}/characters MangaCharactersQuery (list) RoleSubEntity
/{id}/news MangaNewsQuery (list) NewsArticle
/{id}/pictures MangaPicturesQuery (list) Pictures
/{id}/statistics MangaStatisticsQuery Stats
/{id}/forum MangaForumQuery (list) ForumTopic
/{id}/moreinfo MangaMoreInfoQuery MoreInfo
/{id}/reviews/{page} MangaReviewsQuery (list) Review
/{id}/recommendations MangaRecommendationsQuery Recommendations
/{id}/userupdates/{page} MangaUserUpdatesQuery (list) UserUpdate
Person
/{id} PersonQuery Person
/{id}/pictures PersonPicturesQuery (list) Picture
Character
/{id} CharacterQuery Character
/{id}/pictures CharacterPicturesQuery (list) Picture
Search
/anime AnimeSearchQuery (list) AnimeSearchSub
/manga MangaSearchQuery (list) MangaSearchSub
/person PersonSearchQuery (list) PersonSearchSub
/character CharacterSearchQuery (list) CharacterSearchSub
Season
/{year}/{season} SeasonQuery (list) SeasonAnime
/archive SeasonArchiveQuery (list) SeasonArchiveYear
/later SeasonLaterQuery (list) SeasonAnime
Schedule
/{day} ScheduleQuery Schedule
Top
/anime/{page}/{subtype} AnimeTopQuery (list) AnimeTopSub
/manga/{page}/{subtype} MangaTopQuery (list) MangaTopSub
Genre
/anime/{page}/{subtype} AnimeGenreQuery (list) AnimeGenreSub
/manga/{page}/{subtype} MangaGenreQuery (list) MangaGenreSub
Producer
/{id}/{page} ProducerQuery Producer
Magazine
/{id}/{page} MagazineQuery Magazine
User
/{username} UserProfileQuery UserProfile
/{username}/history (not implemented)
/{username}/history/anime UserHistoryAnimeQuery (list) UserHistory
/{username}/history/manga UserHistoryAnimeQuery (list) UserHistory
/{username}/friends/{page} UserFriendsQuery (list) UserFriend
/{username}/animelist/{status} UserAnimeQuery (list) UserAnime
/{username}/mangalist/{status} UserMangaQuery (list) UserManga
Club
/{id} ClubQuery Club
/{id}/members/{page} ClubMembersQuery (list) ClubMember
Meta
/status (not implemented)
/requests/{type}/{period}/{page} (not implemented)