본문 바로가기
BE/GraphQL

BE로서 GraphQL 맛보기

by gamxong 2024. 4. 22.

0. 목표

  1. graphQL이 무엇인지 누구한테 간단히 말할 수 있을 정도로 알아보자.
  2. graphQL를 통해서 실제 개발은 어떤식으로 하는지 감각을 가져보자.

 

1. GraphQL 그게 뭔데

1-1. 일단 REST API ?

REST API에 대해서는 깊게 들어가면 끝이 없지만 다들 어느정도 알고 계시기도 하고, 이게 중요한게 아니니까 REST API 자체에 대한 자세한 설명은 넘어가겠습니다!

1-2. REST API 한계

OverFetching 문제

특정 API 의 응답값이 다음과 같다고 가정해보겠습니다!

[
  {
    "name": "송민규",
    "nickname" : "송민규짱짱맨",
    "generation" : 33,
    "part" : "server",
    "drinkingCapacity" : 2.5
    "mbti": "ENTJ"
  },
  {
    "name": "홍길동",
    "nickname" : "홍길이",
    "generation" : 32,
    "part" : "server",
    "drinkingCapacity" : 7.5
    "mbti": "CUTE"
  },
  {
    "name": "원윤이",
    "nickname" : "워뉴니",
    "generation" : 31,
    "part" : "IOS",
    "drinkingCapacity" : 0.1
    "mbti": "ISFP"
  },
  // ...
]

 

만약 특정 화면을 출력하기 위해 name 과 part 만 필요하다면?

  1. BE 에서 새로운 API 를 만들어준다.
    1. → 새로운 API를 만드는데 필요한 리소스, 현실적으로 모든 모든 API를 커스텀하긴 힘듦 
    2. → BE 코드 중복 발생으로 인한 유지보수의 어려움
  2. FE 에서 같은 API를 사용하되, 받은 데이터 중 name 과 part 만 사용한다.                                                   
    1. OverFetching 문제 발생 : 필요없는 데이터까지 리턴받아 통신 비용 증가
    2.  보안적으로도 문제 있을수도!

 

UnderFetching 문제

특정 화면을 출력하기 위해선 다음과 같은 데이터가 필요하다고 가정해보겠습니다!

{
  "partLeader": "최윤한",
  "members": [
    {
      "name": "송민규",
      "mbti": "ENTJ",
      "studyParticipationCount" : 3
    },
    {
      "name": "규민송",
      "mbti": "ENTJ",
      "studyParticipationCount" : 15
    },
    {
      "name": "민송규",
      "mbti": "ISFJ",
      "studyParticipationCount" : 7
    },
    //...
  ]
}

이 데이터를 얻기 위해서는 이전 API와 또다른 API를 조합하여 해당 데이터 구조를 만들 수 있을 것입니다!

다시 말해, 2번 이상의 API 요청이 필요합니다!

→ OverFetching 문제와 비슷한 맥락으로 통신 비용이 증가하는 단점을 가지고 있습니다.

 

1-3. GraphQL

  • GraphQL(이하 gql)도 다른 SQL(이하 sql)과 마찬가지로 쿼리언어입니다.
  • 하지만 gql과 sql은 언어적 구조 차이가 매우 큽니다.
  sql gql
목적 데이터베이스 시스템에 저장된 데이터를 효율적으로 가져온다. 웹 클라이언트가 데이터를 서버로부터 효율적으로 가져온다.
사용주체 백엔드 시스템 클라이언트 시스템
  • sql이 아래와 같다면,
SELECT name, mbti, generation FROM members;

 

  • gql은 아래와 같습니다!
query {
  members {
    name
    mbti
    generation
  }
}

❓클라이언트가 이렇게 보내면, 서버에서는 뭘하는거지?

  • 서버는 gql로 작성된 쿼리를 클라이언트로부터 입력 받아 DB로 쿼리(SQL)를 처리한 결과를 다시 클라이언트로 돌려줍니다.

REST API와 비교

REST API GQL API
다양한 Endpoint 존재 단 하나의 Endpoint
Endpoint마다 데이터베이스 SQL 쿼리가 달라짐 gql 스키마의 타입마다 데이터베이스 SQL 쿼리가 달라짐

 

 

1-4. 그래서 성능이 실제로 어느정도인데?

  • 페이스북 또는 넷플릭스가 어느정도의 성능 최적화를 이뤄냈는지 궁금했는데 관련 지표는 역시 찾기 어렵군요..

 

2. BE 입장에서 GraphQL 맛보기

“뭐 좋은거 알겠는데, 그래서 백엔드는 뭐가 달라지는거야?”

  • 저는 아무래도 백엔드쪽이다 보니까 백엔드 입장에서 실제로 어떻게 사용해야하는지, 기존과 얼마나 다른지, 어떻게 구현되는지 궁금했습니다.

2-1. 아키텍처

  • 큰 그림에서의 아키텍처는 기존 REST API를 사용했을 때와 동일한 패턴입니다!
  • 물론 세부적으로는 리졸버 함수 때문에 다르겠지만 앞단에서만 조금 달라질 뿐 서비스 로직부터는 크게 다르지 않습니다.

2-2. 아주 살짝 맛보기 - Spring for GraphQL 사용

  • 나름 최근에 Spring에서 공식 릴리즈한 프로젝트입니다.
  • 이전에 나온 라이브러리/프레임워크를 사용하면 Resolver를 개발하고 별도의 설정 등 필요했습니다.
  • 하지만 Spring for GraphQL은 Spring이 추구하는 방향답게 추가적인 코드 없이 기존 MVC 개발하듯 개발하면 됩니다!

Query & Mutation

  • 등록, 수정, 삭제, 조회를 구분하는 방법입니다.
    • 조회 : Query
    • 등록, 삭제, 수정 : Mutation

Controller

  • 이처럼 어노테이션 기반으로 코드 작성이 가능합니다!
  • @Argument :
    • @RequestBody 와 비슷한 역할을 한다고 생각했습니다!
    • gql을 통해 전달되는 인수를 매핑하는 역할을 하는 것 같습니다!
  • @QueryMapping :
    • @GetMapping 과 비슷한 역할을 합니다.
  • @MutationMapping :
    • Get를 제외(등록, 수정, 삭제)한 것들에 해당합니다!

Repository

Schema

  • graphql을 사용하기 전에 schema를 설정해야 합니다!
  • schema.graphqls 파일을 만들고 거기에 스키마를 설정해놓으면, spring-boot-graphql 이 컨트롤러에서 받은 요청을 자동으로 매핑시킨다.

 

3. 정리

3-1. 느낀점

  • 사실 그렇게 깊게 들어가진 않고, 가볍게 알아봤는데요!
  • 저는 사실 만약 graphQL이 기존에 제가 해왔던 방식과 크게 다르다면, 사용하는 것에 살짝은 부정적일 수도 있었을 것 같아요!
  • 하지만 전체적인 플로우를 보고 완전 새로운 것이 아닌, 기존의 방식에서의 개선한 느낌이라 좋았던 것 같아요.
  • 대충 코드를 보시면 아시겠지만 서비스 로직 자체는 이전에 REST API 개발때와 크게 다르지 않다는 것을 알 수 있습니다!
  • 즉, 제가 하고 싶은 말은 물론 GraphQL에 대해 배워야 하는 러닝커브가 있는 것은 사실이지만 본질적으로는 크게 다르지 않다! 라는 것을 얘기해보고 싶었습니다!
  • 크게 다르지 않지만, REST API 의 문제점을 해결해주는 솔루션이 될 수 있기에 도입해보는 것도 좋겠다라고 생각했습니다!

3-2. TradeOff

  • GraphQL 스키마의 유지보수 : 서버 개발자로서 유지보수 포인트가 늘어난 건 맞는 것 같습니다!
  • 서버 개발자의 노력이 더 필요하게 된다.
  • 캐싱 전략이 RESTful API에 비해 어렵다. (이 말은 사실 크게 와닿지는 않았습니다..!)
  • 학습 곡선이 있다.(기존 RESTful API 보다)

참고자료

GraphQL과 Apollo

GraphQL 개념잡기

Spring for GraphQL

Annotated Controllers :: Spring GraphQL

 

댓글