graphql_ 바로알기 & 쿼리와 뮤테이션

강의를 듣는 중이였다. 분명 강의 제목은 간단한 쇼핑몰 만들기 였지만, 전혀 간단하지 않았다 ㅜㅜㅜ 경험삼아 개념을 아예 모르는채 들은 뒤 공부하는 식의 방향으로 강의를 들으려고 했으나 graphql , apollo-server , jsonDB 등등 이것들의 원리와 필요 이유를 모르게 되니, 강의에 대한 흥미도도 떨어지고, 애러가 났을 때 어디서 잘못 된 건지 모르는 답답함이 느껴져 이렇게 듣다가는 시간낭비 겠구나.. 생각이 들어, 짧게 나마라도 이 친구. 그러니까 그 Graphql 이라는 친구랑 친해지는 시간을 가지려고 한다.

1️⃣💕 Meta가 사랑한 Graphql

GraphQL is a query language for your API, and a server-side runtime for executing queries using a type system you define for your data.
GraphQL isn't tied to any specific database or storage engine and is instead backed by your existing code and data.
// 공식 홈페이지

공식 홈페이지에 따르면 GraphQL은 API용 쿼리 언어로, 시스템을 사용하여 쿼리를 실행하기 위한 서버측 런타임이다. GraphQL은 특정 데이터베이스, 스토리지 엔진에 연결되지 않으며 기존 코드 및 데이터로 지원된다.

라고 하는데 무슨 말인지 와닿지 않는다. 쿼리 언어부터 시작해보자

◾ 쿼리언어

Graphql은 API용 쿼리 언어라고 한다. 그럼 쿼리언어는 무엇이며 그 종류에는 무엇이 있는 것일까.

쿼리언어는 쿼리를 보내 데이터베이스 및 정보 시스템에서 데이터를 요청하고 검색하는 모든 컴푸터 프로그래밍 언어를 나타낸다. 여기서 쿼리는 데이터를 조회하기 위한 명령어이며, 정보 시스템에 데이터를 질의하는 일을 한다.

GraphQL에서 데이터 요청을 할 때에 REST API와 다르게 쿼리 키와 그 키에 해당하는 필드로 데이터를 요청한다.

query GET_CART {
  cart {
    amount
    id
  } 
}

이처럼 쿼리를 통해 데이터를 요청하는 프로그래밍 언어를 나타낸다.

또한 GraphQL은 API유지 관리자에게 기존 쿼리에 영향을 미치지 않고 필드를 추가하거나 폐기할 수 있는 유연성을 부여한다. 이 때문에 우리는 선호하는 방식으로 API를 빌드할 수 있으며, GraphQL사양은 이러한 API가 예측 가능한 방식으로 작동할 수 있도록 보장한다.

query GET_CART($id:ID!) {
  cart {
  amount
  id
  } 
cartItem(id:$id){
  id
}
}

❓ GraphQL이 나오게 된 배경

◽ 기존 API 호출방식의 한계

REST API는 URL, METHOD등을 조합하여 데이터를 호출하기 때문에 다양한 end point 가 존재한다. 반면 GraphQL은 단 하나의 EndPoint가 존재한다. 또한, 데이터의 종류를 쿼리 조합을 통해 결정한다. 만약 보여져야 할 View 에서 필요한 데이터가 다른 경우, Rest API에서는 각자의 end point 가 다르기 때문에 여러번 호출을 해야 한다. (axios.all, Promise.all, Promise.allsettled 등등)

또한 이 방식으로 데이터를 호출 해야 할 경우, 뷰에서 사용할 데이터와 관계없이 모든 데이터의 객체들을 호출하게 된다.

하지만 GraphQL은 클라이언트에서 필요한 데이터만을 쿼리를 사용해 가져올 수 있다. 이 부분은 매우 직관적이면서 깔끔하게 데이터를 처리할 수 있다.

1. 여러번의 데이터 호출 없이 데이터를 가져올 수 있다. 2. 원하는 데이터만 쿼리를 통해 직관적으로 가져올 수 있다.

2️⃣ Query & Mutation

🔸 Query

◽ Field

GraphQL에서 특정 필드를 요청하는 것은 무척 간단하다.

{
  hero {
    name
		# 해당 객체의 하위 선택도 가능
		friends{
			name
		}
  }
}

결과

{
  "data": {
    "hero": {
      "name": "R2-D2",
			"friends":[
				{
					"name": "hello"
				}
			]
    }
  }
}

쿼리와 결과가 동일한 형태임을 볼 수 있다. 이것이 GraphQL의 핵심이자 특징이다. 서버에서 클라이언트가 요청하는 필드를 알고 있기 때문이다.

◽ Arguments

REST API같은 시스템에서는 요청에 쿼리 파라미터와 URL 세크먼트같은 단일 인자들만 전달 할 수 있디만, GraphQL에서는 모든 필드와 중첩된 인자를 가질 수 있다.

{
  hero (name:"IronMan") {
    height
		age
  }
}

인자는 다양한 타입이 될 수 있다. (다음 블로그 기재 예정)

◽ Aliases

필드의 결과를 원하는 이름으로 바꾸어 사용할 수 있다. 필드 네임이 같을 경우 충돌하지만, 서로 다른 이름의 별칭을 지정하여 한 요청에 두 결과를 가져올 수 있다.

{
  ironMan:hero (name:"IronMan") {
    height
  }
	Thor:hero(name:"thor"){
		height
	}
}

◽ Fragment

fragment는 재사용을 가능하게 한다. 프래그먼트를 사용하면 필드셋을 구성한 다음 필요한 쿼리에 포함 시킬 수 있다.

{
  ironMan:hero (name:"IronMan") {
    ...comparionFields
  }
	Thor:hero(name:"thor"){
		...comparionFields
	}
	fragment comparionFields on Int{
		height
		age
	}
}

fragment 안에 변수를 사용할 때에는 이렇게 사용한다.

query HeroComparison($id:ID){
  ironMan:hero (name:"IronMan") {
    ...comparionFields
  }
	Thor:hero(name:"thor"){
		...comparionFields
	}
}
	fragment comparionFields on Int{
		getId(id:$id){
			edges{
				node{
					name
				}
			}
		}
	}

◽ Variables

대부분의 응용프로그램에서 필드에 대한 인자는 동적이다. ex. 검색어, 필터 등등

클라이언트 측 코드는 쿼리 문자열을 런타임에 동적으로 조작하고 , 이를 GraphQL의 특정한 포맷으로 직렬화해야하기 떄문에 동적 인자를 쿼리 문자열에 직접 전달 받는 방법은 좋지 않다. 동적 쿼리 대신 변수로 전달한다.

query HeroNameAndFriends($episode: Episode) {
  hero(episode: $episode) {
    name
    friends {
      name
    }
  }
}
  1. 쿼리 안의 정적 값을 변경한다. ($episode) => 2. $eposide를 쿼리에서 받는 변수로 선언한다. => 3. JSON 변수에 {“episode”:”JEDI”}를 전달한다.

카테고리 | TAG :

#react-query   #graphql