프린세스 다이어리

[GraphQL] 5. Query 구현하는 기본 코드 설명 본문

GraphQL

[GraphQL] 5. Query 구현하는 기본 코드 설명

개발공주 2021. 11. 23. 19:36
728x90

얄팍한 사전코딩 GraphQL

 

기존 코드

const database = require('./database');
const { ApolloServer, gql } = require('apollo-server');

const typeDefs = gql`
  type Query {
    teams: [Team] 
  }
  type Team {
    id: Int
    manager: String
    office: String
    extension_number: String
    mascot: String
    cleaning_duty: String
    project: String 
  } 
`;
const resolvers = {
  Query: {
    teams: () => database.teams
  },
};
const server = new ApolloServer({ typeDefs, resolvers });
server.listen().then(({ url }) => {
  console.log(`🚀  Server ready at ${url}`);
});

 

서버를 켜고, localhost:4000 에 접속한다.

nodemon index.js

 

Apollo GraphQL studio가 뜨면서 변경되는 스키마를 실시간으로 확인할 수 있다.  https://www.apollographql.com/docs/studio/ 참고.

 

1. DB의 특정 데이터를 반환하는 쿼리 추가하기

const typeDefs = gql`
  ...
  type Equipment {
    id: String
    used_by: String
    count: Int
    new_or_used: String
  }
}

디비의 equipment의 데이터 자료형에 따라 typeDefs 템플릿에 이어서 작성을 해 준다. 그리고 이 Equipment 자료형을 복수로 받는 쿼리를 추가한다. 

 

const typeDefs = gql`
  type Query {
    teams: [Team] 
    equipments: [Equipment]
  }
}

쿼리 루트에도 추가를 해 준다.

 

const resolvers = {
  Query: {
    teams: () => database.teams, 
    equipments: () => database.equipments, 
  },
};

쿼리를 실제로 수행할 resolvers에도 추가를 해 준다. 

 

쿼리를 요청해 보면 제대로 작동하는 것을 알 수 있다. 다른 데이터도 이와 같은 방식으로 추가해줄 수 있다.

 

const typeDefs = gql`
  type Query {
    teams: [Team] 
    equipments: [Equipment]
    supplies: [Supply]
  }
  type Team {
    id: Int
    manager: String
    office: String
    extension_number: String
    mascot: String
    cleaning_duty: String
    project: String 
  }
  type Equipment {
    id: String
    used_by: String
    count: Int
    new_or_used: String
  }
  type Supply {
    id: String
    team: Int
  }
`;
const resolvers = {
  Query: {
    teams: () => database.teams,
    equipments: () => database.equipments,
    supplies: () => database.supplies,
  },
};

이렇게 teams, equipments, supplies 를 디비에서 받아와서 반환하는 쿼리를 만들 수 있다.

 

2. 특정 조건에 해당하는 데이터만 받아오기

 

const resolvers = {
  Query: {
    // ...
    team: (parent, args, context, info) =>
      database.teams.filter((team) => team.id === args.id)[0],
  },
};

team은 4개의 인자를 받는다. 이 중 여기서 사용하는 것은 args이다. teams 전체를 받아오는 게 아니라, teams 중에 특정 id를 가진 팀만 찾고 싶기 때문에 team.id와 args.id가 일치하는 팀만 찾아서 필터 하고, filter 함수가 특정 팀에 대한 데이터 하나만 달랑 있는 배열을 반환하기 때문에 마지막으로 [0]으로 원소를 반환해준다.

 

const typeDefs = gql`
  type Query {
    // ...
    team(id: Int): Team
  }
`

team이라는 쿼리로 요청을 하는데 이 쿼리에는 id라는 Int형 인자가 들어간다. 그 결과로 하나의 Team을 받는다. 

 

아폴로 스튜디오에서 team의 id에 2를 넣고 쿼리를 요청해 보면 아이디가 2인 팀에 대한 정보만 반환되는 것을 확인할 수 있다. 역시 한꺼번에 teams로 요청했을 때와는 달리 배열 형태가 아니라 하나의 개별 객체 형태로 반환된다.

 

이처럼 특정 조건에 따라 데이터를 받아오는 쿼리문을 작성할 수 있다. 

 

3. 한 번의 fetch에 여러 데이터 받아오기

 

const typeDefs = gql`
  type Query {
    teams: [Team]
    team(id: Int): Team
    equipments: [Equipment]
    supplies: [Supply]
  }
  type Team {
    id: Int
    manager: String
    office: String
    extension_number: String
    mascot: String
    cleaning_duty: String
    project: String 
  }
  type Equipment {
    id: String
    used_by: String
    count: Int
    new_or_used: String
  }
  type Supply {
    id: String
    team: Int
  }
`;

위처럼 쿼리가 짜여 있는데 한 번 teams를 요청할 때 해당 팀에 해당하는 supplies도 한꺼번에 가져오고 싶다면 RestAPI의 경우 teams와 supplies를 가져오는 요청을 두 번 해야 한다. 이를 해결하기 위해서는 GraphQL에서는 team에 supply를 항목 중 하나로 연결해서 쿼리를 짜 두면 된다. 

 

const resolvers = {
  Query: {
    teams: () =>
      database.teams.map((team) => {
        team.supplies = database.supplies.filter((supply) => {
          return supply.team === team.id;
        });
        return team;
      }),
    // ...
  },
};

디비에서 teams를 받아온 다음에, team의 supplies와 디비의 supplies를 id로 비교해서, id가 일치하는(팀이 일치하는) supplies를 team의 정보에 넣어서 같이 전체 팀 배열을 반환하게 하는 코드다.

 

const typeDefs = gql`
  ...
  type Team {
    id: Int
    manager: String
    office: String
    extension_number: String
    mascot: String
    cleaning_duty: String
    project: String
    supplies: [Supply]
  }
  ...
`;

Team의 자료형도 바꿔준다. supplies에는 다수의 Supply가 배열로 들어간다고 써준다.

 

Apollo Studio에서 teams 하위에 supplies도 원하는 데이터를 선택해서 요청하면, teams 정보에 해당 팀에 대한 supplies까지 연결되어 반환되는 걸 확인할 수 있다.

728x90
Comments