DB) GraphQL 개념 파헤치기 (feat. Under-fetching ,Over-fetching)

백준우·2022년 5월 25일
0

DB

목록 보기
5/8
post-thumbnail

1. Under-fetching, Over-fetching

1.1 Under-fetching, Over-fetching 이란?


2. GraphQL

2.1 GraphQL이란?

2.2 GraphQL사용법

2.3 GraphQL 예제


3. GraphQL VS REST


  • 들어가면서...
    BackEnd개발자로 일을 시작하면서 가장 먼저 접하는건 API이다. 흔히 자주 쓰이는 REST API가 있지만 요즘 GraphQL이 이야기로 많이 나오고 특히 다많은 양의 데이터를 처리하는것에 탁월하다는 이야기를 듣고 심층적으로 공부하며 추후 과제나 개인프로젝트에 사용해보고자 한다.
  • 시작
    그래프QL(영어: GraphQL)은 페이스북이 2012년에 개발하여 2015년에 공개적으로 발표된 데이터 질의어이다. 그래프QL은 REST 및 부속 웹서비스 아키텍처를 대체할 수 있다. 클라이언트는 필요한 데이터의 구조를 지정할 수 있으며, 서버는 정확히 동일한 구조로 데이터를 반환한다. 그래프QL은 사용자가 어떤 데이터가 필요한 지 명시할 수 있게 해 주는 강타입 언어이다. 이러한 구조를 통해 불필요한 데이터를 받게 되거나 필요한 데이터를 받지 못하는 문제를 피할 수 있다.(출처: 위키백과)
  • 위 내용을 미루어 봤을때 단순히 데이터를 반화해주는 언어라고 생각이 들지만 불필요한 데이터를 받게되거나 필요한 데이터를 못받게 되는 문제를 피할 수 있다고 한다는 부분이 흥미로웠다. 애초에 데이터는 백에드에서 가공하는 부분이니 결론적이로는 RESTAPI랑 동일하지 않나라는 생각에서 의문점을 가지고 공부를 시작했다.

1. Under-fetching, Over-fetching

1.1 Under-fetching, Over-fetching 이란?

  • GraphQL을 공부하면 한번은 마주치는 개념이다 바로 over-fetching과 under-fetching이다.
    예를 들어 페이스북 myprofile을 예시로 들어 보겠다. 페이스북에 방대한 데이터에서 사용자와 관련된 데이터는 무수히 많을 것이다.
    사용자가 좋아요 누른 게시글 혹은 사용자가 가입한 클럽, 작성한 게시글, 등등 많은 양의 데이터가 쏟아진다
    하지만 myprofile에 필요한 데이터는 한정적이고 Front에 효과적으로 데이터를 전달해야지 동적인 데이터를 만들기 쉬워질것이고 데이터 통신의 무게도 가벼워질것이다.

  • 이때 Over-fetching과 Under-fetching의 개념을 짚고 들어갈 수 있는것이다.

// over-fetching의 예제
{
 	mypage :{
   			Name: Baek
     		Birthday : Oct.08 
     		Hobby : Jogging
     		....
 	},
 	LikePost:{
     		Post_uid: 1   
             Post_uid: 3
    			...  
   	},
     JoinClub:{
     		ClubName: "Like Run",
     		ClubName: "Make Cook"
     		...
     }
}
// under-fetching의 예제
{
 	mypage :{
			Name: Baek
     		Birthday : Oct.08 
     		....
    }
}

위 예시를 보면 한쪽은 데이터를 너무 받아왔으며 남은 한쪽은 데이터를 부족하게 보내준 예시이다.

  • over-fetching: 사용하는 데이터보다 더 많은 데이터를 보내주는 일이다.이는 쓸모없는 데이터를 보내 통신을 무겁게 하고 프론트측에 데이터의 혼동을 줄 수 있다.
  • under-fetching: 하나의 EndPoint로 데이터가 충족되지않으니 API를 두번 호출해야하는 상황이 된다. 이는 사용자에게 느린 서비스를 제공할 수 밖에 없게된다.

🤚🏻 때문에 데이터는 필요한 데이터만 만들어서 통신을 해야하는것이다. 이를 위해 REST API에서는 SQL이나 DBMS를 이용해 데이터를 엔드포인트마다 가공하여 보내주거나 받아서 DataBase에 처리한다.

2. GraphQL

2.1 GraphQL이란?

  • 페이스북에서 만든 쿼리언어이다.
  • 위 사진과 같이 인기는 점점 높아져가고 인지도도 비례하게 높아진다.
  • 기존의 DB의 쿼리문과는다르게 데이터를 정리한다.
#기존 데이터 호출 Query 
	select ID, Name from tableA 
    
#GraphQL 데이터 호출 쿼리     
    {
    	tableA{
     		ID
            Name
        }
    }    
  • 다양한 Server 프레임워크에 사용가능하다. (Node.js, Django, Spring 등)

  • API마다 다른 EndPoint를가지고 SQL Query를 처리하는 REST와는 다르게 GraphQL는 하나의 요청으로 여러가지 엔드포인트를 호출한다.(GraphQL은 스키마의 타입마다 데이터베이스 SQL 쿼리가 달라진다.)

2.2 GraphQL 예제

GraphQL의 예시를 살펴보겠다.

  • DB와 직접 연동하는 것이 아닌 Node.js로 서버마 열어서 Dummy를 직접넣어준뒤 GraphQL로 Dummy를 조작하는 실습을 할것이다.
  1. ApolloServer라는 훌륭한 오픈 서버를 통해 GraphQL의 데이터 호출 상태를 확인 할 수 있다.
// typeDefs를 통해 Data 스키마를 정의하고 resolbers를 통해 스키마에 따른 데이터를 처리하는 방법을 넣는다.
const server = new ApolloServer({ typeDefs, resolvers });
server.listen().then(({ url }) => {
  console.log(`Running on ${url}`);
});
  1. typeDefs를 통해 GraphQL의 schema를 정의해준다.
// graphql은 기본적으로 nullable이 된다 따라서 require로 필드를 만들고 싶으면 !를 뒤에 붙이면 Notnull필드가 된다. 
// (EX : deleteTweet(id: ID!): Boolean!)
const typeDefs = gql`
  type User {
    id: ID!
    firstname: String!
    lastname: String!
    fullName: String!
  }
  type Tweet {
    id: ID!
    text: String!
    author: User!
  }
  type Query {
// 전체 User의 데이터를 Array로 반환한다. 이떄 return되는 값은 NotNull일수 없으며 안에 데이터도 NotNull일 수 없다.
	allUser : [User!]!
    allTweets: [Tweet!]!
// argument로 id에 ID를 받고 그에따른 Tweet을 리턴해준다.
    tweet(id: ID!): Tweet
    ping : String!
  }
  type Mutation {
    postTweet(text: String, userId: ID): Tweet
    deleteTweet(id: ID!): Boolean!
  }
  1. tweets와 users라는 dummyData를 넣어주고 resolvers에 데이터의 처리 방법을 작성하여 넣어준다.
let tweets =[
  {
    id:"1",
    text:"first one",
    userId: "2"
  },
  {
    id:"2",
    text:"Bye",
    userId: "1"
  }
]
let users = [
  {
  id: "1",
  firstname: "Baek",
  lastname: "Joon", 
  // fullName: "BaekJoon"
  },
  {
  id: "2",
  firstname: "Tom",
  lastname: "Holand",
  // fullName: "SpiderMan"
  }
]
const resolvers = {
  Query: {
    //argument로 받는값에 따라 데이터를 보내준다.
    //argument로 입력받은 tweet을 찾아서 반환해준다.
    tweet(root, {id}){
      return tweets.find(tweet => tweet.id = id)
    },
    // allTweets을 통해서 tweets배열을 return해준다.
    // allTweets라는 Query를 입력하면 dummyData의 Tweets내역이 출력된다.
    allTweets(){
      return tweets
    },
  },
  // Get요청이 아닌 메소드는 Mutation으로 처리된다.
  Mutation: {
    // 입력 받은 argument를 처리하는방식
    postTweet(__, {text, userId}){
      const newTweet = {
        id: tweets.length + 1,
        text,
      }
      tweets.push(newTweet)
      // 새로 tweet을 입력받고 입력된 tweet을 반환한다.
      return newTweet
    },
    deleteTweet(__, args){
      const tweet = tweets.find(tweet => tweet.id == args.id)
      if(!tweet) return false
      tweets = tweets.filter(tweet => tweet.id !== args.id)
      return true
    }
  },
}

4. 데이터 처리에대해 입력을 했으니 데이터를호출해보자 (localhost:4000으로 이동하면 Apollo가 열리는것을 확인 할 수 있다.)

  • allTweets로 데이터를 호출 하였을때 모든 데이터가 출력된다.
  • argument로 입력받은 id값의 데이터만 출력된다.
  • 새롭게 id:5 라는 tweet이 작성되었다.

3. GraphQL VS REST

  • 그럼 한가지의 의문이 들 수 있다. 기존에 쓰고있는 REST API가 있는데 왜 굳이 GraphQL로 넘어가야하는것이다.
    나의 생각을 명확히 말하자면 "굳이?"라는 말을 던지고 싶다.
    차이점은 명확히 존재하나 REST API가 우월하다. GraphQL이 우수하다 딱 점찍어 말할 수 없는것이다.
    실제로 미니프로젝트와 클론코딩을 통해 깨닫게된점과 생각되는 부분을 나열 해보겠다.

GraphQL :

  • 사용방법이 어려우나 명확한 데이터 처리가 가능하며 앞서말한 under, over Fetching이 일어날 확률히 현저히 적다.
  • Front-End에서 데이터를 정리 할 수 있다.
  • 하나의 Query를 통해 데이터를 송수신 할 수 있다. 그리고 Query가 쉽고 직관적이다.
  • EndPoint의 모양이 Query의 모양과 일치하도록 실행라이브러리에 의해 구성됩니다.
  • 엄격하게 정의된 데이터 유형은 클라이언트와 서버 간의 통신 오류를 줄여줍니다.

REST :

  • 사용방법이 간단하나 under, over Fetching이 일어날 확률히 상대적으로 높다.
  • Back-End에 의존해야하는 경향이 있다.
  • DB의 데이터를 가공하여 보낼 수 있다.
  • EndPoint를 통해 구성을 한다.

향후 진행방향

참고

profile
이게 되네?

0개의 댓글