From d2a3b8ad37ee4c311d005aca18f006f49a9b2de1 Mon Sep 17 00:00:00 2001 From: "Timothy J. Warren" Date: Wed, 21 Oct 2020 17:59:43 -0400 Subject: [PATCH] More Kitsu GraphQL API cleanup, resolves #33 --- src/AnimeClient/API/APIRequestBuilder.php | 74 ++++++++ .../Queries/Unused/AnimeDetails.graphql | 159 ------------------ .../Queries/Unused/ListItemIdByMalId.graphql | 9 - .../Queries/Unused/MangaDetails.graphql | 101 ----------- .../Queries/Unused/MangaIdByMalId.graphql | 5 - .../Queries/Unused/UserAnimeList.graphql | 56 ------ .../Queries/Unused/UserMangaList.graphql | 56 ------ .../API/Anilist/RequestBuilder.php | 2 + src/AnimeClient/API/Kitsu/Model.php | 15 +- .../API/Kitsu/Queries/GetUserId.graphql | 6 + src/AnimeClient/API/Kitsu/RequestBuilder.php | 128 +------------- 11 files changed, 96 insertions(+), 515 deletions(-) delete mode 100644 src/AnimeClient/API/Anilist/Queries/Unused/AnimeDetails.graphql delete mode 100644 src/AnimeClient/API/Anilist/Queries/Unused/ListItemIdByMalId.graphql delete mode 100644 src/AnimeClient/API/Anilist/Queries/Unused/MangaDetails.graphql delete mode 100644 src/AnimeClient/API/Anilist/Queries/Unused/MangaIdByMalId.graphql delete mode 100644 src/AnimeClient/API/Anilist/Queries/Unused/UserAnimeList.graphql delete mode 100644 src/AnimeClient/API/Anilist/Queries/Unused/UserMangaList.graphql create mode 100644 src/AnimeClient/API/Kitsu/Queries/GetUserId.graphql diff --git a/src/AnimeClient/API/APIRequestBuilder.php b/src/AnimeClient/API/APIRequestBuilder.php index 687cf001..333aa311 100644 --- a/src/AnimeClient/API/APIRequestBuilder.php +++ b/src/AnimeClient/API/APIRequestBuilder.php @@ -33,6 +33,12 @@ use Psr\Log\LoggerAwareTrait; abstract class APIRequestBuilder { use LoggerAwareTrait; + /** + * Where to look for GraphQL request files + * @var string + */ + protected string $filePath = __DIR__; + /** * Url prefix for making url requests * @var string @@ -294,6 +300,74 @@ abstract class APIRequestBuilder { return $this; } + /** + * Create a GraphQL query and return the Request object + * + * @param string $name + * @param array $variables + * @return Request + */ + public function queryRequest(string $name, array $variables = []): Request + { + $file = "{$this->filePath}/Queries/{$name}.graphql"; + if ( ! file_exists($file)) + { + throw new LogicException('GraphQL query file does not exist.'); + } + + $query = file_get_contents($file); + $body = [ + 'query' => $query + ]; + + if ( ! empty($variables)) + { + $body['variables'] = []; + foreach($variables as $key => $val) + { + $body['variables'][$key] = $val; + } + } + + return $this->setUpRequest('POST', $this->baseUrl, [ + 'body' => $body, + ]); + } + + /** + * Create a GraphQL mutation request, and return the Request object + * + * @param string $name + * @param array $variables + * @return Request + * @throws Throwable + */ + public function mutateRequest (string $name, array $variables = []): Request + { + $file = "{$this->filePath}/Mutations/{$name}.graphql"; + if ( ! file_exists($file)) + { + throw new LogicException('GraphQL mutation file does not exist.'); + } + + $query = file_get_contents($file); + $body = [ + 'query' => $query + ]; + + if (!empty($variables)) { + $body['variables'] = []; + foreach ($variables as $key => $val) + { + $body['variables'][$key] = $val; + } + } + + return $this->setUpRequest('POST', $this->baseUrl, [ + 'body' => $body, + ]); + } + /** * Create the full request url * diff --git a/src/AnimeClient/API/Anilist/Queries/Unused/AnimeDetails.graphql b/src/AnimeClient/API/Anilist/Queries/Unused/AnimeDetails.graphql deleted file mode 100644 index db4ba20b..00000000 --- a/src/AnimeClient/API/Anilist/Queries/Unused/AnimeDetails.graphql +++ /dev/null @@ -1,159 +0,0 @@ -query ($id: Int) { - Media(type: ANIME, idMal:$id) { - id - idMal - isAdult - season - title { - romaji - english - native - userPreferred - } - description(asHtml: true) - duration - format - status - chapters - volumes - genres - synonyms - countryOfOrigin - source - startDate { - year - month - day - } - endDate { - year - month - day - } - trailer { - id - site - } - coverImage { - large - medium - } - bannerImage - tags { - id - name - description - category - isGeneralSpoiler - isMediaSpoiler - isAdult - } - characters { - edges { - role - voiceActors { - id - name { - first - last - native - } - language - image { - large - medium - } - description(asHtml: true) - siteUrl - } - node { - id - name { - first - last - native - } - image { - large - medium - } - description - siteUrl - } - } - pageInfo { - total - perPage - currentPage - lastPage - hasNextPage - } - } - staff { - edges { - role - node { - id - name { - first - last - native - } - language - image { - large - medium - } - description(asHtml: true) - siteUrl - } - } - pageInfo { - total - perPage - currentPage - lastPage - hasNextPage - } - } - studios { - edges { - isMain - node { - name - siteUrl - } - } - pageInfo { - total - perPage - currentPage - lastPage - hasNextPage - } - } - externalLinks { - id - url - site - } - mediaListEntry { - id - userId - status - score - progress - progressVolumes - repeat - private - notes - } - streamingEpisodes { - title - thumbnail - url - site - } - siteUrl - } -} \ No newline at end of file diff --git a/src/AnimeClient/API/Anilist/Queries/Unused/ListItemIdByMalId.graphql b/src/AnimeClient/API/Anilist/Queries/Unused/ListItemIdByMalId.graphql deleted file mode 100644 index 704f006d..00000000 --- a/src/AnimeClient/API/Anilist/Queries/Unused/ListItemIdByMalId.graphql +++ /dev/null @@ -1,9 +0,0 @@ -query ($id: Int, $type: MediaType) { - Media (idMal: $id, type: $type) { - mediaListEntry { - id - userId - mediaId - } - } -} \ No newline at end of file diff --git a/src/AnimeClient/API/Anilist/Queries/Unused/MangaDetails.graphql b/src/AnimeClient/API/Anilist/Queries/Unused/MangaDetails.graphql deleted file mode 100644 index c032070e..00000000 --- a/src/AnimeClient/API/Anilist/Queries/Unused/MangaDetails.graphql +++ /dev/null @@ -1,101 +0,0 @@ -query ($id: Int){ - Media(type: MANGA, id: $id) { - id - idMal - isAdult - season - title { - romaji - english - native - userPreferred - } - description(asHtml:true) - duration - format - status - chapters - volumes - genres - synonyms - countryOfOrigin - source - startDate { - year - month - day - } - endDate { - year - month - day - } - trailer { - id - site - } - coverImage { - large - medium - } - bannerImage - tags { - id - name - description - category - isGeneralSpoiler - isMediaSpoiler - isAdult - } - characters { - edges { - id - } - nodes { - id - name { - first - last - native - } - image { - large - medium - } - description - siteUrl - } - pageInfo { - total - perPage - currentPage - lastPage - hasNextPage - } - } - externalLinks { - id - url - site - } - mediaListEntry { - id - userId - status - score - progress - progressVolumes - repeat - private - notes - } - streamingEpisodes { - title - thumbnail - url - site - } - siteUrl - } -} \ No newline at end of file diff --git a/src/AnimeClient/API/Anilist/Queries/Unused/MangaIdByMalId.graphql b/src/AnimeClient/API/Anilist/Queries/Unused/MangaIdByMalId.graphql deleted file mode 100644 index 86899951..00000000 --- a/src/AnimeClient/API/Anilist/Queries/Unused/MangaIdByMalId.graphql +++ /dev/null @@ -1,5 +0,0 @@ -query ($id: Int) { - Media (type: ANIME, malId: $id) { - id - } -} \ No newline at end of file diff --git a/src/AnimeClient/API/Anilist/Queries/Unused/UserAnimeList.graphql b/src/AnimeClient/API/Anilist/Queries/Unused/UserAnimeList.graphql deleted file mode 100644 index ea25ddca..00000000 --- a/src/AnimeClient/API/Anilist/Queries/Unused/UserAnimeList.graphql +++ /dev/null @@ -1,56 +0,0 @@ -query ($name: String) { - MediaListCollection(userName: $name, type: ANIME) { - lists { - entries { - id - mediaId - score - progress - repeat - private - notes - status - media { - id - idMal - title { - romaji - english - native - userPreferred - } - type - format - status - episodes - season - genres - synonyms - countryOfOrigin - source - trailer { - id - } - coverImage { - large - medium - } - bannerImage - tags { - id - } - externalLinks { - id - } - mediaListEntry { - id - } - } - user { - id - } - } - } - } -} - diff --git a/src/AnimeClient/API/Anilist/Queries/Unused/UserMangaList.graphql b/src/AnimeClient/API/Anilist/Queries/Unused/UserMangaList.graphql deleted file mode 100644 index df0f039d..00000000 --- a/src/AnimeClient/API/Anilist/Queries/Unused/UserMangaList.graphql +++ /dev/null @@ -1,56 +0,0 @@ -query ($name: String) { - MediaListCollection(userName: $name, type: MANGA) { - lists { - entries { - id - mediaId - score - progress - progressVolumes - repeat - private - notes - status - media { - id - idMal - title { - romaji - english - native - userPreferred - } - type - format - status - chapters - volumes - genres - synonyms - countryOfOrigin - source - trailer { - id - } - coverImage { - large - medium - } - bannerImage - tags { - id - } - externalLinks { - id - } - mediaListEntry { - id - } - } - user { - id - } - } - } - } -} diff --git a/src/AnimeClient/API/Anilist/RequestBuilder.php b/src/AnimeClient/API/Anilist/RequestBuilder.php index 3717bf15..d2460b14 100644 --- a/src/AnimeClient/API/Anilist/RequestBuilder.php +++ b/src/AnimeClient/API/Anilist/RequestBuilder.php @@ -30,6 +30,8 @@ use const Aviat\AnimeClient\USER_AGENT; use Aviat\AnimeClient\API\APIRequestBuilder; +use LogicException; + final class RequestBuilder extends APIRequestBuilder { use ContainerAware; diff --git a/src/AnimeClient/API/Kitsu/Model.php b/src/AnimeClient/API/Kitsu/Model.php index 4a05e484..4d3740e2 100644 --- a/src/AnimeClient/API/Kitsu/Model.php +++ b/src/AnimeClient/API/Kitsu/Model.php @@ -172,10 +172,9 @@ final class Model { /** * Get the userid for a username from Kitsu * - * @param string $username + * @param string|null $username * @return string - * @throws InvalidArgumentException - * @throws Throwable + * @throws \Psr\SimpleCache\InvalidArgumentException */ public function getUserIdByUsername(string $username = NULL): string { @@ -185,15 +184,11 @@ final class Model { } return $this->getCached(K::AUTH_USER_ID_KEY, function(string $username) { - $data = $this->requestBuilder->getRequest('users', [ - 'query' => [ - 'filter' => [ - 'name' => $username - ] - ] + $data = $this->requestBuilder->runQuery('GetUserId', [ + 'slug' => $username ]); - return $data['data'][0]['id'] ?? NULL; + return $data['data']['findProfileBySlug']['id'] ?? NULL; }, [$username]); } diff --git a/src/AnimeClient/API/Kitsu/Queries/GetUserId.graphql b/src/AnimeClient/API/Kitsu/Queries/GetUserId.graphql new file mode 100644 index 00000000..e86ae567 --- /dev/null +++ b/src/AnimeClient/API/Kitsu/Queries/GetUserId.graphql @@ -0,0 +1,6 @@ +query ($slug: String!) { + findProfileBySlug(slug: $slug) { + id + slug + } +} diff --git a/src/AnimeClient/API/Kitsu/RequestBuilder.php b/src/AnimeClient/API/Kitsu/RequestBuilder.php index 9da7bafe..24d5b526 100644 --- a/src/AnimeClient/API/Kitsu/RequestBuilder.php +++ b/src/AnimeClient/API/Kitsu/RequestBuilder.php @@ -43,7 +43,13 @@ final class RequestBuilder extends APIRequestBuilder { * The base url for api requests * @var string $base_url */ - protected string $baseUrl = K::JSON_API_ENDPOINT; + protected string $baseUrl = K::GRAPHQL_ENDPOINT; + + /** + * Where to look for GraphQL request files + * @var string + */ + protected string $filePath = __DIR__; /** * HTTP headers to send with every request @@ -123,92 +129,6 @@ final class RequestBuilder extends APIRequestBuilder { return $request->getFullRequest(); } - /** - * Remove some boilerplate for get requests - * - * @param mixed ...$args - * @throws Throwable - * @return array - */ - public function getRequest(...$args): array - { - return $this->request('GET', ...$args); - } - - /** - * Remove some boilerplate for patch requests - * - * @param mixed ...$args - * @throws Throwable - * @return array - */ - public function patchRequest(...$args): array - { - return $this->request('PATCH', ...$args); - } - - /** - * Remove some boilerplate for post requests - * - * @param mixed ...$args - * @throws Throwable - * @return array - */ - public function postRequest(...$args): array - { - $logger = $this->container->getLogger('kitsu-request'); - - $response = $this->getResponse('POST', ...$args); - $validResponseCodes = [200, 201]; - - if ( ! in_array($response->getStatus(), $validResponseCodes, TRUE)) - { - $logger->warning('Non 2xx response for POST api call', $response->getBody()); - } - - return JSON::decode(wait($response->getBody()->buffer()), TRUE); - } - - /** - * Remove some boilerplate for delete requests - * - * @param mixed ...$args - * @throws Throwable - * @return bool - */ - public function deleteRequest(...$args): bool - { - $response = $this->getResponse('DELETE', ...$args); - return ($response->getStatus() === 204); - } - - public function queryRequest(string $name, array $variables = []): Request - { - $file = __DIR__ . "/Queries/{$name}.graphql"; - if ( ! file_exists($file)) - { - throw new LogicException('GraphQL query file does not exist.'); - } - - $query = file_get_contents($file); - $body = [ - 'query' => $query - ]; - - if ( ! empty($variables)) - { - $body['variables'] = []; - foreach($variables as $key => $val) - { - $body['variables'][$key] = $val; - } - } - - return $this->setUpRequest('POST', K::GRAPHQL_ENDPOINT, [ - 'body' => $body, - ]); - } - /** * Run a GraphQL API query * @@ -232,38 +152,8 @@ final class RequestBuilder extends APIRequestBuilder { } /** - * @param string $name - * @param array $variables - * @return Request - * @throws Throwable - */ - public function mutateRequest (string $name, array $variables = []): Request - { - $file = __DIR__ . "/Mutations/{$name}.graphql"; - if ( ! file_exists($file)) - { - throw new LogicException('GraphQL mutation file does not exist.'); - } - - $query = file_get_contents($file); - $body = [ - 'query' => $query - ]; - - if (!empty($variables)) { - $body['variables'] = []; - foreach ($variables as $key => $val) - { - $body['variables'][$key] = $val; - } - } - - return $this->setUpRequest('POST', K::GRAPHQL_ENDPOINT, [ - 'body' => $body, - ]); - } - - /** + * Run a GraphQL mutation + * * @param string $name * @param array $variables * @return array