저는 백엔드 개발자이기도 하면서 프론트엔드 개발자이고 iOS 개발자입니다.

파트별로 서로에 대한 불만은 항상 존재합니다. API 가 별로다, 요청해야할 것이 너무 많다 등 여러가지가 있죠. 저는 이 중에서 HTTP 기반 API 호출은 어떻게 써야 효율적인가? 에 대해서 자주 고민을 합니다.

프론트엔드 기술들이 빠른속도로 발전하면서 어떤 기술을 사용해야 하나 도 고민도 자주 합니다. 그러던중 GraphQL 을 알게됐고, GraphQL 을 통해서 첫 번째 고민을 해결 해보고자 했습니다. 이 과정에서 어떤 것들을 느끼고 뭐라고 결론지었는지 공유해보려 합니다.

시작전 간단한 설명

GraphQL 이란?

GraphQL은 최신 응용 프로그램의 복잡하고 중첩 된 데이터 종속성을 설명하기 위해 고안된 데이터 쿼리 언어입니다. 몇 년 동안 Facebook의 프로덕션에서 사용되었습니다.

서버에서는 쿼리를 기본 데이터 패칭 코드에 매핑하도록 GraphQL 시스템을 구성합니다. 이 구성 계층은 GraphQL이 임의의 기본 저장소 메커니즘과 함께 작동하도록합니다. Relay는 GraphQL을 쿼리 언어로 사용하지만 GraphQL의 특정 구현과 관련이 없습니다.

출처 : https://facebook.github.io/react/blog/2015/02/20/introducing-relay-and-graphql.html

GraphQL 은 엄밀하게 RESTful API 와 관계가 없습니다. GraphQL 은 쿼리 문법, DSL 입니다. HTTP 와도 관계가 없습니다. 서버와 클라이언트는 이 문법을 GraphQL 구현체 를 통해서 사용하고, 기존에는 관리하기 힘들었던 nested 한 요청과 응답을 편하게 제어할 수 있습니다.

javascript 에서는 graphql-js, 파이썬에서는 graphene 이 대표적인 GraphQL 구현체입니다.

아래 예시를 보고 한번 느껴보세요.

RESTful API 예시

Request:
GET /products/1?fields=%22id%22%2C%20%22name%22%2C%20%22sellers%22 HTTP/1.1
Host: api.ne-go.kr
Accept: application/json

Response:
{
    "id": 1346463,
    "name": "BN-NBMD543013IVORY",
    "sellers": [{
        "delivery_fee": null,
        "image": "http://imageurl",
        "info": "뉴발란스 자켓 /BN-NBMD543013IVORY/UNI 우븐 플리스",
        "mall_name": "11번가",
        "old_price": null,
        "price": 136040,
        "url": "http://linkurl"
    }]
}

GraphQL 예시 (HTTP 통신을 사용)

Request:
POST /graphql HTTP/1.1
Host: api.ne-go.kr
Content-Type: application/json
Accept: application/json

query {
  products(id: 1) {
    id
    name
    sellers {
      info
      price
    }
  }
}

Response:
{
    "data": {
        "id": 1346463,
        "name": "BN-NBMD543013IVORY",
        "sellers": [
            {
                "info": "뉴발란스 자켓 /BN-NBMD543013IVORY/UNI 우븐 플리스",
                "price": 136040
            }
        ]
    }
}

Relay

Relay는 Facebook의 새로운 프레임 워크로서 React 애플리케이션을 위한 데이터 패칭 기능을 제공합니다. React.js Conf (2015 년 1 월)에서 발표되었습니다.

각 구성 요소는 GraphQL이라는 쿼리 언어를 사용하여 선언적으로 자체 데이터 종속성을 지정합니다. this.props 의 속성을 통해 구성 요소에서 데이터를 사용할 수 있습니다.

개발자는 이러한 React 구성 요소를 자연스럽게 구성하며 Relay는 데이터 쿼리를 효율적인 배치로 구성하고 각 구성 요소에 요청한 데이터를 정확하게 제공하며 데이터 변경시 해당 구성 요소를 업데이트하며 클라이언트 측 모든 데이터를 유지시킵니다.

출처 : https://facebook.github.io/react/blog/2015/02/20/introducing-relay-and-graphql.html

Relay 는 페이스북에서 만든, React 와 조합해서 쓰는 라이브러리입니다. react components 마다 필요한 데이터들을 정의해두면 Relay 가 해당 부분들을 관리해주고, 한번에 모아서 요청을 날린 후 받은 결과를 해당되는 컴포넌트들에게 전달해줍니다.

본론

서버 개발자가 RESTful 한 API 를 만들어두면, 클라이언트 개발자는 해당 API 를 보다 잘 이해하고 사용할 수 있습니다.

하지만.. 복잡하고 많은 정보들이 들어가있는 를 그려야 한다면 ???

API 를 한번… 다른 API 를 또 한번… 다른 API 를 또 한번… 여기에 순차 요청까지 필요하다면…

뷰를 보여주기도 전에 네트워크 요청단에서 너무 나도 많은 시간을 소모하게됩니다.

이 부분에서 GraphQL 은 너무나도 매력있게 느껴졌습니다. 과도하게 많아질 수 있는 호출들을 한방에 해결할 수 있고, 초기 로딩이 빨라지면서 UX 에도 좋은 영향을 줄것이고, 새로운 모델이 추가되거나 기존 모델이 수정되지 않는 한 뷰가 바뀌어도 서버쪽에 추가적인 요청 없이 입맛대로 요청이 가능합니다.

하지만 문제점들이 있습니다.

첫번째로 (자바스크립트를 제외하고) GraphQL 구현체들의 완성도가 아직 미숙합니다. GraphQL 은 커뮤니티 드리븐 방식이기 때문에 페이스북의 도움또한 없습니다. 그리고 대부분의 커뮤니티는 js 쪽에 형성이 되어있습니다. 파이썬과같은 주류 언어에서는 잘 개발되고있지만 다른 언어들은 미숙합니다. 레포 스타 갯수도 100개 언저리고 과연 지속적으로 사용이 가능할지 장담할 수 없습니다.

두번째로 (자바스크립트를 제외하고) ORM 모델들과의 결합이 힘듭니다. 파이썬의 경우에는 ORM 모델과 같이 사용할 수 있도록 익스텐션 라이브러리를 만들어놔서 그나마 괜찮지만, 타 비주류 언어들에는 거의 없다시피합니다. ORM 객체와 GraphQL 타입을 둘다 따로 만들어서 따로 관리를 해주어야 합니다. (Go-lang 개발자로서 정말 처참합니다…)

세번째로 Relay 적용의 어려움과 불편함입니다. 이놈을 적용하기 위해선 꽤나 많은 작업을 해줘야합니다. 기존에 정의된 GraphQL Type 들의 설계를 아예 바꿔야해서 프론트엔드의 React app 에서 뿐만아니라 서버에서도 GraphQL Type 들을 Relay 에 맞게 싹다 다시 작성해야 합니다. 심지어 Relay 를 쓰지않는 다른 iOS 나 Android 앱에서도 재작성해야 합니다.

네번째로 클라이언트측에서 장점이지만 동시에 단점이 됩니다. API 를 매번 요청할 필요도 없어지고, API 호출을 한번만 해도 되는 강력한 장점과 함께, 클라이언트 개발자가 GraphQL 을 공부해서 쿼리를 직접 짜야한다는 강력한 단점이 생깁니다. 과연 모든 클라이언트 개발자가 이를 받아들일 수 있을지 모르겠네요.

결론

만약 백엔드에서 nodejs 를 사용하고 프론트엔드에서는 react + relay 를 사용하고 네이티브 앱에서는 react native + relay 를 사용한다면 첫번째, 두번째, 세번째 문제는 해결이 됩니다.

하지만 대부분의 서비스들의 기술 스택이 이렇지 않습니다. 보통 네이티브 앱은 Java 와 Swift or Objective-c 를 사용하고 백엔드에서 사용하는 언어는 너무나도 다양하죠. 저 또한 저는 백엔드에서 Python 혹은 Golang 을 사용하고 네이티브 앱에서 Swift 를 사용하고 있습니다.

이러한 이유들로 GraphQL 을 사용하기에는 상당히 문제가 있다고 판단을 했습니다.

이재연's profile image

이재연

2016-12-17

글 더보기