1 ๋ถ„ ์†Œ์š”

GraphQL?

GraphQL ์€ API๋ฅผ ์œ„ํ•œ ์ฟผ๋ฆฌ ์–ธ์–ด์ž„.

ํƒ€์ž… ์‹œ์Šคํ…œ์„ ์‚ฌ์šฉํ•˜์—ฌ ์‹คํ–‰ํ•˜๋Š” ์„œ๋ฒ„์‚ฌ์ด๋“œ ๋Ÿฐํƒ€์ž„์ด๋‹ค.

GraphQL ์€ ํŠน์ •ํ•œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋‚˜ ํŠน์ •ํ•œ ์Šคํ† ๋ฆฌ์ง€ ์—”์ง„๊ณผ ๊ด€๊ณ„๋˜์–ด ์žˆ์ง€ ์•Š๊ณ , ๊ธฐ์กด ์ฝ”๋“œ์™€ ๋ฐ์ดํ„ฐ์— ์˜ํ•ด ๋Œ€์ฒด๋œ๋‹ค.

SQL์ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์‹œ์Šคํ…œ์œผ๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋ชฉ์ ์„ ๊ฐ€์ง„๋‹ค๋ฉด, GraphQL์€ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ์„ ๋ชฉ์ ์œผ๋กœ ํ•œ๋‹ค.

GraphQL vs REST API

ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ์„ ๋ชฉ์ ์œผ๋กœ ํ•˜๋Š” ๊ฒƒ์€ GraphQL๊ณผ REST API ๋ชจ๋‘ ๊ฐ™๋‹ค.

๊ทธ๋Ÿผ ์–ด๋–ค ์ฐจ์ด๊ฐ€ ์žˆ์„๊นŒ?

GraphQL

๋ณดํ†ต ํ•˜๋‚˜์˜ ์—”๋“œํฌ์ธํŠธ๋ฅผ ๊ฐ€์ง„๋‹ค.

REST API ์—”๋“œํฌ์ธํŠธ ์˜ˆ์‹œ

- example.com/class
- example.com/class/{๋ฐ˜ index}
- example.com/class/{๋ฐ˜ index}/students

GraphQL ์—”๋“œํฌ์ธํŠธ ์˜ˆ์‹œ

- example.com/grpahql

์œ„์˜ ์˜ˆ์‹œ์ฒ˜๋Ÿผ REST API์™€ ๊ฐ™์ด ์—ฌ๋Ÿฌ ์—”๋“œํฌ์ธํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ์ง๊ด€์ ์ด๊ธด ํ•˜์ง€๋งŒ ๊ด€๋ฆฌํ•˜๊ธฐ ํž˜๋“ค๊ณ , ๋งŽ์€ ์—”๋“œํฌ์ธํŠธ์˜ ๋…ธ์ถœ์„ ๋ง‰๊ธฐ ์œ„ํ•ด ์ถ”๊ฐ€์ ์ธ ์ฒ˜๋ฆฌ๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

์ด์— ๋ฐ˜ํ•ด GraphQL์€ ํ•˜๋‚˜์˜ ์—”๋“œํฌ์ธํŠธ์— ๋‹ค๋ฅธ ์ฟผ๋ฆฌ๋ฅผ ์š”์ฒญํ•˜์—ฌ ์‘๋‹ต์„ ๋ฐ›๊ธฐ ๋•Œ๋ฌธ์— REST API์ฒ˜๋Ÿผ ์ง๊ด€์ ์ด์ง€๋Š” ์•Š์ง€๋งŒ ๊ด€๋ฆฌ์™€ ๋…ธ์ถœ ๋ฐฉ์ง€ ๋ฐฉ๋ฉด์—์„œ๋Š” ์œ ๋ฆฌํ•˜๋‹ค.

์›ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋งŒ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

REST API๋Š” ๋ณดํ†ต ์—ฌ๋Ÿฌ ์—”๋“œํฌ์ธํŠธ๋ฅผ ๊ฐ€์ง€๋ฉฐ, ๊ฐ๊ฐ์˜ ์—”๋“œํฌ์ธํŠธ๊ฐ€ ๋™์ผํ•œ ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

ํ•˜์ง€๋งŒ GraphQL์€ ๋ณดํ†ต ํ•˜๋‚˜์˜ ์—”๋“œํฌ์ธํŠธ๋งŒ์„ ์‚ฌ์šฉํ•˜๊ณ , ์ด๋ฅผ ์š”์ฒญํ•˜๋Š” ์ฟผ๋ฆฌ๋ฅผ ๋‹ค๋ฅด๊ฒŒ ํ•˜์—ฌ ๋‹ค๋ฅธ ์‘๋‹ต์„ ๋ฐ›๋Š” ๋ฐฉ์‹์ด๋‹ค.

๋˜ํ•œ, REST API๋Š” ์—”๋“œํฌ์ธํŠธ๋งˆ๋‹ค ์ •ํ•ด์ง„ ์‘๋‹ต๋งŒ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

REST API ์‘๋‹ต ์˜ˆ์‹œ

// REST API request
GET, https://swapi.dev/api/people/1

// REST API response
{
    "name": "Luke Skywalker",
    "height": "172",
    "mass": "77",
    "hair_color": "blond",
    "skin_color": "fair",
    "eye_color": "blue",
    "birth_year": "19BBY",
    "gender": "male",
    "homeworld": "http://swapi.dev/api/planets/1/",
    "films": ["http://swapi.dev/api/films/1/", "http://swapi.dev/api/films/2/", "http://swapi.dev/api/films/3/", "http://swapi.dev/api/films/6/"],
    "species": [],
    "vehicles": ["http://swapi.dev/api/vehicles/14/", "http://swapi.dev/api/vehicles/30/"],
    "starships": ["http://swapi.dev/api/starships/12/", "http://swapi.dev/api/starships/22/"],
    "created": "2014-12-09T13:50:51.644000Z",
    "edited": "2014-12-20T21:17:56.891000Z",
    "url": "http://swapi.dev/api/people/1/"
}

GraphQL ์‘๋‹ต ์˜ˆ์‹œ

// GraphQL request
query {
    person(personID: 1) {
        name
        height
        mass
    }
}

// GraphQL response
{
    "data": {
        "person": {
            "name": "Luke Skywalker",
            "height": 172,
            "mass": 77
        }
    }
}

์œ„ ์˜ˆ์‹œ๋Š” ์Šคํƒ€์›Œ์ฆˆ์˜ ์ธ๋ฌผ ์ •๋ณด๋ฅผ ๋ฐ›์•„์˜ค๋Š” ์˜ˆ์‹œ์ด๋‹ค.

REST API๋Š” ์ธ๋ฌผ์˜ ์ •๋ณด๋ฅผ ๋ฐ›์•„์˜ค๋ฉด ํ•„์š”ํ•œ ์ •๋ณด ์ด์™ธ์—๋„ ๋งŽ์€ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๊ฒŒ ๋œ๋‹ค.

ํ•˜์ง€๋งŒ GrpahQL์€ ์ฟผ๋ฆฌ๋ฅผ ์ ์ ˆํ•˜๊ฒŒ ์‚ฌ์šฉํ•จ์œผ๋กœ์จ, ํ•„์š”ํ•œ ์ •๋ณด๋งŒ ๊ฐ€์ ธ์˜ค๋„๋ก ํ•  ์ˆ˜ ์žˆ๋‹ค.

GraphQL์˜ ์žฅ์ 

  1. HTTP ์š”์ฒญ ํšŸ์ˆ˜๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.
  2. HTTP ์‘๋‹ต ์‚ฌ์ด์ฆˆ๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.
  3. ํ”„๋ก ํŠธ์—”๋“œ์™€ ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž์˜ ๋ถ€๋‹ด์„ ๋œ ์ˆ˜ ์žˆ๋‹ค.

GraphQL์˜ ๋‹จ์ 

  1. ๊ณ ์ •๋œ ์š”์ฒญ๊ณผ ์‘๋‹ต๋งŒ ํ•„์š”ํ•  ๋•Œ๋Š” ์ฟผ๋ฆฌ๋กœ ์ธํ•ด ์š”์ฒญ์˜ ํฌ๊ธฐ๊ฐ€ REST API๋ณด๋‹ค ์ปค์งˆ ์ˆ˜ ์žˆ๋‹ค.
  2. HTTP ์บ์‹ฑ ์‚ฌ์šฉ ๋ถˆ๊ฐ€๋Šฅ
  3. ํŒŒ์ผ ์—…๋กœ๋“œ ๊ตฌํ˜„ ๋ฐฉ๋ฒ•์ด ์ •ํ•ด์ ธ์žˆ์ง€ ์•Š์•„ ์ง์ ‘ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค.

์ฐธ๊ณ  ์ž๋ฃŒ

GraphQL์˜ ๋‹จ์ ๊ณผ ๋Œ€์•ˆ

ํƒœ๊ทธ:

์นดํ…Œ๊ณ ๋ฆฌ:

์—…๋ฐ์ดํŠธ:

๋Œ“๊ธ€๋‚จ๊ธฐ๊ธฐ