김마드 2021. 2. 15. 13:08

🍔 핵심 내용

 

🥑 아키텍처의 의미 (divide and Conquer)

쉽게 설명 하면, 같은 의미있는 것들끼리 묶어 두는 행위라고 보면 된다. ex) 비슷한 유형의 어플들끼리 같은 폴더로 묶어 관리하게 되면 나중에 재사용시, 혹은 변경 시 쉽게 접근 및 수정이 가능하다.

 

현재 server.js에는 typesDefs들과 resolvers(query, mutation), server실행 하는 로직 등이 짬뽕 되어 있다. 이를 분리해주자.

 

🥑 npm i graphql-tools 설치

graphql 필수 요소인, typesDefs와 resolvers들을 분리해놓게 되면 이를 다시 한 곳에 불러와야 하는데, 이 때 사용 될 도구 이다. 자세한 내용은 아래 코드 리뷰에서...!

 

🍔 코드 리뷰

 

🥑 client.js

import { PrismaClient } from "@prisma/client";

const client = new PrismaClient() // client 객체 생성

export default client;

cleint 파일 별도 분리

 

🥑 movies/movies.typeDefs.js

import { gql } from "apollo-server";

export default gql`
type Movie {
    id: Int!
    title: String!
    year: Int!
    genre: String
    createdAt: String!
    updatedAt: String!
  }
  type Query {
    movies: [Movie]
    movie(id:Int!): Movie
  }
  type Mutation {
    createMovie(title: String!, year: Int!, genre: String): Movie
    deleteMovie(id:Int!): Movie
    updateMovie(id: Int!, year: Int!): Movie
  }
`;

movies 폴더 생성 후, typeDefs파일 별도 생성. 추 후, User폴더, like 폴더 추가와 같이 divide and Conquer 해야 한다.

(export default를 해야 함)

 

🥑 movies/movies.queries.js

import client from "../client"

export default {
    Query: {
      movies: () => client.movie.findMany(), //여기서 movie는 prisma에서 정의한 schema (model) 테이블 값이다.
      movie: (_, {id}) => client.movie.findUnique({where:{id}})
    }
  }

 

🥑 movies/movies.mutatios.js

import client from "../client"

export default {
    Mutation: { //movie 테이블 값에 데이터를 추가해보자
    createMovie: (_, { title, year, genre }) => client.movie.create({
      data: {
      title,
      year,
      genre,
    }}),
    deleteMovie: (_, { id }) => client.movie.delete({where: { id }}),
    updateMovie: (_, { id, year }) => client.movie.update({where: { id }, data: { year }}),
  }
};

🥑 schema.js

import { loadFilesSync, makeExecutableSchema, mergeResolvers, mergeTypeDefs } from "graphql-tools";

const loadedTypes = loadFilesSync(`${__dirname}/**/*.typeDefs.js`);
const loadedResolvers = loadFilesSync(`${__dirname}/**/*.{queries,mutations}.js`);

const typeDefs = mergeTypeDefs(loadedTypes);
const resolvers = mergeResolvers(loadedResolvers);

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

export default schema;

위에, typeDefs와 resolvers 파일을 별도 생성 해 주었다. 이를 schema 파일안에 한번에 merge 해주기 위해서는, 앞서 말한 graphql-tools의 도움을 받으면 쉽게 진행 될 수 있다. 

 

여기서, ${__dirname}/**/*.typeDefs.js 는 ${__dirname}/어느 폴더에서든/어느 파일명에서든.typeDefs.js로 끝나는 모든 걸 다 load 해온다. 라는 뜻이고, ${__dirname}/**/*.{queries,mutations}.js 는  ${__dirname}/어느 폴더에서든/어느 파일명에서든.{queries 혹은 mutations파일명이 들어간 }.js의 모든 파일을 load해온다라는 뜻으로 이해하면 된다.

 

그래서 movies.queires.js / movies.mutations.js로 파일명을 지은 것이다.

 

이렇게 schema라는 변수 명으로 typeDefs와 resolvers가 담겼고, 이를 server.js로 보내주기만 하면 된다.

 

🥑 server.js

import { ApolloServer } from "apollo-server";
import schema from "./schema"

const server = new ApolloServer({
  schema,
});

server
  .listen()
  .then(() => console.log("Server is running http://localhost:4000/"));

 

불러 왔다. 이렇게 함으로써, server.js에 있던 모든 내용들이 총 5개로 각 성격별로 찢어 지게 되었다. 분리해서 정복하자!

 


🍔 핵심 내용

 

🥑 npm i dotenv 설치

.env 파일의 데이터를 가져 올 수 있는 모듈을 설치하자. .env에는 다른사람에게 노출되지 않을 정보들이 들어가 있어야 한다

 

🥑 기본 백엔드 셋팅 완료

이제 뼈대까지는 완성이다. 이제 prisma 폴더를 삭제해주고(movies로 만든거는 test용), movies 폴더도 삭제해주자. 그리고 db도 삭제 및 재생성해서 뼈대만 있는 상태에서 진행해보자.

 

🍔 코드 리뷰

 

🥑 server.js

require("dotenv").config(); // <-- 추가
import { ApolloServer } from "apollo-server";
import schema from "./schema"

const server = new ApolloServer({
  schema,
});

const PORT = process.env.PORT;

server
  .listen()
  .then(() => console.log(`🚀 Server is running http://localhost:${PORT} ✅`));

dotenv 부분을 추가 해주었다. 이 부분을 추가함으로써, process.env.변수명을 가져다 쓸 수 있게 되었다.

 

🥑 .env (비공개)

PORT=4000

이렇게 함으로써, .env에 있는 데이터를 끌어다 쓸 수 있다.

 


backend 기본 셋업 완료