본문 바로가기

Dev Dialry/PickMovie

Graphql Schema and Definition

Typeorm을 이용하여 데이터에 대한 객체들을 선언해 주었다.

이제 실제로 가져온 데이터를 요청에 맞게 내보내 줄 필요가 있다. 이때 필요한것이 graphql schema이다. 그와 함께 typescript를 사용하여 개발을 진행해줄 것이기 때문에 graphql definition을 함께 생성해주게 되면 좀더 쉽게 개발을 진행 해 줄 수 있다.

먼저 필요한 패키지를 설치해준다.

yarn add --dev gql-merge graphql-to-typescript

yarn add merge-graphql-schemas graphql-tools

위 설치해준 패키지들을 이용하여 생성해줄 모든 graphql schema들을 합쳐주고

합쳐준 schema 파일을 통해 type definition을 생성해줄 것이다.

먼저 schema 파일들을 합쳐서 schema로 생성해주는 파일이다.

전체적인 구조는 api들 별로 graphql 파일을 만들어 주고 각각의 resolver들을 생성해줄 것이다. 아래 코드를 보면 알겠지만 각 graphql 파일들은 graphql schema들이 들어있는 파일이며 그 예시도 아래에 보여주겠다.

import { GraphQLSchema } from "graphql";
import { makeExecutableSchema } from "graphql-tools";
import { fileLoader, mergeResolvers, mergeTypes } from "merge-graphql-schemas";
import path from "path";

const allTypes: any[] = fileLoader(path.join(__dirname, "./api/**/*.graphql"));

const allResolvers: any[] = fileLoader(
path.join(__dirname, "./api/**/*.resolvers.*")
);

const typeDefs: string = mergeTypes(allTypes);
const resolvers: any = mergeResolvers(allResolvers);

const schema: GraphQLSchema = makeExecutableSchema({ typeDefs, resolvers });

export default schema;

위 코드를 통해 api 폴더 내에 있는 모든 .graphql 파일을 불러와서 types를 생성해게 되며,

동일한 폴더내에 resolvers들을 모두 불러와 resolvers들을 생성해주게 된다.

이를 schema 하나로 합쳐주게 된다. 이렇게 생성해준 schema는 app.ts 파일내에서 GraphQLServer를 생성해줄때 schema 값에 넣어주게 된다.

this.app = new GraphQLServer({
schema,
context: req => {
const { connection: { context = null } = {} } = req;
return {
req: req.request,
context,
};
},
});

이제 각 graphql schema 파일의 예시를 보여주겠다.

type MovieRank {
id: Int!
rank: Int!
rankDate: String!
movie: Movie
movieId: Int
salesAmount: Float
salesShare: Float
salesInten: Float
salesChange: Float
audiCnt: Int
audiInten: Int
audiChange: Float
screenCnt: Int
showCnt: Int
salesAcc: Float
audiAcc: Int
createdAt: String
}

아래는 위 MovieRank type을 이용하여 실제 요청에 대한 type 정의이다.

type GetMovieRankResponse {
ok: Boolean!
error: String
movies: [MovieRank]
}

type Query {
GetMovieRank(rankDate: String): GetMovieRankResponse!
}

GetMovieRank 요청에 대한 간단한 예시이다.

MovieRank의 배열형태로 movies를 리턴해주게 된다.

scripts로 타입들을 생성해주는 스크립트를 만들어 준다.

"scripts": {
...
"pretypes": "gql-merge --out-file ./src/schema.graphql ./src/api/**/*.graphql",
"types": "graphql-to-typescript ./src/schema.graphql ./src/types/graph.d.ts",
...
}

스크립트 생성 후 아래 명령을 실행해주면 

yarn types

schema.graphql 파일과 types/graph.d.ts 파일이 생성되는 것을 확인할 수 있다.

이를 통해 각 기능별로 graphql schema 파일을 두고, 이를 스크립트를 통해 merge 해주고, 그것을 통해서 편하게 서버에 사용할 수 있게 되었다.

실제 생성된 schema는 아래와 같다.

type Query {
GetAllActors: GetAllActorsResponse!
GetAllGenres: GetAllGenresResponse!
GetMovieRank(rankDate: String): GetMovieRankResponse!
GetNearBySchedule(movieId: Int!, latitude: Float!, longitude: Float!, showDate: String, display: Int, start: Int): GetNearByScheduleResponse!
GetTodayPick: GetTodayPickResponse!
SearchMovieByActor(actorName: String!, orderBy: OrderByOptions, asc: Boolean, start: Int, display: Int): SearchMovieByActorResponse!
SearchMovieByGenres(genresName: String!, orderBy: OrderByOptions, asc: Boolean, start: Int, display: Int): SearchMovieByGenresResponse!
SearchMovieByName(movieName: String!, orderBy: OrderByOptions, asc: Boolean, start: Int, display: Int): SearchMovieByNameResponse!
}

type GetAllGenresResponse {
ok: Boolean!
error: String
genres: [MovieGenres]
}

type GetMovieRankResponse {
ok: Boolean!
error: String
movies: [MovieRank]
}
...

이제 실제 resolver들을 생성해주어 서버에서 결과를 return해주는게 남았다.

'Dev Dialry > PickMovie' 카테고리의 다른 글

Make ORM entity  (0) 2018.12.13
Run Graphql Server with graphql-yoga  (0) 2018.12.12
Package Setup  (0) 2018.12.10
Spec  (0) 2018.12.10