개인 개발 프로젝트/Graphql, MongoDB 실습

[Graphql, MongoDB 실습] 3. Graphql 기본 쿼리 예제

종범2 2020. 8. 5. 21:59

Database의 document 생성

tutorial database에 poeple이라는 document를 생성하고 다음과 같이 데이터를 넣는다.

 

총 세 개의 collection을 넣었고 각 collection은 id, friendsIds, name 속성을 가진다. _id는 자동으로 부여되며 friendIds에는 친구의 _id값을 배열로 저장한다. 위의 예제에서 Mike의 친구는 Bill이고, Bill의 친구는 Mike와 Andy이고, Andy의 친구는 Bill이다. 이 document를 바탕으로 전체 사람 목록, 사람의 속성, 사람의 friendIds를 이용하여 다시 사람을 불러오는 쿼리를 작성한다.

 

mongoose Schema 작성

MongoDB의 people이라는 document에 저장된 데이터를 다루기 위해 mongoose에서 Person이라는 스키마를 정의한다. Person에는 String 타입의 name과 Person의 id 타입의 배열인 friendsIds를 정의한다. 이를 위해 models/person.js를 다음과 같이 정의한다.

 

models/person.js

const mongoose = require('mongoose');
const { Schema } = mongoose;
const personSchema = new Schema({
  name: {
    type: String,
    required: true
  },
  friendIds: [{
    type:Schema.Types.ObjectId,
    ref:'Person'
  }]
});

module.exports = mongoose.model('Person', personSchema);

 

Graphql Type 정의

grahpql/schema/index.js에서는 Query 타입과 Person 타입을 정의한다. 여기서는 Person이라는 타입을 정의하고 Person 목록을 불러오는 people이라는 함수를 쿼리 타입에 정의한다.

 

graphql/schema/index.js

const { gql } = require('apollo-server');
const typeDefs = gql`
  type Query {
    people:[Person]
  }
  type Person{
    _id: ID
    name: String
    friends: [Person]
  }
`;

module.exports = typeDefs;

Graphql API를 이용하여 가져올 데이터의 형태는 MongDB에서 정의한 데이터의 형태와 유사하다.

 

Resolver 작성

resolver를 작성한다. people이라는 함수와 Person 타입 정보를 처리하기 위한 로직을 작성한다.

 

graphql/resolvers/index.js

const Person = require('../../models/person');
const resolvers = {
  Query: {
    async people(_, args){
      try {
        const people = await Person.find();
        return people;
      } catch (err) {
        console.log(err);
        throw err;
      }
    },
  },
  Person: {
    _id(_, args) {
      return _._id;
    },
    name(_, args) {
      return _.name;
    },
    async friends(_,args){
      const friends = await Person.find({ _id: { $in: _.friendIds } })
      return friends
    },
  }
};

쿼리에서 people을 요청하면 Person객체의 find 메서드를 호출하여 MongoDB에 저장된 모든 collection을 반환한다. _는 요청하기 이전 객체를 의미한다. 예제에서 people 함수의 _값은 undefined가 되고 _id, name, friends 함수의 _값은 요소 값을 요청하는 Person이 된다. args는 쿼리의 인자인데 지금의 예제에서는 전달하는 인자가 없다.

 

Playground 실행

애플리케이션을 실행하고 playground에서 다음과 같은 쿼리를 작성한다.

query{
  people{
    _id
    name
  }
}

쿼리에서 people을 다음과 같이 요청하면 Person 타입 객체의 배열을 결과값으로 받는다. 이때 Person 객체의 id, name 속성만 받는다.

 

만약 친구의 목록까지 받아오고 싶다면 다음과 같이 쿼리를 작성한다.

 

resolver에서 Person 타입 객체의 요소에 대한 요청까지 처리할 수 있도록 했기 때문에 다음과 같이 쿼리를 작성할 수 있다. 또한 추가적인 작업 없이 Person 타입 객체의 friends 목록에서 각 friends에 해당하는 Person의 friends 목록을 다시 불러올 수 있다.