Web 개발/Web 기본 지식

GraphQL - GraphQL로 정보 주고받기

Surge100 2023. 3. 23. 17:05

GraphQL로 정보 주고 받기

 

REST API는 어떤 라이브러리나 기술이 아니라 정보를 주고 받는 형식이다. 그래서 해당 형식에 따라서 여러 라이브러리들이 정보를 주고 받을수 있다.

 

위 화면은 Apllo라이브러리에서 제공하는 UI이다. 위 UI로 만들고 있는 GraphQL프로젝트에 여러 명령어들을 실행 할 수 있는 UI를 제공한다. REST API에서 사용되는 PostMan과 같은 기능을 한다고 생각하면 된다.

 

GraphQL 사용해 보기

teams정보 받아오기

query는  REST API에서 GET과 같은 것이다. 그 다음에 받아올 객체인 teams{ }을 입력하고 그 안에 team객체에서 받아오기를 원하는 모든 속성을 입력해준다. 일단 위 그림에서는 team에 존재하는 모든 속성을 입력한 다음에 재생 버튼을 눌러준다.

 

{
  "data": {
    "teams": [
      {
        "id": "1",
        "manager": "Mandy Warren",
        "office": "101A",
        "extension_number": "#5709",
        "mascot": "Panda",
        "cleaning_duty": "Monday",
        "project": "Hyperion"
      },
      {
        "id": "2",
        "manager": "Stewart Grant",
        "office": "101B",
        "extension_number": "#4012",
        "mascot": "Tadpole",
        "cleaning_duty": "Tuesday",
        "project": "Zen"
      },
      {
        "id": "3",
        "manager": "Smantha Wheatly",
        "office": "102A",
        "extension_number": "#3852",
        "mascot": "Falcon",
        "cleaning_duty": "Wednesday",
        "project": "Duranno"
      },
      {
        "id": "4",
        "manager": "Francis Buckley",
        "office": "103B",
        "extension_number": "#1039",
        "mascot": "Beaver",
        "cleaning_duty": "Thursday",
        "project": "Genghis"
      },
      {
        "id": "5",
        "manager": "Blake Smith",
        "office": "104A",
        "extension_number": "#7750",
        "mascot": "Wildcat",
        "cleaning_duty": "Friday",
        "project": "Acheron"
      }
    ]
  }
}

그럼 위 JSON 형태로 모든 teams에 관련한 정보를 받아오는 것을 확인할 수 있다. 이는 REST API에서 teams에 해당하는 객체를 불러오는 것과 동일한 결과다.

 

teams의 필요한 정보만 받아오기

{
  "data": {
    "teams": [
      {
        "manager": "Mandy Warren",
        "office": "101A"
      },
      {
        "manager": "Stewart Grant",
        "office": "101B"
      },
      {
        "manager": "Smantha Wheatly",
        "office": "102A"
      },
      {
        "manager": "Francis Buckley",
        "office": "103B"
      },
      {
        "manager": "Blake Smith",
        "office": "104A"
      }
    ]
  }
}

하지만 OverFetching의 문제를 해결하기위해 GraphQL의 특성을 활용하여 원하는 teams에서 원하는 속성인 manager와 office속성만을 불러온다.

 

teams를 id로 구분해서 특정 team만 받아오기

query {
  team(id:2) {
    id
    manager
    office 
  }
}
{
  "data": {
    "team": {
      "id": "2",
      "manager": "Stewart Grant",
      "office": "101B"
    }
  }
}

 

teams를 id로 구분한뒤에 해당 team에 속한 people(members)정보까지 받아오기

query {
  team(id:2) {
    manager
    office 
    members {
      first_name
      last_name
    }
  }
}
{
  "data": {
    "team": {
      "manager": "Stewart Grant",
      "office": "101B",
      "members": [
        {
          "first_name": "Alex",
          "last_name": "Davidson"
        },
        {
          "first_name": "Page",
          "last_name": "Adams"
        },
        {
          "first_name": "Dennis",
          "last_name": "Marshall"
        },
        {
          "first_name": "Eleanor",
          "last_name": "Smith"
        },
        {
          "first_name": "Zelda",
          "last_name": "Hall"
        },
        {
          "first_name": "Brooke",
          "last_name": "Evans"
        },
        {
          "first_name": "Victoria",
          "last_name": "Brown"
        },
        {
          "first_name": "Nancy",
          "last_name": "Brooks"
        },
        {
          "first_name": "Oliver",
          "last_name": "Simpson"
        },
        {
          "first_name": "Simon",
          "last_name": "Henderson"
        }
      ]
    }
  }
}

REST API에서는 teams와 people 두 계층의 정보를 한번에 받아올 수 없었지만 GraphQL에서는 team정보와 해당 team정보를 해당 query에 members들을 끼워 넣어서 보냄으로써 team이라는 계층과 people(members)이라는 계층의 정보를 한꺼번에 받아 올 수 있다.

 

팀 목록과 역할 목록 받아 오기

완전히 다른 정보들을 각자 요청해서 받아 올 수도 있다. 현재 프로젝트에는 teams정보들 뿐만 아니라 member들의 역할 즉 roles라는 데이터도 함께 있다. roles객체의 속성으로는 roles의 이름인 id와 해당 역활을 수행하기 위한 requirement가있다.

 

query {
 teams {
  manager
  office
  mascot
	}
 roles {
  id
  requirement
	}
}

 

{
  "data": {
    "teams": [
      {
        "manager": "Mandy Warren",
        "office": "101A",
        "mascot": "Panda"
      },
      {
        "manager": "Stewart Grant",
        "office": "101B",
        "mascot": "Tadpole"
      },
      {
        "manager": "Smantha Wheatly",
        "office": "102A",
        "mascot": "Falcon"
      },
      {
        "manager": "Francis Buckley",
        "office": "103B",
        "mascot": "Beaver"
      },
      {
        "manager": "Blake Smith",
        "office": "104A",
        "mascot": "Wildcat"
      }
    ],
    "roles": [
      {
        "id": "developer",
        "requirement": "computer science degree"
      },
      {
        "id": "designer",
        "requirement": "graphic design certificate"
      },
      {
        "id": "planner",
        "requirement": "portfolio"
      }
    ]
  }
}

위 쿼리와 같이 요청하면 서로 다른 데이터 정보들이 평행으로 응답하는 것을 확인할 수 있다. 한번 요청에 여러 데이터을 함께 요청해서 받아 오는 것을 확인할 수있다. 이것으로 UnderFetching의 문제도 해결할 수 있다.

 

 클라이언트에 필요한 정보만 요청하면서 그 요청이 여러번 반복 되지 안도록 할 수 있고, 이런 방식을 이용하면 네트워크를 통해 정보를 주고 받는 소프트웨어간에 데이터 낭비를 훨씬 줄일 수 있다.

 

그렇다면 GraphQL을 이용해서 정보를 넣을때는 어떻게 할까?

 

새팀추가

새로운 정보를 생성할 때는 mutation 명령어를 사용한다.

 

mutation request

mutation{
  postTeam(input:{
    manager: "John Smith"
    office:"104B"
    extension_number:"#9982"
    mascot:"Dragon"
    cleaning_duty:"Moday"
    project:"Lordearon"
  }){
    manager
    office
    extension_number
    mascot
    cleaning_duty
    project
  }
}

 

mutation response

{
  "data": {
    "postTeam": {
      "manager": "John Smith",
      "office": "104B",
      "extension_number": "#9982",
      "mascot": "Dragon",
      "cleaning_duty": "Moday",
      "project": "Lordearon"
    }
  }
}

 

데이터를 생성하는 것과 삭제하는 것도 mutation을 통해서 할 수 있다.

 

특정 번호의 팀 정보 수정

mutation{
  editTeam(id: 2, input:{
  	manager: "Maruchi Han"
    office: "105A"
    extension_number: "2315"
    mascot: "Direwolf"
    cleaning_duty: "Wednesday"
    project: "Haemosu"
  }){
  	id,
    manager,
    office,
    extension_number,
    mascot,
    cleaning_duty,
    project
  }
}

 

특정 번호의 팀 삭제

mutation{
  deleteTeam(id: 3){
    id,
    manager,
    office,
    extension_number,
    mascot,
    cleaning_duty,
    project
  }
}

 

 

정리

GraphQL의 강점

1.필요한 정보들만 선택하여 받아올 수 있다.

  • Overfetching 문제 해결
  • 데이터 전송량 감소

2. 여러 계층의 정보들을 한 번에 받아올 수 있다.

  • Underfetching 문제 해결
  • 요청 횟수 감소

3. 하나의 endpoint에서 모든 요청을 처리

  • 하나의 URI에서 POST로 모든 요청 가능

 

출처 - https://www.yalco.kr/@graphql-apollo/1-3/