본문 바로가기

Dev Dialry/PickMovie

Run Graphql Server with graphql-yoga

graphql 서버를 가장 쉽게 띄우는 방법은 graphql-yoga 모듈을 이용하는 것이다.

graphql-yoga: https://github.com/prisma/graphql-yoga


index.ts와 app.ts를 구분하여 서버 설정 부분은 index.ts에 정의해주고

서버 내에 올라갈 yoga 설정의 경우 app.ts 로 분리하여서 작업.

class App {
public app: GraphQLServer;
constructor() {

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

this.middlewares();
}

private middlewares = (): void => {
this.app.express.use(cors());
this.app.express.use(logger("dev"));
this.app.express.use(helmet());
};
}

위와 같이 기본 설정을 해줄수 있으며, context 내용을 넣어줘서 인증 정보를 비롯한 기타 요청에 대한 정보를 서버내 어디로든 전달해 줄 수 있음.

추후 pubsub 기능이라던가 토큰을 이용한 인증을 붙이는 부분도 이곳에 추가가 가능함.

인증의 경우는 middleware에 추가가 될 것이며, pubsub의 경우 app 생성 단계에 추가가 될것임.

해당 부분에 대해서는 추후 기회가 된다면 다뤄보겠음.

이외에도 시스템 구성에서 heartbeat 기능과 약관을 위한 페이지가 필요해서 해당 url을 추가했다.

여기서 heartbeat는 Linode NodeBalancer가 서버의 상태를 체크할때 사용할 static url이다.

this.app.get("/heartbeat", function(req, res) {
res.send("Still Alive");
});

this.app.use("/public", express.static(path.join(__dirname, "/../public")));

이제 구동 시켜줄 app이 생성되었다. 그런데 에러가 발생한다. 

문제는 schema를 만들어 주지 않았는데..

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

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

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

const typeDefs = mergeTypes(allTypes);
const resolvers = mergeResolvers(allResolvers);

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

export default schema;

위를 이용해 schema를 만들어준 후 해당 schema를 지정해주면 동작할것이다.

위 schema는 프로젝트내 api 폴더안에 존재하는 모든 graphql과 resolvers파일을 가져와 모두 합쳐서 쉽게 사용할 수 있도록 해주는 부분이다.

생성된 앱을 이제 서버에 붙여줄 필요가 있다.

index.ts 파일을 작성해줄 차례다.

const PORT: number | string = process.env.PORT || 4000;
const CRONSERVER: string = process.env.CRONSERVER || "0";
const PLAYGROUND_ENDPOINT: string = "/playground";
const GRAPHQL_ENDPOINT: string = "/graphql";

const appOptions: Options = {
port: PORT,
playground: PLAYGROUND_ENDPOINT,
endpoint: GRAPHQL_ENDPOINT,
};

const handleAppStart = (): void => console.log(`Listening on port ${PORT}`);

createConnection(connectionOptions)
.then(() => {
app.start(appOptions, handleAppStart);

/// Start Movie crons
if (CRONSERVER === "1") {
console.log("Start CRON");
}
})
.catch(error => console.log(error));

app.ts에서 생성해준 graphql server를 로드해서 start해주면 된다.

이때 서버의 설정들을 지정해서 넘겨주면 된다.

이렇게 실행해주게 되면 typeorm 연결을 하고, sync 액션 등.

orm이 동작하게되면 웹서버를 올리게 된다.

"픽무비" 앱의 경우 매일 영화 순위 정보를 갱신해줄 필요가 있다.

이때 cron을 이용해서 동작해주고, 하나의 크론 서버만이 동작되도록 적용해주었다.

실제 서비스에서는 playground를 제거해줄 필요가 있다.

이제 실제 graphql 서버를 갖게 되었으니 resolver들을 지정해서 개발을 해주면 된다.

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

Graphql Schema and Definition  (0) 2019.01.21
Make ORM entity  (0) 2018.12.13
Package Setup  (0) 2018.12.10
Spec  (0) 2018.12.10