GraphQL 강좌 1편: GraphQL이 무엇인가?


최근 페이스북에서 만든 어플리케이션 레이어 쿼리 언어인 GraphQL 이 공식릴리즈되어 여기저기서 적용한 사례가 생기고있죠 (페이스북은 원래부터 사용하고있었고, 대표적으로 갓 GitHub..) 이 GraphQL 이 뭔지, 이게 왜 필요한건지, 기존의 방식과 뭐가 달라지는건지, 한번 갈피를 잡아봅시다.

GraphQL 강좌 1편: GraphQL이 무엇인가?

소개

GraphQL 은 페이스북에서 만든 어플리케이션 레이어 쿼리 언어입니다. 기존의 웹 혹은 모바일 어플리케이션의 API 를 구현 할 때는, 통상적으로 REST API 가 사용됩니다. 기존의 REST API 를 사용하여 API 를 구현을 한다면, 우리가 클라이언트사이드에서 어떠한 기능이 필요 할 때마다 그때 그때 새로운 API를 만들어주었어야했습니다.

예를들어 여러분의 어플리케이션에 Account 라는 모델이 있고, /accounts 라는 endpoint 가 있다고 가정해봅시다.

GET /accounts

{
  "accounts": [
    {
      "id": "1",
      "username": "velopert",
      "email": "public.velopert@gmail.com",
      "friends": [
        "2",
        "3"
      ],
      "first_name": "Minjun",
      "last_name": "Kim"
    },
    {
      "id": "2",
      "username": "jn4kim",
      "email": "jn4kim@gmail.com",
      "friends": [
        "1",
        "4"
      ],
      "first_name": "Jayna",
      "last_name": "Kim"
    },
    {
      "id": "3",
      "username": "abet",
      "email": "abet@gmail.com",
      "friends": [
        "4"
      ],
      "first_name": "Abet",
      "last_name": "Bane"
    },
    {
      "id": "4",
      "username": "Betty",
      "email": "betty@gmail.com",
      "friends": [
        "1",
        "3"
      ],
      "first_name": "Betty",
      "last_name": "Cain"
    }
  ]
}

만약에 특정 id 를 가진 계정의 정보를 가져오려면 다음과 같이 하겠죠.

GET /accounts/1

{
  "account": {
    "id": "1",
    "username": "velopert",
    "email": "public.velopert@gmail.com",
    "friends": [
      "2",
      "3"
    ],
    "first_name": "Minjun",
    "last_name": "Kim"
  }
}

위 데이터를 보시면 친구의 id들을 friends 라는 field 에 담습니다.

   "friends": [
      "2",
      "3"
    ]

이 목록에 따라서, 친구 계정들의 목록을 가져오려면, 이런 API를 만들어야겠죠..

GET /accounts/1/?include_friend_details=username,first_name

혹은, 이렇게 할 수도 있겠구요

GET /accounts_with_friend_details/1

이런식으로 진행하다가보면, 나중에 어플리케이션의 규모가 커지면 수많은.. 정말 수많은 endpoint가 생성되게 됩니다.

물론, documentation 이 잘 만들어진다면 유지보수하는데에는 그리 큰 문제가 발생하지는 않겠지만, 그래도 보다 간단한 방법이 없을까요?

만약에, 다음과 같이 클라이언트측에서 쿼리를 만들어서 서버로 보내면 우리가 원하는대로 결과를 반환해주면 좋지 않을까요?

쿼리

query {
    account(id: "1") {
        username
        email
        firstName
        lastName
        friends {
            firstName
            username
        }
    }
}

결과

{
  "data": {
    "account": {
      "username": "velopert",
      "email": "public.velopert@gmail.com",
      "firstName": "Minjun",
      "lastName": "Kim",
      "friends": [
        {
          "firstName": "Jayna",
          "username": "jn4kim"
        },
        {
          "firstName": "Abet",
          "username": "abet"
        }
      ]
    }
  }
}

이렇게 깔끔하게 우리가 필요한 정보를 쿼리로 만들어서 서버에 전달해 주면, 서버가 알아서 프로세싱을 하여 주어진 틀대로 데이터를 보여준다면, 정말 멋질것같지 않나요?

쿼리를 통하여 딱 필요한 데이터만 fetching 을 하기 때문에 overfetch 혹은 underfetch 를 할 걱정을 할 필요가 없습니다.

이 포스트를 보고계신 많은 분들께서 이미 예상을 하셨겠지만, 방금 여러분들이 본것이 바로 GraphQL 입니다.

 

이 GraphQL 기술은, 특정 언어에 제한된것이 아니여서, Node.js, Ruby, PHP, Python, Golang, 등 여러 환경에서 사용 할 수 있습니다. 심지어, HTTP 프로토콜에 제한되어있지도 않아서, WebSocket 이나 MQTT 프로토콜 위에서 사용 할 수도 있답니다. 데이터베이스도 어떤 데이터베이스를 사용하던 상관없습니다.

따라서, 이미 구현된 시스템에 도입을 해도 기존에 있던 시스템이 무너지지 않기 때문에 부담 없이 적용을 할 수 있습니다.

맛보기

한번 GraphQL 맛보기를 해봅시다. https://graphql-tryout.herokuapp.com/graphql 에 접속하여 쿼리를 입력해보세요.

이미지 15

예제 쿼리 1

query {
  account (id: "1") {
    username
    email
  }
}

예제 쿼리 2

query {
    account(id: "1") {
        username
        email
        firstName
        lastName
        friends {
            firstName
            username
        }
    }
}

예제 쿼리 3

query {
  accounts {
    id
    username
  }
}

예제 쿼리 4

mutation {
  createAccount(
    username: "testuser"
    email: "tester@email.com"
    firstName: "first"
    lastName: "last"
  ) {
    id
    username
  }
}

GraphQL을 사용하면 큰 노력을 들이지 않고도, 다양한 형태의 데이터를 fetching 을 할 수 있는 시스템을 구현 할 수 있습니다. 오늘은 이렇게 맛보기로 포스트를 마치고, 다음 포스트에서 계속해서 진행하겠습니다. 앞으로 진행 될 GraphQL 강의 시리즈에서는, GraphQL 의 주요 개념들을 배워보고 Node.js 환경에서 GraphQL 서버를 만드는 방법을 알아보겠습니다.

  • 이동주

    와 정말 멋지네요 프론트엔드가 이렇게까지 점점 발전하니 해보고 싶은게 무궁무진해지네요ㅠ 강좌 기대됩니다!

    • 준비가 되는대로 올려보겠습니다 :ㅇ

  • Jeong Hwan Kim

    오.. 재밌네요!

  • Xiang Tian

    너무 기다립니다…^_^

  • byzz

    좋은 강좌 감사합니다 🙂

    • 다음 편도 어서 작성해야하는데.. ㅎㅎㅎ
      이번달 안에 2편을 쓰는걸 목표로..!! 하겠습니당

  • korona

    혹시 https://graphql-tryout.herokuapp.com/graphql 요 서버의 코드가 궁금한데
    다음편에서 알려주시나요???

    • 앗..ㅋㅋㅋ 다음것두 빠른 시일내에 올리겠습니다…

  • 나그네

    이와 비슷한 방식을 한 10년전에 개인적으로 자바프레임웍을 만들어서 프로젝트에 적용했던 적이 있었다능(머 쿼리 모양이 name, email, friends, ..이런식으로 나열식인것만 빼고..ㅎ)…가만히 보면 요즘에 쓰이는 기숟들 중에 다수는 다 예전부터 사용했던거고 다른 언어에 이미 있었던거고 완전히 새롭게 만들어진 것들은 거의 없는듯…

    • 김광훈

      라떼는 말이야~

    • serpiko

      전형적인 꼰데 마인드…..

    • 지나가다

      원글에 아무 문제도 없구만 열라 배배꼬였네. 내가 볼땐 니들이 더 꼰데같다.

  • 양돌

    흠 좋다…

  • Jong-Hyun Kim

    안녕하세요 그래프ql을 사용해보려는 학생입니다. 공식문서를 봐도 어떻게 사용하는지 모르겠어서 댓글 남김니다. 혹시 다음 시리즈는 언제쯤 나올까요?

  • 고건주

    좋은 글 감사드립니다!! 2편도 보고 싶네요..

  • 한영수

    글 잘 읽었습니다.
    GraphQL을 사용하려면 서버에서도 이에 맞게 재설계작업을 추가적으로 해줘야 되지않나요?
    기존 프로젝트에 도입을 하려면 서버개발자와도 많은 대화가 필요하겠네요.

  • Yoo Jin Young

    잘 읽었습니다. 감사합니다.

  • 박성진

    페북이 만든거에 대한건 거의 다 하시는 것 같네요 ㅋㅋㅋ 잘 읽었습니다.

  • 황다슬

    빠뜨성니뮤ㅠㅠ 몇년을 앞서가셨네요ㄷㄷ.. 2편은 어디있나요ㅠㅠ

  • 신동선

    그런데요.. createAccount 쿼리 날리고나서 query { account 하면 생성한 계정 내용이 나와야하지요..? 근데 왜 data : { account : null } 로 나올까요..? createAccount 쿼리 날릴때 리턴으로 id: ‘5’ 해서 생성된것처럼 나오던데요..