Skip to content
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

feat(apps/mobile): use API generated by RTK Query #15

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
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
30 changes: 30 additions & 0 deletions apps/mobile/openapi-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import type { ConfigFile } from '@rtk-query/codegen-openapi';

const EXCLUDED_OPERATIONS = [
'getImagesBkIEhN3PG',
'getImagesByImageIdBreeds',
'postImagesByImageIdBreeds',
'deleteImagesByImageIdBreedsAndBreedId',
];
const EXCLUDED_TAGS = ['Breeds', 'Facts', 'Webhooks'];

const config: ConfigFile = {
schemaFile:
'https://raw.githubusercontent.com/thatapicompany/apis/main/theCatAPI.com/thecatapi-oas.yaml',
apiFile: './src/store/services/EmptyApi.ts',
apiImport: 'EmptyApi',
outputFile: './src/store/services/PetApi.ts',
exportName: 'PetApi',
hooks: true,
tag: true,
filterEndpoints: (operationName, operationDefinition) => {
if (EXCLUDED_OPERATIONS.includes(operationName)) {
return false;
}

const tagsForOperation = operationDefinition.operation.tags ?? [];
return !EXCLUDED_TAGS.some((tag) => tagsForOperation.includes(tag));
},
};

export default config;
19 changes: 19 additions & 0 deletions apps/mobile/src/store/services/EmptyApi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';

// Initialize an empty API service that we'll inject endpoints into later
export const EmptyApi = createApi({
baseQuery: fetchBaseQuery({
baseUrl: 'https://api.thecatapi.com/v1/',
prepareHeaders: (headers) => {
// @TODO In a real app, this should throw an error to be handled by an ErrorBoundary
if (!process.env.EXPO_PUBLIC_CAT_API_KEY) {
console.error('No API key set for Cat API');
return headers;
}

headers.set('x-api-key', process.env.EXPO_PUBLIC_CAT_API_KEY);
return headers;
},
}),
endpoints: () => ({}),
});
298 changes: 298 additions & 0 deletions apps/mobile/src/store/services/PetApi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,298 @@
import { EmptyApi as api } from './EmptyApi';
export const addTagTypes = ['Images', 'Favourites', 'Votes'] as const;
const injectedRtkApi = api
.enhanceEndpoints({
addTagTypes,
})
.injectEndpoints({
endpoints: (build) => ({
getImagesSearch: build.query<
GetImagesSearchApiResponse,
GetImagesSearchApiArg
>({
query: (queryArg) => ({
url: `/images/search`,
headers: {
'Content-Type': queryArg['Content-Type'],
'x-api-key': queryArg['x-api-key'],
},
params: {
size: queryArg.size,
mime_types: queryArg.mimeTypes,
format: queryArg.format,
has_breeds: queryArg.hasBreeds,
order: queryArg.order,
page: queryArg.page,
limit: queryArg.limit,
},
}),
providesTags: ['Images'],
}),
getImages: build.query<GetImagesApiResponse, GetImagesApiArg>({
query: (queryArg) => ({
url: `/images/`,
headers: {
'Content-Type': queryArg['Content-Type'],
'x-api-key': queryArg['x-api-key'],
},
params: {
limit: queryArg.limit,
page: queryArg.page,
order: queryArg.order,
},
}),
providesTags: ['Images'],
}),
postImagesUpload: build.mutation<
PostImagesUploadApiResponse,
PostImagesUploadApiArg
>({
query: (queryArg) => ({
url: `/images/upload`,
method: 'POST',
body: queryArg.body,
headers: {
'Content-Type': queryArg['Content-Type'],
'x-api-key': queryArg['x-api-key'],
},
}),
invalidatesTags: ['Images'],
}),
deleteImagesByImageId: build.mutation<
DeleteImagesByImageIdApiResponse,
DeleteImagesByImageIdApiArg
>({
query: (queryArg) => ({
url: `/images/${queryArg.imageId}`,
method: 'DELETE',
headers: {
'Content-Type': queryArg['Content-Type'],
'x-api-key': queryArg['x-api-key'],
},
}),
invalidatesTags: ['Images'],
}),
getFavourites: build.query<GetFavouritesApiResponse, GetFavouritesApiArg>(
{
query: (queryArg) => ({
url: `/favourites`,
headers: {
'Content-Type': queryArg['Content-Type'],
'x-api-key': queryArg['x-api-key'],
},
}),
providesTags: ['Favourites'],
}
),
postFavourites: build.mutation<
PostFavouritesApiResponse,
PostFavouritesApiArg
>({
query: (queryArg) => ({
url: `/favourites`,
method: 'POST',
body: queryArg.body,
headers: {
'Content-Type': queryArg['Content-Type'],
'x-api-key': queryArg['x-api-key'],
},
}),
invalidatesTags: ['Favourites'],
}),
getFavouritesByFavouriteId: build.query<
GetFavouritesByFavouriteIdApiResponse,
GetFavouritesByFavouriteIdApiArg
>({
query: (queryArg) => ({
url: `/favourites/${queryArg.favouriteId}`,
headers: {
'Content-Type': queryArg['Content-Type'],
'x-api-key': queryArg['x-api-key'],
},
}),
providesTags: ['Favourites'],
}),
deleteFavouritesByFavouriteId: build.mutation<
DeleteFavouritesByFavouriteIdApiResponse,
DeleteFavouritesByFavouriteIdApiArg
>({
query: (queryArg) => ({
url: `/favourites/${queryArg.favouriteId}`,
method: 'DELETE',
headers: {
'Content-Type': queryArg['Content-Type'],
'x-api-key': queryArg['x-api-key'],
},
}),
invalidatesTags: ['Favourites'],
}),
getVotes: build.query<GetVotesApiResponse, GetVotesApiArg>({
query: (queryArg) => ({
url: `/votes`,
headers: {
'Content-Type': queryArg['Content-Type'],
'x-api-key': queryArg['x-api-key'],
},
}),
providesTags: ['Votes'],
}),
postVotes: build.mutation<PostVotesApiResponse, PostVotesApiArg>({
query: (queryArg) => ({
url: `/votes`,
method: 'POST',
body: queryArg.body,
headers: {
'Content-Type': queryArg['Content-Type'],
'x-api-key': queryArg['x-api-key'],
},
}),
invalidatesTags: ['Votes'],
}),
getVotesByVoteId: build.query<
GetVotesByVoteIdApiResponse,
GetVotesByVoteIdApiArg
>({
query: (queryArg) => ({
url: `/votes/${queryArg.voteId}`,
headers: {
'Content-Type': queryArg['Content-Type'],
'x-api-key': queryArg['x-api-key'],
},
}),
providesTags: ['Votes'],
}),
deleteVoteByVoteId: build.mutation<
DeleteVoteByVoteIdApiResponse,
DeleteVoteByVoteIdApiArg
>({
query: (queryArg) => ({
url: `/vote/${queryArg.voteId}`,
method: 'DELETE',
headers: {
'Content-Type': queryArg['Content-Type'],
'x-api-key': queryArg['x-api-key'],
},
}),
invalidatesTags: ['Votes'],
}),
}),
overrideExisting: false,
});
export { injectedRtkApi as PetApi };
export type GetImagesSearchApiResponse = /** status 200 OK */ object;
export type GetImagesSearchApiArg = {
'Content-Type'?: string;
/** [optional] without it only the a basic set of images can be searched */
'x-api-key'?: string;
/** [optional] thumb , small, med or full - small is perfect for Discord */
size?: string;
/** [optional] a comma separated strig of types to return e.g. jpg,png for static, or gif for gifs */
mimeTypes?: string;
/** [optional] json | src */
format?: string;
/** [optional] - only return images with breed data */
hasBreeds?: boolean;
/** [optional] default:RANDOM - RANDOM | ASC | DESC */
order?: string;
/** [optional] paginate through results */
page?: number;
/** [optional] number of results to return, up to 25 with a valid API-Key */
limit?: number;
};
export type GetImagesApiResponse = /** status 200 OK */ object;
export type GetImagesApiArg = {
'Content-Type'?: string;
/** - will return all the images from your account
*/
'x-api-key': string;
/** [Optional] number of images to return valid 1 to 10 - default: 1 */
limit?: number;
/** [Optional] only works if account_id is present to page through your own uploads */
page?: number;
/** [Optional] only works if account_id is present, either ASC or DESC - ascending or descending. */
order?: string;
};
export type PostImagesUploadApiResponse = /** status 201 Created */ object;
export type PostImagesUploadApiArg = {
'Content-Type'?: string;
/** - saves the uploaded image to your account. */
'x-api-key': string;
body: {
file?: Blob;
/** [optional] - a string you can use to segment your images, e.g. knowing which of your own users uploaded it. */
sub_id?: string;
/** [optional] comma separated string of breed ids contained in the image */
breed_ids?: string;
};
};
export type DeleteImagesByImageIdApiResponse =
/** status 200 Successful response */ Blob;
export type DeleteImagesByImageIdApiArg = {
'Content-Type'?: string;
'x-api-key'?: string;
imageId: string;
};
export type GetFavouritesApiResponse = /** status 200 OK */ object;
export type GetFavouritesApiArg = {
'Content-Type'?: string;
'x-api-key': string;
};
export type PostFavouritesApiResponse = /** status 200 OK */ object;
export type PostFavouritesApiArg = {
'Content-Type'?: string;
'x-api-key': string;
body: object;
};
export type GetFavouritesByFavouriteIdApiResponse =
/** status 200 Successful response */ Blob;
export type GetFavouritesByFavouriteIdApiArg = {
'Content-Type'?: string;
'x-api-key': string;
favouriteId: string;
};
export type DeleteFavouritesByFavouriteIdApiResponse =
/** status 200 Successful response */ Blob;
export type DeleteFavouritesByFavouriteIdApiArg = {
'Content-Type'?: string;
'x-api-key': string;
favouriteId: string;
};
export type GetVotesApiResponse = /** status 200 OK */ object;
export type GetVotesApiArg = {
'Content-Type'?: string;
'x-api-key': string;
};
export type PostVotesApiResponse = /** status 201 Created */ object;
export type PostVotesApiArg = {
'Content-Type'?: string;
'x-api-key': string;
body: object;
};
export type GetVotesByVoteIdApiResponse =
/** status 200 Successful response */ Blob;
export type GetVotesByVoteIdApiArg = {
'Content-Type'?: string;
'x-api-key': string;
voteId: string;
};
export type DeleteVoteByVoteIdApiResponse =
/** status 200 Successful response */ Blob;
export type DeleteVoteByVoteIdApiArg = {
'Content-Type'?: string;
'x-api-key': string;
voteId: string;
};
export const {
useGetImagesSearchQuery,
useGetImagesQuery,
usePostImagesUploadMutation,
useDeleteImagesByImageIdMutation,
useGetFavouritesQuery,
usePostFavouritesMutation,
useGetFavouritesByFavouriteIdQuery,
useDeleteFavouritesByFavouriteIdMutation,
useGetVotesQuery,
usePostVotesMutation,
useGetVotesByVoteIdQuery,
useDeleteVoteByVoteIdMutation,
} = injectedRtkApi;
Binary file modified bun.lockb
Binary file not shown.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"@nx/jest": "20.0.0",
"@nx/js": "20.0.0",
"@nx/workspace": "20.0.0",
"@rtk-query/codegen-openapi": "^1.2.0",
"@swc-node/register": "~1.9.1",
"@swc/core": "~1.5.7",
"@swc/helpers": "~0.5.11",
Expand Down