🌸 GraphQL

GraphQL 로 영화 API 만들기(3)

ji-hyun 2022. 2. 1. 02:55
type Query {
  name: Int!
}

 

Int 로 리턴하기를 요청했지만

 

 

const resolvers = {
  Query: {
    name: () => "jihyun",
  },
};

export default resolvers;

 

resolvers 에는 위와 같이 정의했기 때문에......

 

 

 

localhost:4000 에 접속해보자

 

 

실제로 리턴하는 것은 String 이 된다.

보다시피 이런 식으로 type(데이터 유형) 을 적는 건 매우 안전하다. 오류를 잡을 수 있으니까!

 

 

위와 같이 localhost4000 에 접속하면 playground 라고 할 수 있는데 내 데이터베이스를 테스트하게 해준다.

 

 

 

이것은 Postman 과 같은 것이라고 보면 된다...? (난 아직 모르겠다)

이건 데이터베이스를 위한거다.

 

 

 

네트워크탭을 확인해보면 post 방식으로 데이터를 보냄을 알 수 있다.

왼쪽에 있는 query 는 data, 즉 JSON data 라고 할 수 있으며 이걸 어디로 보내야 하는데 그걸 POST 로 보낸다. 모든 Query, Mutation 을 보내야 하는데 항상 POST 로 보내야 한다.

 

왜냐하면 서버가 받아야 하기 때문이다. 

 

 

 

 

const jihyun = {
  name: "Jihyun",
  age: 26,
  gender: "female",
};

const resolvers = {
  Query: {
    person: () => jihyun,    // 위에서 정의한 jihyun 을 리턴
  },
};

export default resolvers;

 

다음은 reslovers 에 위와 같이 jihyun 을 리턴해보도록 수정해보자.

 

 

 

 

그럼 Query 에도 수정을 해줘야 한다. person 을 요청해서 jihyun 타입을 받고 싶다면 어떻게 써줘야 할까?

다음과 같이 Jihyun 이라는 타입을 새로 정의해서 쓰면 된다. 

 

// 새로운 타입 정의
type Jihyun {
  name: String!
  age: Int!
  gender: String!
}


// Jihyun 을 필수로 리턴하게 함
type Query {
  person: Jihyun!
}

 

 

 

 

옆에 도구를 열어볼 수 있다. 이는 내 데이터베이스를 이해할 수 있는 도구이다.

 

 

 

 

query 에 person 을 요청했을 때 다음과 같은 안내창이 뜬다.

 

Nicolas --> Jihyun

 

Jihyun 형식의 person 영역은 하위 영역에 대한 선택권을 가져야 한다고 말하고 있다.

 

여기서 graphql 의 특징을 다시 볼 수 있는데, graphql 에 내가 원하는 정보를 요청할 수 있다는 특징이다.

 

 

 

따라서 다음과 같이 gender, age 원하는 정보만을 얻을 수 있다.

 

 

 


이제 조금 더 복잡한 쿼리를 만들어보자.

 

 

resolvers.js 의 파일의 크기가 너무 커져서 따로 db.js 파일을 만들어주었다. resolver.js 에서는 이를 import { people } from "db.js" 해서 사용할 것이다.

 

// db.js
export const people = [
  {
    id: "0",
    name: "one",
    age: 20,
    gender: "male",
  },
  {
    id: "1",
    name: "two",
    age: 21,
    gender: "female",
  },
  {
    id: "2",
    name: "three",
    age: 22,
    gender: "female",
  },
];

 

 

// resolvers.js
import { people } from "./db";

const resolvers = {
  Query: {
    people: () => people,
  },
};

export default resolvers;

 

 

 

 

 

 

 

 

// schema.graphql
type Person {
  id: String!
  name: String!
  age: Int!
  gender: String!
}

type Query {
  people: [Person]!
  person(id: Int!): Person
}

 

[ ] 는 배열을 요청한다는 뜻이다.

그리고 오직 한 person 에 접근하기 위해서는 person 의 해당 id 가 필요하다.

해당하는 person 을 못 찾는 경우가 있을 수 있으므로 Person 뒤에는 ! 을 없앤다.

 

 

 

 

 

 

playground 에 접속하여 도구를 열어보면..

쿼리문은 people 과 person 을 요청하고 있고 person 을 클릭해보았을 때 오른쪽과 같이 나타나는데

person 에는 id 가 필수로 요구되고 Person 타입을 반환해야 함을 알 수 있다.

 

 

 

 

 

 

 

전체 배열 중에서 graphql 을 통해, 우리가 요청한 영역만을 받게 된다.

 

 

 

 

백엔드 필요없이 내가 원하는 정보만을 이렇게 받을 수 있는게 graphql 의 장점이다!

이제 id 를 어떻게 받아올 수 있는지 보자.

 

 

 

 

 

 

// resolvers.js
export const getById = (id) => {
  const filteredPeople = people.filter((person) => person.id === id);
  return filteredPeople[0];
};

 

filter 는 모든 대상을 거친 뒤 해당 조건에 맞는걸 리턴한다.

 

 

 

 

// playground
{
  person(id:"1"){
    name
  }
}

 

graphql resolvers 는 graphql 서버에서 요청을 받는다.

graphql 서버가 Query 나 Mutation 의 정의를 발견하면 resolvers 를 찾을 것이고 해당 함수를 실행할 것이다. 이때 여기서 argument 를 줄 때가 있다. 

 

 

 

 

 

 

 

 

import { people, getById } from "./db";

const resolvers = {
  Query: {
    people: () => people,
    person: (_, args) => {
      console.log(args);
    },
  },
};

export default resolvers;

 

처음 인자 _ 는 현재 object 를 보내는 object 인데 지금은 중요하지 않으니 신경 안써도 된다.

그리고 argument 를 주고, 

 

 

 

왼쪽에서 graphql 은 argument 와 함께 resolvers 를 요청하고 있다.

 

 

 

서버에서 console.log 되는 것을 확인할 수 있다.

 

 

보다시피 이런 접근 방식은 REST 나 Express, Django 보다 훨씬 낫다. 그것들은 url 이 필요하고 url 은 parameter 들이 필요하고 form-data 를 전송해야 하고 body-parse 하고... 이런 것들을안해도 된다..!

 

 

 

import { people, getById } from "./db";

const resolvers = {
  Query: {
    people: () => people,
    person: (_, { id }) => getById(id),
  },
};

export default resolvers;

 

args -> { id } 로 수정해주자. 이는 console.log(agrs.id) 와 같다.

 

 

 

 

 

다음과 같이 결과가 잘 출력된다..!

 

 

 

 

 

 

 

 

이번에는 Argument 가 있는 Query 를 공부해보았다.

다음 시간에는 Mutation 을 어떻게 사용하는지 알아보겠다!!