웹 개발/GraphQL

GraphQL 간단한 Query와 Mutation을 구현하고 테스트 해 보기

restudy 2024. 2. 24. 09:59
반응형

이번 포스트에서는 GraphQL에서 데이터에 접근하는 Query와, 데이터를 추가하고 삭제하는 간단한 Mutation을 구현해 보고 테스트를 해 보도록 하겠습니다.

 

 

개요: 구현할 기능

먼저 구현할 기능은 다음과 같습니다.

 

Person이라는 객체 타입을 정의하고, 각 Person은 고유한 id, 이름, 나이를 값으로 가지도록 작성할 것입니다.

모든 Person들은 group이라는 배열에 저장됩니다. (실제 프로젝트에서는 group이라는 이름을 가지는 데이터베이스에 저장이 되겠죠?)

 

Query는 group을 반환받아 전체 Person들을 받아오는 group 쿼리와, 특정 이름을 가진 Person이 있는지 체크하는 person 쿼리가 있습니다.

 

마지막으로 Mutation에는 2가지를 작성할 것입니다.

group에 새로운 Person을 정의하여 추가하는 createPerson특정 이름을 가진 Person을 group에서 제거하는 deletePerson을 구현할 것입니다.

 

 

 

전체 코드 살펴보기

이제 다음으로 코드를 살펴보겠습니다.

간략한 설명을 위해 한눈에 볼 수 있게끔 모든 typeDefs들과 resolvers들을 한 JavaScript 파일에 작성하였습니다.

 

// server.js

import { ApolloServer, gql } from "apollo-server";

const typeDefs = gql`
  type Person {
    id: ID!
    name: String!
    age: Int!
  }
  type Query {
    group: [Person]
    person(name: String!): Person
  }
  type Mutation {
    createPerson(name: String!, age: Int!): Boolean
    deletePerson(name: String!): Boolean
  }
`;

const group = [
  { id: 1, name: "asdf", age: 25 },
  { id: 2, name: "qwer", age: 30 },
];

const resolvers = {
  Query: {
    group: () => {
      return group;
    },
    person: (_, { name }) => {
      return group.find((person) => {
        return person.name === name;
      });
    },
  },
  Mutation: {
    createPerson: (_, { name, age }) => {
      const newPerson = {
        id: group.length + 1,
        name,
        age,
      };
      group.push(newPerson);
      return true;
    },
    deletePerson: (_, { name }) => {
      const index = group.findIndex((person) => person.name == name);
      if (index === -1) return false;
      group.splice(index, 1);
      return true;
    },
  },
};

const server = new ApolloServer({
  typeDefs,
  resolvers,
});

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

 

 

typeDefs 살펴보기

먼저 typeDefs를 살펴볼까요?

 

 

구현할 기능에서 말한 대로, Person 타입을 선언하고 id, name, age 값을 정의해 줍니다.

그 다음 Query와 Mutation에도 각각 위에서 언급한 내용들을 적어줍니다.

매개변수가 필요한 Query와 Mutation은 소괄호를 쳐주고 필요한 매개변수들과 타입을 적어주어야 합니다.

반환값의 타입을 적어주는 것도 주의해야 합니다.

 

 

그 다음 group 배열을 미리 만들어줍니다.

실제 프로젝트에서는 DB가 필요하겠지만, 여기서는 임시로 배열을 선언하여 여기에 데이터를 추가하고 제거하도록 하겠습니다.

 

 

resolvers 살펴보기

다음으로 resolvers를 살펴봅시다.

resolvers에는 실제로 데이터에 접근하거나 수정하는 과정을 수행하는 함수를 구현해야 합니다.

 

 

Query 부분을 살펴봅시다.

group의 경우에는 전체 배열을 반환해 주면 됩니다.

person은 같은 이름을 가진 Person을 반환해야 하므로, name 인자를 받아 find 함수를 이용해 동일한 이름을 가진 Person을 반환받아 해당 Person을 반환해 줍니다.

 

다음은 Mutation 부분입니다.

createPerson에는 새로 지정할 Person의 name, age 값이 필요합니다.

이제 새로운 Person 객체를 정의하고, 그 객체를 group에 push 해 주면 됩니다.

성공적으로 처리가 되었음을 알리기 위해 true 값을 마지막에 반환해 주도록 합시다.

deletePerson에서는 먼저 해당 name을 가진 Person이 있는지 검색해야 합니다.

만약 index가 -1이라면 해당 이름을 가진 Person이 없다는 뜻이므로, 아무런 변화도 주지 않고 false를 반환하면 됩니다.

만약 찾았다면 해당 Person을 splice 함수를 이용해 group 배열로부터 제거해 주고, true를 반환합니다.

 

 

Query, Mutation 실행해 보기

 

npm run 명령어를 터미널에 입력하여 코드를 실행하면 이렇게 localhost:4000에 서버가 열렸다는 메시지를 출력됩니다.

 

 

localhost:4000으로 이동하면 이렇게 Operation을 작성하고 보낼 수 있는 창이 제공됩니다.

그럼 아까 작성한 쿼리를 실행해 봅시다.

 

 

먼저 group 쿼리입니다.

존재하는 모든 Person들의 id, name, age를 받아오도록 하니 제대로 출력되는 것을 확인할 수 있습니다.

 

 

person 쿼리입니다.

person 쿼리부터는 인자가 필요하므로, name 값에 찾는 사람의 이름을 적어주면 위와 같이 해당 Person만 반환하는 것을 확인할 수 있습니다.

 

 

이제 mutation들을 실행해 보겠습니다.

mutation을 실행할 때에는 위와 같이 가장 바깥쪽의 중괄호 앞에 'mutation'이라고 명시해 주어야 합니다.

 

먼저 createPerson입니다.

name과 age를 적어 create 해 주도록 하였습니다.

반환값을 요청하지 않아도 자동으로 true를 반환하는 것을 확인할 수 있습니다.

 

 

간단히 Person들의 name만 요청해서 확인해 볼까요?

"zxcv"라는 이름을 가진 Person이 group에 잘 추가된 것을 확인할 수 있습니다.

 

 

이번에는 deletePerson입니다.

"asdf"라는 이름을 가진 Person을 group에서 제거해 보겠습니다.

true 값이 정상적으로 반환되는 것을 확인할 수 있습니다.

 

 

group 쿼리로 확인해 보면, "asdf"라는 이름을 가진 Person이 성공적으로 제거된 것을 확인할 수 있습니다.

 

 

What's next...

이렇게 해서 간단한 쿼리와 뮤테이션들을 작성하고 실행해 보았습니다.

 

하지만 이 코드의 경우에는 실제 DB가 아닌 코드의 배열에서 데이터를 다루고 있기 때문에 서버를 재시작하면 모든 변경 사항이 초기화되고 다시 "asdf"와 "qwer" 이름을 가진 Person들이 들어있는 group으로 시작할 것입니다.

따라서 우리는 별도로 상태를 저장할 데이터베이스가 필요합니다.

 

다음 시간에는 Prisma Studio를 이용해 별도의 Database를 관리하는 방법에 대해 알아보겠습니다.

 

 

반응형