GraphQL 끄적끄적

DB|2020. 8. 20. 20:17

GraphQL을 들어본것은 오래됬지만, 클라이언트 단에서 질의를 날린다는게 위험할것 같기도 하고

굳이 불필요 할 것 같아 어떻게 사용하고 동작하는지 파악하지 않았었습니다.

 

하지만, 요즘 많은곳에서 사용되는것들을 보며 대략적으로 어떻게 사용하며

어떻게 동작하는지 살펴보려고 합니다.

 

살펴보기 이전에 GraphQL을 사용하는 이유, GraphQL의 강점을 살펴보자면

기존 많이 사용하는 REST API의 경우 각 쿼리에 대해서 url을 설계하고

해당 url으로 주는 값은 언제나 형태가 고정적이였습니다.

하지만, 업무에 따라 필요한 필드가 다름에도, 공개되어있는 API의 응답의 형태는 동일할 것이기 때문에

클라이언트에서 필요없는 데이터 및 필드들은 알아서 필터링해서 사용해야 했습니다.

 

그리고 매번 새로운 형태의 API가 필요하다면 url을 계속해서 추가해야 합니다.

두개의 리소스를 얻기위해서는 두번의 URL 요청을 해야 합니다.

 

하지만, GraphQL을 사용하게 되면, 필요한 필드만을 응답으로 받을수 있고

여러 리소스들을 한번의 요청으로 받아올 수 있습니다.

 

간단하게는, 클라이언트단에서 여러 요청 및 응답을 유연하게 처리할 수 있게 됩니다.

 

일반적으로, GraphQL은 여러 URL이 아닌 하나의 URL을 통해 처리합니다.

(보통 설정으로 path는 수정할 수 있겠지만, 기본값은 /graphql 을 사용합니다.)

 

그리고 모든 리소스, 그리고 모든 필드를 클라이언트가 조회할 수 있게 된다면

보안상 문제가 될수 있기 때문에

graphqls를 확장자의 파일에 정의된 것만 질의 할 수 있게 되어있습니다.

 

제가 작성한 item.graphqls은

schema{
    query: Query
}

type Query{
    allItems: [Item]
    item(id: Float): Item
}

type Item{
    id: Float
    name: String
}

실제로 Item에는 price와 같은 필드들이 존재하지만 graphqls에 Item에는 존재하지 않기 때문에

질의로 얻을 수 없습니다.

 

이에 대응하는 서버 로직을 작성하는 방법은 여러가지가 있겠지만

제가 작성한 방법은 SpringBoot에서 GraphQLQueryResolver를 사용하여 테스트를 진행해 보았습니다.

 

/graphql 로 요청을 보낼때는 GET, POST 모두 지원하지만 요청 방식이 조금씩 다릅니다.

해당 내용은 https://graphql-kr.github.io/learn/serving-over-http/ 을 참고하시면 될것 같으며

 

POST에 대략적인 사용방법은 request content-type은 application/json으로 하고

아래 처럼 바디에 json 형태로 질의를 요청합니다.

{
	"query" : "{result : allItems{id name}}"	
}

위 쿼리는 "allItems를 응답으로 받을껀데, id, name필드를 받을꺼고 result라는 필드에 데이터를 담아서 받고 싶다"가 됩니다.

물론 이것은 테스트로 작성했기에 파라미터 없이 모든 데이터를 받게 했지만

이런 쿼리를 노출한다면, 부하로 인해 문제가 생길수 있겠습니다.

 

이에 응답은 아래와 같은 형태가 됩니다.

{"data":{"result":[{"id":1.0,"name":null},{"id":2.0,"name":null}]}}

 

하나 더 살펴본다면, 아까 언급한것 처럼 기존에는 두번의 요청을 보내야 하는경우를 graphQL은 한번의 요청으로 처리 할 수 있습니다.

{
	"query" : "{result : allItems{id name},result2 : item(id: 1){name}}"
	
}

방금 요청한 모든 Item을 가져오는 결과를 'result'필드로 응답 받고, id 1번에 대한것은 'result2'로 응답을 달라는 질의 입니다(여기서는 같은 item이지만 일반적으로는 같은 리소스가 아니겠지요)

 

 

이에 응답은 아래와 같은 형태가 됩니다.

{"data":{"result":[{"id":1.0,"name":null},{"id":2.0,"name":null}],"result2":{"name":null}}}

 

바로 적용하지는 않을 예정이기 때문에 간단한 사용방법과 사용 까닭 정도 파악을 위해 테스트 해보았고

끄적끄적 정리해보았습니다.

 

추후 더 파악되는 내용 및 기억하기 위해 기록으로 남겨놓을 내용들이 있다면 기록할 예정입니다

감사합니다.

'DB' 카테고리의 다른 글

[DB] 기초부터다시, ACID, CAP  (0) 2020.09.14
기초부터다시, 조인  (0) 2020.08.18
[MongoDB] 해킹된 후 보안 설정 관련  (0) 2019.12.23
[MyBatis] MyBatis 문법 파서  (0) 2019.05.29
DB 스키마를 관리하자  (0) 2018.12.20

댓글()