ํ๋ก ํธ์๋ ๊ฐ๋ฐ์๋ฅผ ์ํ GraphQL ์ ๋ฌธ
- #GraphQL
- #REST
- #Frontend
- #Apollo
๋ค์ด๊ฐ๋ฉฐ
์๋ ํ์ธ์. ๋ ธ๋จธ์ค ํ๋ก ํธ์๋ ํ์ ํ์๋น์ ๋๋ค.
ํ๋ก ํธ์๋ ๊ฐ๋ฐ์๋ก์ ๋ค์ํ ์์ ์ ์ํํ์ง๋ง, ๊ทธ์ค์์๋ ์๋ฒ์์ ํต์ ์ ๋งค์ฐ ์ค์ํ ์ ๋ฌด์ ๋๋ค. ํ์ฌ ์ ํฌ ๋ ธ๋จธ์ค์์๋ ์ผ๋ถ ์๋น์ค์ GraphQL์ ๋์ ํ๋ ๊ฒ์ ๊ฒํ ์ค์ ๋๋ค. ์ด์ ๋ฐ๋ง์ถ์ด GraphQL์ ๋ํด ๋น ๋ฅด๊ฒ ์์๋ณด๊ณ ์ ํฉ๋๋ค.
GraphQL์ด๋?
GraphQL์ Facebook์์ ๊ฐ๋ฐํ ์คํ ์์ค ๋ฐ์ดํฐ ์ฟผ๋ฆฌ ์ธ์ด์ ๋๋ค. ํด๋ผ์ด์ธํธ๊ฐ ํ์ํ ๋ฐ์ดํฐ๋ฅผ ์ ํํ๊ฒ ์์ฒญํ ์ ์๋๋ก ํ์ฌ ๋คํธ์ํฌ ํจ์จ์ฑ์ ๊ทน๋ํํ๊ณ , ๋จ์ผ ์๋ํฌ์ธํธ๋ฅผ ํตํด ๋ค์ํ ๋ฐ์ดํฐ ์์ฒญ์ ์ฒ๋ฆฌํ ์ ์๋ ์ ์ฐ์ฑ์ ์ ๊ณตํฉ๋๋ค. ์ด๋ฅผ ํตํด ํ๋ก ํธ์๋ ๊ฐ๋ฐ์๋ค์ ๋ณด๋ค ๊ฐํธํ๊ณ ํจ์จ์ ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๊ด๋ฆฌํ ์ ์์ต๋๋ค.
GraphQL ์ฟผ๋ฆฌ ์ธ์ด๋?
GraphQL ์ฟผ๋ฆฌ ์ธ์ด๋ ํด๋ผ์ด์ธํธ๊ฐ ํ์ํ ๋ฐ์ดํฐ๋ฅผ ๊ตฌ์กฐํ๋ ๋ฐฉ์์ผ๋ก ์์ฒญํ ์ ์๋๋ก ํฉ๋๋ค. ์ด๋ ํด๋ผ์ด์ธํธ๊ฐ ์๋ฒ๋ก๋ถํฐ ์ ํํ ์ด๋ค ๋ฐ์ดํฐ๋ฅผ ํ์๋ก ํ๋์ง ๋ช ์ํ ์ ์์ด, ๋ถํ์ํ ๋ฐ์ดํฐ ์ ์ก์ ์ค์ด๊ณ ์๋ต ์๊ฐ์ ์ต์ ํํ ์ ์์ต๋๋ค.
๊ฐ๋จํ ์์
์๋ฅผ ๋ค์ด, ์ฌ์ฉ์์ ์ด๋ฆ๊ณผ ์ด๋ฉ์ผ์ ์์ฒญํ๋ GraphQL ์ฟผ๋ฆฌ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
query {
user(id: 1) {
name
email
}
}
์ ์ฟผ๋ฆฌ๋ user
์ํฐํฐ์์ id
๊ฐ 1์ธ ์ฌ์ฉ์์ name
๊ณผ email
ํ๋๋ฅผ ์์ฒญํฉ๋๋ค. ์๋ฒ๋ ์ด ์์ฒญ์ ๋ฐ๋ผ ์ ํํ ํด๋น ํ๋๋ง ํฌํจ๋ ๋ฐ์ดํฐ๋ฅผ ๋ฐํํฉ๋๋ค.
์๋ต ์์
์๋ฒ๋ ํด๋ผ์ด์ธํธ์ ์์ฒญ์ ๋ฐ๋ผ JSON ํ์์ ๋ฐ์ดํฐ๋ฅผ ๋ฐํํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ์์ ์ฟผ๋ฆฌ์ ๋ํ ์๋ต์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
{
"data": {
"user": {
"name": "Luke Skywalker",
"email": "luke@rebellion.com"
}
}
}
์ด ์๋ต์ ํด๋ผ์ด์ธํธ๊ฐ ์์ฒญํ ๋ฐ์ดํฐ ๊ตฌ์กฐ์ ๋ง์ถ์ด ๋ฐํ๋ฉ๋๋ค. data
๊ฐ์ฒด ๋ด์ user
๊ฐ์ฒด๊ฐ ํฌํจ๋์ด ์์ผ๋ฉฐ, ์์ฒญํ name
๊ณผ email
ํ๋๊ฐ ์ ๊ณต๋ฉ๋๋ค. ์ด๋ฅผ ํตํด ํด๋ผ์ด์ธํธ๋ ํ์ํ ๋ฐ์ดํฐ๋ง ์ ํํ ๋ฐ์๋ณผ ์ ์์ต๋๋ค.
REST API์์ ์ฐจ์ด์
GraphQL๊ณผ REST API๋ ๋ชจ๋ ์๋ฒ์ ํด๋ผ์ด์ธํธ ๊ฐ์ ๋ฐ์ดํฐ ํต์ ์ ์ํด ์ฌ์ฉ๋์ง๋ง, ๋ช ๊ฐ์ง ์ค์ํ ์ฐจ์ด์ ์ด ์์ต๋๋ค:
1. ๋ฐ์ดํฐ ์์ฒญ ๋ฐฉ์
- REST API: ๊ฐ ๋ฆฌ์์ค์ ๋ํด ๊ณ ์ ํ URL์ ๊ฐ์ง๊ณ ์์ผ๋ฉฐ, ํน์ ์๋ํฌ์ธํธ์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ต๋๋ค. ์๋ฅผ ๋ค์ด,
/users
์๋ํฌ์ธํธ๋ ์ฌ์ฉ์ ๋ฐ์ดํฐ๋ฅผ ๋ฐํํ๊ณ ,/posts
์๋ํฌ์ธํธ๋ ๊ฒ์๋ฌผ ๋ฐ์ดํฐ๋ฅผ ๋ฐํํฉ๋๋ค. - GraphQL: ๋จ์ผ ์๋ํฌ์ธํธ(
/graphql
)๋ฅผ ํตํด ํด๋ผ์ด์ธํธ๊ฐ ํ์ํ ๋ฐ์ดํฐ๋ฅผ ์ฟผ๋ฆฌํฉ๋๋ค. ํด๋ผ์ด์ธํธ๋ ์์ฒญ ์ ํ์ํ ํ๋๋ง ๋ช ์ํ์ฌ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค.
2. ์ค๋ฒ ํ์นญ ๋ฐ ์ธ๋ ํ์นญ
- REST API: ํน์ ์๋ํฌ์ธํธ์์ ๋ถํ์ํ ๋ฐ์ดํฐ๋ฅผ ํฌํจํ ์ค๋ฒ ํ์นญ(over-fetching)์ด๋ ํ์ํ ๋ฐ์ดํฐ๊ฐ ๋ถ์กฑํ ์ธ๋ ํ์นญ(under-fetching)์ด ๋ฐ์ํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด,
/users
์๋ํฌ์ธํธ๊ฐ ๋ชจ๋ ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ๋ฐํํ ๋, ํด๋ผ์ด์ธํธ๋ ํน์ ์ฌ์ฉ์ ํ๋๋ง ํ์๋ก ํ๋๋ผ๋ ์ ์ฒด ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ผ ํฉ๋๋ค. - GraphQL: ํด๋ผ์ด์ธํธ๊ฐ ํ์ํ ๋ฐ์ดํฐ๋ง ์์ฒญํ ์ ์์ด ์ค๋ฒ ํ์นญ๊ณผ ์ธ๋ ํ์นญ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ์ฌ์ฉ์ ์ด๋ฆ๊ณผ ์ด๋ฉ์ผ๋ง ํ์ํ ๊ฒฝ์ฐ ํด๋น ํ๋๋ง ์์ฒญํ ์ ์์ต๋๋ค.
3. ๋ฒ์ ๊ด๋ฆฌ
- REST API: ์๋ํฌ์ธํธ ๋ฒ์ ๊ด๋ฆฌ๊ฐ ํ์ํฉ๋๋ค. ์๋ก์ด ๊ธฐ๋ฅ์ด๋ ๋ฐ์ดํฐ ๊ตฌ์กฐ ๋ณ๊ฒฝ ์,
/v1/users
,/v2/users
์ ๊ฐ์ ์๋ํฌ์ธํธ ๋ฒ์ ๊ด๋ฆฌ๊ฐ ํ์ํฉ๋๋ค. - GraphQL: ๋ฒ์ ๊ด๋ฆฌ๊ฐ ํ์ ์์ต๋๋ค. ํด๋ผ์ด์ธํธ๊ฐ ์์ฒญํ๋ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ์ ์ํ ์ ์์ผ๋ฏ๋ก, ์๋ฒ ์ธก์์ ๋ฐ์ดํฐ ๊ตฌ์กฐ ๋ณ๊ฒฝ์ด ๋ฐ์ํ๋๋ผ๋ ํด๋ผ์ด์ธํธ๋ ์ํฅ์ ๋ฐ์ง ์์ต๋๋ค.
4. ๋คํธ์ํฌ ์์ฒญ ์
- REST API: ์ฌ๋ฌ ์๋ํฌ์ธํธ์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์์ผ ํ๋ ๊ฒฝ์ฐ, ์ฌ๋ฌ ๋ฒ์ ๋คํธ์ํฌ ์์ฒญ์ด ํ์ํฉ๋๋ค.
- GraphQL: ๋จ์ผ ์ฟผ๋ฆฌ๋ก ์ฌ๋ฌ ๋ฆฌ์์ค๋ฅผ ๋์์ ์์ฒญํ ์ ์์ด ๋คํธ์ํฌ ์์ฒญ ์๋ฅผ ์ค์ผ ์ ์์ต๋๋ค.
REST API์ GraphQL์ ์ฐจ์ด์ : Star Wars API ์์
REST API์ GraphQL์ ๋น๊ตํ๊ธฐ ์ํด Star Wars API(SWAPI)๋ฅผ ์ฌ์ฉํ ์์๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค. SWAPI๋ Star Wars ๋ฐ์ดํฐ์ ์ ๊ทผํ ์ ์๋ API์ ๋๋ค. ์ฌ๊ธฐ์์๋ REST์ GraphQL์ ํตํด ์ํ์ ๋ฑ์ฅ์ธ๋ฌผ์ ์์ฒญํ๋ ์์๋ฅผ ํตํด ๋ ์ ๊ทผ ๋ฐฉ์์ ์ฐจ์ด์ ์ ์ค๋ช ํฉ๋๋ค.
REST API ์์
REST API๋ฅผ ์ฌ์ฉํ์ฌ ์ํ์ ๊ด๋ จ๋ ๋ฑ์ฅ์ธ๋ฌผ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ค๋ฉด ๋ ๋ฒ์ ์์ฒญ์ด ํ์ํฉ๋๋ค.
1. ์ํ ๋ชฉ๋ก ๊ฐ์ ธ์ค๊ธฐ
GET https://swapi.dev/api/films
์๋ต ์์:
{
"count": 6,
"results": [
{
"title": "A New Hope",
"episode_id": 4,
"characters": [
"https://swapi.dev/api/people/1/",
"https://swapi.dev/api/people/2/"
]
},
...
]
}
2. ์ํ์ ๋ฑ์ฅํ๋ ํน์ ์ธ๋ฌผ ์ ๋ณด ๊ฐ์ ธ์ค๊ธฐ
GET https://swapi.dev/api/people/1
์๋ต ์์:
{
"name": "Luke Skywalker",
"height": "172",
"mass": "77",
"hair_color": "blond",
"skin_color": "fair",
"eye_color": "blue",
"birth_year": "19BBY",
"gender": "male"
}
์ด์ ๊ฐ์ ๋ฐฉ์์ผ๋ก ๊ฐ ๋ฑ์ฅ์ธ๋ฌผ์ ๋ํด ๋ณ๋์ ์์ฒญ์ด ํ์ํฉ๋๋ค.
GraphQL ์์
GraphQL์ ์ฌ์ฉํ๋ฉด ๋จ์ผ ์ฟผ๋ฆฌ๋ก ์ํ์ ๊ด๋ จ๋ ๋ฑ์ฅ์ธ๋ฌผ ๋ฐ์ดํฐ๋ฅผ ๋์์ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค.
1. ๋จ์ผ ์ฟผ๋ฆฌ๋ก ์ํ์ ๋ฑ์ฅ์ธ๋ฌผ ๋ฐ์ดํฐ ์์ฒญ
{
allFilms {
films {
title
episodeID
characterConnection {
characters {
name
height
mass
skinColor
}
}
}
}
}
์๋ต ์์:
{
"data": {
"allFilms": {
"films": [
{
"title": "A New Hope",
"episodeID": 4,
"characterConnection": {
"characters": [
{
"name": "Luke Skywalker",
"height": "172",
"mass": "77",
"skinColor": "fair"
},
...
]
}
},
...
]
}
}
}
ํ๋ก ํธ์๋ ์ ์ฉํ๊ธฐ
GraphQL์ ํ๋ก ํธ์๋ ํ๋ก์ ํธ์ ๋์ ํ๋ ๊ณผ์ ์ ๋น๊ต์ ๊ฐ๋จํฉ๋๋ค. React๋ฅผ ์์๋ก ์ค๋ช ํ๊ฒ ์ต๋๋ค.
1. Apollo Client ์ค์น ๋ฐ ์ค์
GraphQL ํด๋ผ์ด์ธํธ๋ก๋ Apollo Client๊ฐ ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉ๋ฉ๋๋ค. Apollo Client๋ฅผ ์ฌ์ฉํ๋ฉด GraphQL ์๋ฒ์ ์ฝ๊ฒ ํต์ ํ ์ ์์ต๋๋ค.
์ค์น
๋จผ์ , ํ๋ก์ ํธ์ ํ์ํ ํจํค์ง๋ฅผ ์ค์นํฉ๋๋ค.
npm install @apollo/client graphql
์ค์
ํ๋ก์ ํธ์ ์ต์์ ์ปดํฌ๋ํธ์์ Apollo Client๋ฅผ ์ค์ ํฉ๋๋ค. Apollo Client๋ฅผ ์ค์ ํ๊ณ ์ด๋ฅผ ApolloProvider
๋ก ๊ฐ์ธ์ ์ ํ๋ฆฌ์ผ์ด์
์ ์ฒด์์ GraphQL ์์ฒญ์ ์ฒ๋ฆฌํ ์ ์๋๋ก ํฉ๋๋ค.
import React from 'react';
import { ApolloClient, InMemoryCache, ApolloProvider } from '@apollo/client';
const client = new ApolloClient({
uri: 'https://your-graphql-endpoint.com/graphql', // GraphQL ์๋ฒ์ URI๋ฅผ ์ง์ ํฉ๋๋ค.
cache: new InMemoryCache()
});
function App() {
return (
<ApolloProvider client={client}>
<YourComponent />
</ApolloProvider>
);
}
export default App;
2. GraphQL ์ฟผ๋ฆฌ ์์ฑ ๋ฐ ๋ฐ์ดํฐ ์์ฒญ
์ฟผ๋ฆฌ๋ฅผ ์์ฑํ๊ณ ๋ฐ์ดํฐ๋ฅผ ์์ฒญํ๋ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
์ฟผ๋ฆฌ ์์ฑ
GraphQL ์ฟผ๋ฆฌ๋ฅผ ์์ฑํฉ๋๋ค. gql
ํ๊ทธ๋ฅผ ์ฌ์ฉํ์ฌ ์ฟผ๋ฆฌ๋ฅผ ์ ์ํฉ๋๋ค.
import { gql } from '@apollo/client';
const GET_USER = gql`
query GetUser($id: ID!) {
user(id: $id) {
name
email
}
}
`;
๋ฐ์ดํฐ ์์ฒญ
React ์ปดํฌ๋ํธ์์ useQuery
ํ
์ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์์ฒญํฉ๋๋ค. useQuery
ํ
์ ์ฟผ๋ฆฌ์ ์ฟผ๋ฆฌ ๋ณ์(์ต์
)๋ฅผ ์ธ์๋ก ๋ฐ์ ๋ฐ์ดํฐ๋ฅผ ์์ฒญํฉ๋๋ค.
import React from 'react';
import { useQuery } from '@apollo/client';
import { GET_USER } from './queries';
function UserComponent({ userId }) {
const { loading, error, data } = useQuery(GET_USER, {
variables: { id: userId }
});
if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {error.message}</p>;
return (
<div>
<h1>{data.user.name}</h1>
<p>{data.user.email}</p>
</div>
);
}
export default UserComponent;
useQuery
ํ
์ loading
, error
, data
๋ฅผ ๋ฐํํ๋ฉฐ, ์ด๋ฅผ ํตํด ๋ก๋ฉ ์ํ, ์๋ฌ ์ํ, ๊ทธ๋ฆฌ๊ณ ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ฒ ๊ด๋ฆฌํ ์ ์์ต๋๋ค.
3. GraphQL์ ํ์ฉํ ๊ณ ๊ธ ๊ธฐ๋ฅ
GraphQL์ ํ์ฉํ ๊ณ ๊ธ ๊ธฐ๋ฅ์๋ ๋ฎคํ ์ด์ , ์บ์ฑ, ์๋ธ์คํฌ๋ฆฝ์ ์ด ํฌํจ๋ฉ๋๋ค. ์ด๋ฅผ ํตํด ๋ฐ์ดํฐ ๋ณ๊ฒฝ, ์ฑ๋ฅ ์ต์ ํ, ์ค์๊ฐ ์ ๋ฐ์ดํธ๋ฅผ ์ฝ๊ฒ ๊ตฌํํ ์ ์์ต๋๋ค.
๋ฎคํ ์ด์ (Mutation)
๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ๋ ์์ฒญ(์: ์์ฑ, ์์ , ์ญ์ )์ useMutation
ํ
์ ์ฌ์ฉํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ์๋ก์ด ์ฌ์ฉ์๋ฅผ ์์ฑํ๋ ๋ฎคํ
์ด์
์ ๋ค์๊ณผ ๊ฐ์ด ์์ฑํ ์ ์์ต๋๋ค.
import { gql, useMutation } from '@apollo/client';
const CREATE_USER = gql`
mutation CreateUser($name: String!, $email: String!) {
createUser(name: $name, email: $email) {
id
name
email
}
}
`;
function CreateUserComponent() {
let inputName, inputEmail;
const [createUser, { data }] = useMutation(CREATE_USER);
return (
<div>
<form
onSubmit={e => {
e.preventDefault();
createUser({ variables: { name: inputName.value, email: inputEmail.value } });
inputName.value = '';
inputEmail.value = '';
}}
>
<input
ref={node => {
inputName = node;
}}
type="text"
placeholder="Name"
/>
<input
ref={node => {
inputEmail = node;
}}
type="email"
placeholder="Email"
/>
<button type="submit">Create User</button>
</form>
</div>
);
}
export default CreateUserComponent;
์บ์ฑ
Apollo Client๋ InMemoryCache
๋ฅผ ์ฌ์ฉํ์ฌ ์์ฒญ๋ ๋ฐ์ดํฐ๋ฅผ ์บ์ฑํฉ๋๋ค. ์ด๋ฅผ ํตํด ๋์ผํ ๋ฐ์ดํฐ๋ฅผ ์ฌ๋ฌ ๋ฒ ์์ฒญํ๋ ๊ฒ์ ๋ฐฉ์งํ๊ณ ์ ํ๋ฆฌ์ผ์ด์
์ ์ฑ๋ฅ์ ํฅ์์ํฌ ์ ์์ต๋๋ค.
์๋ธ์คํฌ๋ฆฝ์ (Subscription)
์ค์๊ฐ ๋ฐ์ดํฐ ์
๋ฐ์ดํธ๊ฐ ํ์ํ ๊ฒฝ์ฐ useSubscription
ํ
์ ์ฌ์ฉํ์ฌ GraphQL ์๋ธ์คํฌ๋ฆฝ์
์ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด ์๋ฒ๋ก๋ถํฐ ์ค์๊ฐ ์
๋ฐ์ดํธ๋ฅผ ๋ฐ์ ์ ์์ต๋๋ค.
import { gql, useSubscription } from '@apollo/client';
const USER_ADDED = gql`
subscription OnUserAdded {
userAdded {
id
name
email
}
}
`;
function NewUsersComponent() {
const { data, loading } = useSubscription(USER_ADDED);
if (loading) return <p>Loading...</p>;
return (
<div>
<p>New user added:</p>
<p>Name: {data.userAdded.name}</p>
<p>Email: {data.userAdded.email}</p>
</div>
);
}
export default NewUsersComponent;
๊ฒฐ๋ก
GraphQL ํ์ต์ ํ๋ฉด์ GraphQL์ ํ๋ก ํธ์๋ ์ ์ฅ์์ ๊ฐ๋ฐํ๊ธฐ ํธํ ํต์ ๋ฐฉ์์ด๋ผ๊ณ ๋๊ปด์ก์ต๋๋ค. ์์ง ํ๋ก๋์ ๋ ๋ฒจ์์ ์ฌ์ฉํด๋ณด์ง ๋ชปํ์ง๋ง, ์์ผ๋ก ํ์ฉํ๊ฒ ๋๋ ๊ฒ์ ๊ธฐ๋๊ฐ์ด ํฝ๋๋ค.
GraphQL์ ์ฅ์ ๊ณผ ๋จ์ ์ ์ดํด๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
์ฅ์
์ ์ฐํ ๋ฐ์ดํฐ ์์ฒญ: GraphQL์ ํ์ํ ๋ฐ์ดํฐ๋ง ์์ฒญํ ์ ์์ด ์๋ต ์ฌ์ด์ฆ๋ฅผ ์ต์ํํ๊ณ , ํ๋ก ํธ์๋์ ๋ฐฑ์๋ ๊ฐ์ ์ปคํ๋ง์ ์ค์ ๋๋ค.
๋จ์ผ ์๋ํฌ์ธํธ ์ฌ์ฉ: GraphQL์ ๋จ์ผ ์๋ํฌ์ธํธ๋ก ๋ค์ํ ๋ฐ์ดํฐ๋ฅผ ์์ฒญํ ์ ์์ด ์ฌ๋ฌ API ์๋ํฌ์ธํธ๋ฅผ ๊ด๋ฆฌํ ํ์๊ฐ ์์ต๋๋ค.
๋จ์
ํ์ต ๊ณก์ : GraphQL์ ๊ฐ๋ ๊ณผ ์ฌ์ฉ๋ฒ์ ๋ฐฐ์ฐ๋ ๋ฐ ์๊ฐ์ด ํ์ํฉ๋๋ค. ํนํ, ๊ธฐ์กด REST API์ ์ต์ํ ๊ฐ๋ฐ์์๊ฒ๋ ์๋ก์ด ํจ๋ฌ๋ค์์ ์ ์ํ๋ ๊ณผ์ ์ด ํ์ํฉ๋๋ค.
๋ณต์ก์ฑ ์ฆ๊ฐ: ๊ฐ๋จํ ์์ฒญ์ ๊ฒฝ์ฐ์๋ ์ฟผ๋ฆฌ์ ๋ฎคํ ์ด์ ์ ์์ฑํด์ผ ํ๋ฏ๋ก ์ด๊ธฐ ์ค์ ๊ณผ ๊ตฌํ์ ์๊ฐ์ด ๋ ๊ฑธ๋ฆด ์ ์์ต๋๋ค.
์ฐธ๊ณ ์๋ฃ
์งง์ ๊ธ์ ๋ง์ ๋ด์ฉ์ ๋ด์ง ๋ชปํ์ต๋๋ค. GraphQL ์ ๋ํด์ ๋ ์๊ณ ์ถ๋ค๋ฉด ์๋ ์๋ฃ๋ค์ ์ฐธ๊ณ ํด์ฃผ์ธ์.