GraphQL로 REST API 감싸기

|

GraphQL로 REST API 감싸기

db.js

db.js라는 파일을 따로 생성해주었습니다. 이 곳에 fetch를 이용해 API통신을 해주었습니다.(axios를 이용해도 됨)
npm i node-fetch

import fetch from 'node-fetch';

const API_URL = 'https://yts.mx/api/v2/list_movies.json?';

export const getMovies = (limit, rating) => {
  let REQUEST_URL = API_URL;
  if (limit > 0) {
    REQUEST_URL += `limit=${limit}`;
  }

  if (rating > 0) {
    REQUEST_URL += `&minimum_rating=${rating}`;
  }

  return fetch(REQUEST_URL)
    .then((res) => res.json())
    .then((json) => json.data.movies);
};

resolvers.js

import { getMovies } from './db';

const resolvers = {
  Query: {
    movies: (_, { limit, rating }) => getMovies(limit, rating),
  },
};

export default resolvers;

schema.graphql

type Movie {
  id: Int!
  title: String!
  rating: Float!
  summary: String!
  language: String!
  medium_cover_image: String!
}

type Query {
  movies(limit: Int, rating: Float): [Movie]!
}

graphql playground에서 테스트

movies에 받아올 데이터를 입력해주면 됩니다. 여기서는 title rating를 입력해줬음

{
  movies(rating:8.5,limit:5){
    title
    rating
  }
}


데이터를 불러온 결과물

{
  "data": {
    "movies": [
      {
        "title": "Club Frontera",
        "rating": 9.1
      },
      {
        "title": "Viva the Underdogs",
        "rating": 8.5
      },
      {
        "title": "The Way I See It",
        "rating": 8.5
      },
      {
        "title": "Officer Involved",
        "rating": 8.6
      },
      {
        "title": "Uncle Tom",
        "rating": 9.1
      }
    ]
  }
}

근데 어떨때 이런 방식을 써주는걸까?

이런 방식이란?
fetch를 이용하여 api 데이터를 받아온 후 graphql schema와 resolvers를 이용하여 graphql를 사용하는 방식을 뜻한다.

  • 오래된 서버를 이용할 때
  • Graphql을 넣을 수 없을 때

Creating Queries with Arguments & Mutation?

|

Creating Queries with Arguments

Graphql의 작동방식

그래프큐엘은 Query를 만나면 그 Query와 일치하는 resolvers를 찾고, 해당 함수를 실행시킨다.

그럼 Argument(전달인자)는 어떤식으로 주고 받을수 있을까?

아래 코드에서 movie 부분을 주목

import { getMovies, getById } from './db';

const resolvers = {
  Query: {
    movies: () => getMovies(),
    movie: (_, { id }) => getById(id),
  },
};

export default resolvers;

  • 첫번째 인자는 Object로, 안쓰인다면 _를 해주면된다. 두번째 인자로 아이디를 받는데, arg.id를 {id}로 작성해준 것이다.

Mutation

Mutation이란 Database 상태가 변할 때 사용되는 것이다.
change of state

※그래프큐엘에게 내 Mutation이나 Query를 요청하길 원한다면
type query나, type mutation에 넣어줘야한다!※

예시)

  • schema.graphql
type Movie {
  id: Int!
  name: String!
  score: Int!
}

type Query {
  movies: [Movie]!
  movie(id: Int!): Movie
}

# Database 상태가 변할때 사용되는것,change of state
# graphql에게 내 Mutation이나 Query을 요청하길 원한다면,
# type query나 type mutation에 넣어줘야함
type Mutation {
  addMovie(name: String!, score: Int!): Movie!
}
  • resolvers.js
import { getMovies, getById, addMovie } from './db';

const resolvers = {
  Query: {
    movies: () => getMovies(),
    movie: (_, { id }) => getById(id),
  },
  Mutation: {
    addMovie: (_, { name, score }) => addMovie(name, score),
  },
};

export default resolvers;

Graphql 서버 만들기 및 babel 설정

|

Graphql 서버 만들기

babel 설정

※ Server쪽에서 require대신 import로 모듈을 불러오게끔 하는 코드 ※

  • npm i nodemon -D
  • npm i @babel/cli -D
  • npm i @babel/core -D
  • npm i @babel/node -D
  • npm i @babel/preset-env -D

  • package.json
    "scripts": {
      "start": "nodemon --exec babel-node index.js"
            }
    
  • 루드디렉토리에서 .babelrc 파일 생성후 작성
    {
      "presets": [
          [
                  "@babel/preset-env",
              {
                  "useBuiltIns": "entry",
                  "corejs": 3
              }
          ]
      ]
    }
    

기본적인 작성

new GraphQLServer({}) 안에 Schema를 작성해주거나 여러 기타등등을 넣어줄 수 있다.
Schema란?: 사용자에게 보내거나 사용자로부터 받을 data에 대한 설명을 뜻 한다.

  • index.js
import { GraphQLServer } from 'graphql-yoga';
import resolvers from './graphql/resolvers';

const server = new GraphQLServer({
  typeDefs: 'graphql/schema.graphql',
  resolvers: resolvers,
});

server.start(() => console.log('Graphql Server Running'));

  • graphql > resolvers.js , schema.graphql

  • resolvers.js

    • 쿼리 실행 ```javascript const resolvers = { Query: { name: () => ‘정중식’, }, };

export default resolvers;


- schema.graphql
  - 쿼리 타입 정의
  - 느낌표 ! 는 필수값이라고 생각하면 됨
```javascript
type Query {
  name: String!
}

이런식으로 작성도 가능하다.

Query의 person은 Jung 를 리턴한다.

  • schema.graphql
type Jung {
  name: String!
  age: Int!
  gender: String!
}

type Query {
  person: Jung!
}

  • resolvers.js
const jung = {
  name: 'jungsikjeong',
  age: 27,
  gender: 'female',
};

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

export default resolvers;

Graphql 소개

|

Graphql 소개

노마드코더에서 강의를 보고 정리했습니다.

REST API와 GraphQL 의 차이점

  • REST API: URL로 JSON을 받아온다.
  • GraphQL : query를 보내거나 mutation을 보내야 한다.

graphql은 어떻게 한 Query에 내가 원하는 정보만 받을 수 있을까?

  • 다음과 같이 쿼리를 작성하여 서버에 보내면, javascript 형태로 답장이온다
    {
      feed {
          comments
          likeNumber
      }
      notifications {
          isRead
      }
      user {
          username
          profilePic
      }
    }
    

graphql-yoga ?

npm i graphql-yoga

  • create-react-app 명령어와 비슷하다. GraphQL 프로젝트를 빠르게 시작할 수 있다.

Graphql로 해결 할 수 있는 문제들

  • Over-fetching

    사용자가 요청한 영역의 정보보다, 많은 정보를 서버에서 받는것
    Ex) User Object의 name정보만을 받고싶지만, 그러려면 우선 User Object를 요청해야만 접근가능하다

  • under-fetching

    어떤 하나를 완성하기 위해 다른 요청들이 오고가는것을 말함
    EX) REST에서 하나를 완성하려고 많은 소스를 요청하는 작업, 인스타그램에서 알림,유저정보,피드 등 세개의 요청이 이루어져야 앱이 켜지는것

javascript 이벤트 위임 핵심 코드 정리

|

들어가기에 앞서..

인프런 - 3D템플릿 만들기 인터랙티브 웹 강의에서나온 코드를 정리했습니다.

코드

  function getTarget(elem, className) {
    while (!elem.classList.contains(className)) {
      elem = elem.parentNode;

      if (elem.nodeName == 'BODY') {
        elem = null;
        return;
      }
    }
    return elem;
  }

//   Ex
let pageElem = getTarget(e.target, 'page');

getTarget 함수 정리

  • 요소를 눌렀을때 ‘page’요소의 하위 요소를 클릭했다면(e.target)
    그 요소의 부모를 할당을 해주는것이다.(elem = elem.parentNode;)
    그러면 ‘page’ 요소가 할당이 된다.