Skip to content

Commit

Permalink
refactor(graphql): replace all the input types into arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
async3619 committed Apr 8, 2023
1 parent ece808e commit 3cf8168
Show file tree
Hide file tree
Showing 10 changed files with 92 additions and 162 deletions.
34 changes: 9 additions & 25 deletions schema.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -69,30 +69,14 @@ type ArtistAlbums {
}

type Query {
track(input: GetItemInput!): Track
tracks(input: GetItemsInput!): [Track]!
searchTracks(input: SearchInput!): [Track!]!
album(input: GetItemInput!): Album
track(id: String!, locale: String): Track
tracks(ids: [String!]!, locale: String): [Track]!
searchTracks(query: String!, limit: Int, locale: String): [Track!]!
album(id: String!, locale: String): Album
artistAlbums(offset: Int, limit: Int, locale: String, artistId: String!): ArtistAlbums
albums(input: GetItemsInput!): [Album]!
searchAlbums(input: SearchInput!): [Album!]!
artist(input: GetItemInput!): Artist
artists(input: GetItemsInput!): [Artist]!
searchArtists(input: SearchInput!): [Artist!]!
}

input GetItemInput {
id: String!
locale: String
}

input GetItemsInput {
ids: [String!]!
locale: String
}

input SearchInput {
query: String!
limit: Int
locale: String
albums(ids: [String!]!, locale: String): [Album]!
searchAlbums(query: String!, limit: Int, locale: String): [Album!]!
artist(id: String!, locale: String): Artist
artists(ids: [String!]!, locale: String): [Artist]!
searchArtists(query: String!, limit: Int, locale: String): [Artist!]!
}
10 changes: 3 additions & 7 deletions src/album/album.resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ export class AlbumResolver {
) {}

@Query(() => Album, { nullable: true })
public async album(
@Args("input", { type: () => GetItemInput }) { locale, id }: GetItemInput,
): Promise<Nullable<Album>> {
public async album(@Args() { locale, id }: GetItemInput): Promise<Nullable<Album>> {
return this.albumService.getItem(id, locale);
}

Expand All @@ -36,14 +34,12 @@ export class AlbumResolver {
}

@Query(() => [Album], { nullable: "items" })
public async albums(
@Args("input", { type: () => GetItemsInput }) { locale, ids }: GetItemsInput,
): Promise<Nullable<Album>[]> {
public async albums(@Args() { locale, ids }: GetItemsInput): Promise<Nullable<Album>[]> {
return this.albumService.getItems(ids, locale);
}

@Query(() => [Album])
public async searchAlbums(@Args("input", { type: () => SearchInput }) input: SearchInput): Promise<Album[]> {
public async searchAlbums(@Args() input: SearchInput): Promise<Album[]> {
return this.albumService.search(input);
}
}
10 changes: 3 additions & 7 deletions src/artist/artist.resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,17 @@ export class ArtistResolver {
public constructor(@Inject(ArtistService) private readonly artistService: ArtistService) {}

@Query(() => Artist, { nullable: true })
public async artist(
@Args("input", { type: () => GetItemInput }) { locale, id }: GetItemInput,
): Promise<Nullable<Artist>> {
public async artist(@Args() { locale, id }: GetItemInput): Promise<Nullable<Artist>> {
return this.artistService.getItem(id, locale);
}

@Query(() => [Artist], { nullable: "items" })
public async artists(
@Args("input", { type: () => GetItemsInput }) { locale, ids }: GetItemsInput,
): Promise<Nullable<Artist>[]> {
public async artists(@Args() { locale, ids }: GetItemsInput): Promise<Nullable<Artist>[]> {
return this.artistService.getItems(ids, locale);
}

@Query(() => [Artist])
public async searchArtists(@Args("input", { type: () => SearchInput }) input: SearchInput): Promise<Artist[]> {
public async searchArtists(@Args() input: SearchInput): Promise<Artist[]> {
return this.artistService.search(input);
}

Expand Down
4 changes: 2 additions & 2 deletions src/common/get-item-input.dto.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Field, InputType } from "@nestjs/graphql";
import { ArgsType, Field } from "@nestjs/graphql";

@InputType()
@ArgsType()
export class GetItemInput {
@Field(() => String)
public id!: string;
Expand Down
4 changes: 2 additions & 2 deletions src/common/get-items-input.dto.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Field, InputType } from "@nestjs/graphql";
import { Field, ArgsType } from "@nestjs/graphql";

@InputType()
@ArgsType()
export class GetItemsInput {
@Field(() => [String])
public ids!: string[];
Expand Down
4 changes: 2 additions & 2 deletions src/common/search-input.dto.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { IsOptional, Max, Min } from "class-validator";

import { Field, InputType, Int } from "@nestjs/graphql";
import { Field, ArgsType, Int } from "@nestjs/graphql";

@InputType()
@ArgsType()
export class SearchInput {
@Field(() => String)
public query!: string;
Expand Down
10 changes: 3 additions & 7 deletions src/track/track.resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,17 @@ export class TrackResolver {
public constructor(@Inject(TrackService) private readonly trackService: TrackService) {}

@Query(() => Track, { nullable: true })
public async track(
@Args("input", { type: () => GetItemInput }) { locale, id }: GetItemInput,
): Promise<Nullable<Track>> {
public async track(@Args() { locale, id }: GetItemInput): Promise<Nullable<Track>> {
return this.trackService.getItem(id, locale);
}

@Query(() => [Track], { nullable: "items" })
public async tracks(
@Args("input", { type: () => GetItemsInput }) { locale, ids }: GetItemsInput,
): Promise<Nullable<Track>[]> {
public async tracks(@Args() { locale, ids }: GetItemsInput): Promise<Nullable<Track>[]> {
return this.trackService.getItems(ids, locale);
}

@Query(() => [Track])
public async searchTracks(@Args("input", { type: () => SearchInput }) input: SearchInput): Promise<Track[]> {
public async searchTracks(@Args() input: SearchInput): Promise<Track[]> {
return this.trackService.search(input);
}
}
58 changes: 22 additions & 36 deletions test/album-graphql.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ import { GetItemsInput } from "@common/get-items-input.dto";
import { GetItemInput } from "@common/get-item-input.dto";
import { RootArtistAlbumsInput } from "@common/artist-albums-input.dto";

const searchAlbumsQuery = gql<{ searchAlbums: PartialDeep<Album> }, { input: SearchInput }>`
query ($input: SearchInput!) {
searchAlbums(input: $input) {
const searchAlbumsQuery = gql<{ searchAlbums: PartialDeep<Album> }, SearchInput>`
query ($query: String!, $limit: Int, $locale: String) {
searchAlbums(query: $query, limit: $limit, locale: $locale) {
id
title
artists {
Expand All @@ -24,9 +24,9 @@ const searchAlbumsQuery = gql<{ searchAlbums: PartialDeep<Album> }, { input: Sea
}
}
`;
const albumsQuery = gql<{ albums: PartialDeep<Album>[] }, { input: GetItemsInput }>`
query ($input: GetItemsInput!) {
albums(input: $input) {
const albumsQuery = gql<{ albums: PartialDeep<Album>[] }, GetItemsInput>`
query ($ids: [String!]!, $locale: String) {
albums(ids: $ids, locale: $locale) {
id
title
artists {
Expand All @@ -36,9 +36,9 @@ const albumsQuery = gql<{ albums: PartialDeep<Album>[] }, { input: GetItemsInput
}
}
`;
const albumQuery = gql<{ album: PartialDeep<Album> }, { input: GetItemInput }>`
query ($input: GetItemInput!) {
album(input: $input) {
const albumQuery = gql<{ album: PartialDeep<Album> }, GetItemInput>`
query ($id: String!, $locale: String) {
album(id: $id, locale: $locale) {
id
title
artists {
Expand Down Expand Up @@ -83,9 +83,7 @@ describe("Album (e2e)", () => {

describe("album (GraphQL)", () => {
it("should be able to get album", async () => {
const { data } = await client
.query(albumQuery, { input: { id: "spotify::5DxGRsBdRlbyWoEWvrYQ5P" } })
.toPromise();
const { data } = await client.query(albumQuery, { id: "spotify::5DxGRsBdRlbyWoEWvrYQ5P" }).toPromise();

expectContainPartially(data?.album, {
id: "spotify::5DxGRsBdRlbyWoEWvrYQ5P",
Expand All @@ -94,18 +92,16 @@ describe("Album (e2e)", () => {
});

it("should be able to return null if album is not found", async () => {
const { data } = await client.query(albumQuery, { input: { id: "spotify::test" } }).toPromise();
const { data } = await client.query(albumQuery, { id: "spotify::test" }).toPromise();

expect(data?.album).toBeNull();
});

it("should respect locale", async () => {
const { data: en } = await client
.query(albumQuery, { input: { id: "spotify::5KyAvL3uY3CsyNXPjKmDyU" } })
.toPromise();
const { data: en } = await client.query(albumQuery, { id: "spotify::5KyAvL3uY3CsyNXPjKmDyU" }).toPromise();

const { data: ko } = await client
.query(albumQuery, { input: { id: "spotify::5KyAvL3uY3CsyNXPjKmDyU", locale: "ko_KR" } })
.query(albumQuery, { id: "spotify::5KyAvL3uY3CsyNXPjKmDyU", locale: "ko_KR" })
.toPromise();

expect(en?.album.title).toBe("Independent Music");
Expand Down Expand Up @@ -159,9 +155,7 @@ describe("Album (e2e)", () => {

describe("albums (GraphQL)", () => {
it("should be able to get albums", async () => {
const { data } = await client
.query(albumsQuery, { input: { ids: ["spotify::5DxGRsBdRlbyWoEWvrYQ5P"] } })
.toPromise();
const { data } = await client.query(albumsQuery, { ids: ["spotify::5DxGRsBdRlbyWoEWvrYQ5P"] }).toPromise();

expectContainPartiallyInArray(data?.albums, {
id: "spotify::5DxGRsBdRlbyWoEWvrYQ5P",
Expand All @@ -170,18 +164,18 @@ describe("Album (e2e)", () => {
});

it("should be able to return null if album is not found", async () => {
const { data } = await client.query(albumsQuery, { input: { ids: ["spotify::test"] } }).toPromise();
const { data } = await client.query(albumsQuery, { ids: ["spotify::test"] }).toPromise();

expect(data?.albums).toEqual([null]);
});

it("should respect locale", async () => {
const { data: en } = await client
.query(albumsQuery, { input: { ids: ["spotify::5KyAvL3uY3CsyNXPjKmDyU"] } })
.query(albumsQuery, { ids: ["spotify::5KyAvL3uY3CsyNXPjKmDyU"] })
.toPromise();

const { data: ko } = await client
.query(albumsQuery, { input: { ids: ["spotify::5KyAvL3uY3CsyNXPjKmDyU"], locale: "ko_KR" } })
.query(albumsQuery, { ids: ["spotify::5KyAvL3uY3CsyNXPjKmDyU"], locale: "ko_KR" })
.toPromise();

expect(en?.albums[0].title).toBe("Independent Music");
Expand All @@ -191,9 +185,7 @@ describe("Album (e2e)", () => {

describe("searchAlbums (GraphQL)", () => {
it("should be able to search albums", async () => {
const { data } = await client
.query(searchAlbumsQuery, { input: { query: "독립음악", limit: 1 } })
.toPromise();
const { data } = await client.query(searchAlbumsQuery, { query: "독립음악", limit: 1 }).toPromise();

expect(data?.searchAlbums).toEqual(
expect.arrayContaining([
Expand All @@ -210,25 +202,19 @@ describe("Album (e2e)", () => {
});

it("should respect limit", async () => {
const result_1 = await client
.query(searchAlbumsQuery, { input: { query: "독립음악", limit: 1 } })
.toPromise();
const result_1 = await client.query(searchAlbumsQuery, { query: "독립음악", limit: 1 }).toPromise();

const result_5 = await client
.query(searchAlbumsQuery, { input: { query: "독립음악", limit: 5 } })
.toPromise();
const result_5 = await client.query(searchAlbumsQuery, { query: "독립음악", limit: 5 }).toPromise();

expect(result_1.data?.searchAlbums).toHaveLength(1);
expect(result_5.data?.searchAlbums).toHaveLength(5);
});

it("should respect locale", async () => {
const result_en = await client
.query(searchAlbumsQuery, { input: { query: "독립음악", limit: 1 } })
.toPromise();
const result_en = await client.query(searchAlbumsQuery, { query: "독립음악", limit: 1 }).toPromise();

const result_ko = await client
.query(searchAlbumsQuery, { input: { query: "독립음악", limit: 1, locale: "ko_KR" } })
.query(searchAlbumsQuery, { query: "독립음악", limit: 1, locale: "ko_KR" })
.toPromise();

expect(result_en.data?.searchAlbums[0].title).toBe("Independent Music");
Expand Down
Loading

0 comments on commit 3cf8168

Please sign in to comment.