Other

[GraphQL]

hyebin Lee 2023. 1. 11. 23:25

GraphQL이 필요한 경우

1. 프론트엔드와 백엔드가 주고받을 데이터를 엄격하게 정의하고 싶을 경우

2. 데이터마다 서로다른 URL을 만들 경우에 지쳤을 경우

3. 필요한 데이터만 알뜰하게 주고 받고 싶을 경우

 

실습환경

https://bit.ly/graphql-example

Fork를 누르면 코드를 수정할 수 있다.

 

상단에 open int New tab 눌르고 개발자 도구에 network를 보면 graphql이라는 주소로 서버와 통신한 내역을 볼 수 있다.

서버쪽으로 던져준 query를 볼 수 있는데 저것이 graphql의 문법이다.

서버는 던져준 코드를 인식해서 응답을 해주는데 응답한 데이터는 다음과 같다.

즉, 이러한 결과값으로 받은 데이터를 가지고 UI를 만들어 주고 있는 애플리케이션이다.

 

스키마 

우리는 GraphQL을 사용한다면 제일 먼저 찾아야할 것은 스키마이다.

스키마(Schema) 란 서버와 클라이언트가 주고 받을 데이터의 형식을 정의한 약속이다.

스키마를 만드는 언어를 Schema Language라고 한다.

 

스키마를 처음 만났을 때 우리는 무조건 type Query를 찾아야한다.  쿼리는 질의한다라는 뜻인데, 즉 브라우저가 서버한테 필요한 정보를 질의한다라는 뜻이다. 

 

🧐 여기서 타입들 뒤에 느낌표가 붙는것은 반드시 값이 있다는 뜻이다.  느낌표가 없는 것은 값이 없을 수 도 있다는 뜻이다.

type Topic {
	id:Int! //숫자
    title:String! //문자열
    body:String //문자열
}

type Query { //브라우저가 서버한테 필요한 정보를 질의한다.
	title : String //타이틀을 요청하면 문자열로 응답할것이다.
    topics:[Topic] //여러개의 글들을 요청하면 배열로 응답할것이고, 그 배열의 각각의 원소는 토픽이다.
    getTopic(id! : Int) : Topic
}

 

GraphQL IDE

주소뒤에 graphQL을 치면 다음과 같은 화면이 나온다.

https://expresssimplez62pqs-ojl5--3010.local-credentialless.webcontainer.io/graphQL

이는 GraphQL이라는 IDE인데 완전 대박 도구이다.

 

여기서 스키마를 확인하기 위해서는 오른쪽 Docs가 있다.

query와 mutation이 나오는데 query를 누르면 아까 확인한 쿼리를 확인할 수 있다.

 

Query Language

이제 코드를 통해서 graphQL과 통신하는 방법을 알아보자. 

 

query language는 데이터를 요청할때 사용한다.

클라이언트가 서버에게 블로그의 제목을 질의하고싶다고 가정해보자.

스카마에 정의된 title을 가지고 오고 싶다면 중괄호 안에 title을 적으면 된다!

실행시켜보면 다음과 같은 결과를 얻을 수 있다.

 

IDE말고 자바스크립트 ajax를 이용하여 json데이터 타입으로 graphql을 이용해보자.

개발자도구를 켜서 다음과 같인 입력하자. 이때 쉬프트를 누르고 엔터를 치면 실행이 유보가 된다. 

endpoint = '/graphql'; //endpoint란 api의 접근할 수 있는 URL이다.
 //서버에게 타이틀을 요청
queryCode =`
{
    title
}
`; 
options = {
    method : 'POST', //통신방법
    headers:{'Content-Type':'application/json'}, //브라우저와 서버와 통신할 때 json타입 데이터로 설정
     //데이터를 보낼 때 자바스크립트 데이터타입을 그대로 보낼 수 없으므로 문자화 해야한다. 
    //객체를 json으로 converting
    body:
    JSON.stringify({
    	query : queryCode 
    })	
}

fetch(endpoint, options);//데이터 접근을 위해 fetch사용, 전송한 데이터들을 옵션으로 줄것이다.


//서버와 통신 후 title값을 추출 하고 싶을 경우 받은 데이터가 json이다라고 알려주면 text를 json data type으로 converting 해준다. 
//우리가 가져온 데이터를 result 이름으로 만들고 그 결과를 찍어보자
fetch(endpoint, options).then(type => type.json()).then(result=>{
	console.log(result); 
    })

엔터를 누르면 서버와 통신이 된 것을 볼 수 있다.

payload는 서버에게 전송된 데이터를 보여주는데, 저것이 query language이다. preview를 보면 응답한 데이터를 볼 수 있다.

 

출력한 result의 값은 다음과 같다. 

 

GraphQL의 유연성

 만약 우리가 글 제목뿐만 아니라 글 목록을 가져오고 싶다면 어떻게 할까?

일단 스키마에서 쿼리부터 보자. 

{
	title //리턴값이 String
    //여기서 topics만 쓰면 에러발생! topics는 배열과 같은 복합적인 데이터이다.
    //배열에 담겨있는 값중에 어떤 값을 사용할 것인지 적어야한다.
    topics{
        id title body
    } 
}

결과는 다음과 값다.

 

RESTful API같은 경우를 사용했다면 타이틀, 토픽 각각의 end point를 만들어서 그에따른 구현을 해야했을 것이다. 

하지만 graphQL같은 경우는 query language를 사용했을 때 자기가 필요한 정보를 적기만 하면 하나의 end point로 유연하게 리턴해준다.

 

함수처럼 인지를 입력받아 사용

- getTopic(id: int) : Topic

getTopic은 우리가 선택한 토픽을 가져오는 상세보기 기능이다. getTopic을 마치 함수처럼 인자를 입력받아 다른 결과를 만들 수 있다.

query ($topicId:Int!){ //topicId변수는 반드시 필요하다라는 표시를 해줌
	title
    topics{
        id title body
    } 
    //쿼리에 함수만 그냥 넣어주면 안되고 정수인 아이디 값을 반드시 넣어줘야한다. 
    //getTopic이 리턴하는 값은 Topic 타입의 데이터이므로 필요한 데이터를 넣어줘야한다.
    //하지만 구체적인 아이디값을 query language안에다 두는것을 좋지않다. 따라서 변수 처리를 해야한다.
    getTopic(id:$topicId){
    	title id body
    }
}

Query Variables (실제 데이터가 있는 곳)

{
	"topicId" : 1
}

 

- 함수를 코드로 통신

endpoint = '/graphql';
queryCode =`
query ($topicId:Int!){
    title
    topics{
    	title id
    }
    getTopic(id:$topicId){
    	id title
    }
}
`; 
variables = {'topicId' : 1}
options = {
    method : 'POST', 
    headers:{'Content-Type':'application/json'},
    body:
    JSON.stringify({
    	query : queryCode,
        variables:variables
    })	
}

fetch(endpoint, options);
fetch(endpoint, options).then(type => type.json()).then(result=>{
	console.log(result); 
    })

결과가 잘 동작하는 것을 확인할 수 있다!

 

Mutation

서버에 있는 데이터를 추가 수정 삭제하고 싶을 때 mutation을 찾는다.

type Mutation {
	createTopic(
    	title : String!, //타이틀 값은 반드시 있어한다.
        body : String
        ):Topic
}

 

- 코드로 통신

endpoint = '/graphql';
queryCode =`
mutation ($title:String!, $body:String){
    createTopic(title:$title, body:$body){
    	id
    }
}
`; 
variables = {'title' : prompt('title') , 'body' : prompt('body') }
options = {
    method : 'POST', 
    headers:{'Content-Type':'application/json'},
    body:
    JSON.stringify({
    	query : queryCode,
        variables:variables
    })	
}

fetch(endpoint, options);
fetch(endpoint, options).then(type => type.json()).then(result=>{
	console.log(result); 
    })

결과 값으로는 createTopic이라는 이름으로 새로운 아이디 값을 리턴한다.

 

 

출처 : 생활코딩 기계들 간의 대화 - GraphQL