Jieunny์ ๋ธ๋ก๊ทธ
S4) Unit 6. [API] GraphQL ๋ณธ๋ฌธ
๐ฃ GraphQL
๐ญ. GraphQL ์ด๋?
โ๏ธ Facebook์์ ์ฒ์์ผ๋ก ๊ฐ๋ฐํ๊ณ , ์คํ ์์ค๋ก ์ ๊ณต๋ ์ฟผ๋ฆฌ ์ธ์ด
โฐ Graph + Query Language
โฐ Query Language ์ค์์๋ Server API ๋ฅผ ํตํด ์ ๋ณด๋ฅผ ์ฃผ๊ณ ๋ฐ๊ธฐ ์ํด ์ฌ์ฉํ๋ Query Language
๐ฎ. ์ GraphQL ๋ฅผ ์ฌ์ฉํ ๊น?
โ๏ธ GraphQL์ REST API ๋ฐฉ์์ ๊ณ ์ ๋ ์์์ด ์๋ ํด๋ผ์ด์ธํธ ์์ฒญ์ ๋ฐ๋ผ ์ ์ฐํ๊ฒ ์์์ ๊ฐ์ ธ์ฌ ์ ์๋ค.
โฐ GraphQL์์๋ ๋ชจ๋ ๋ฐ์ดํฐ๊ฐ ๊ทธ๋ํ ํํ๋ก ์ฐ๊ฒฐ๋์ด ์๋ค๊ณ ์ ์ ํ๋ค.
โฐ ์ด๋ฅผ ํตํด GraphQL์ ํด๋ผ์ด์ธํธ ์์ฒญ์ ๋ฐ๋ผ ์ ์ฐํ๊ฒ ํธ๋ฆฌ ๊ตฌ์กฐ์ JSON ๋ฐ์ดํฐ๋ฅผ ์๋ต์ผ๋ก ์ ์กํ ์ ์๋ค.
๐ฏ. GraphQL๋ก ๊ทธ๋ํ ์ํ
โ๏ธ ๊ทธ๋ํ๋ก ํํํ๊ฒ ๋๋ฉด ์ฐ๋ฆฌ๊ฐ ๊ฐ์ง๊ณ ์๋ ๋ฐ์ดํฐ์ ์กฐ๊ฐ๋ค์ด๋ ๋ํ๋ด๊ณ ์ ํ๋ ์ํฐํฐ(์ฑ , ํน์ ์ ์) ๊ฐ์ ๊ด๊ณ๋ฅผ ๋ํ๋ผ ์ ์๋ค.
โฐ ์ํฐํฐ : ์ฌ๋ฌผ์ ๊ตฌ์กฐ๋ ์ํ, ๋์ ๋ฑ์ ๋ชจ๋ธ๋ก ํํํ๋ ๊ฒฝ์ฐ, ๊ทธ ๋ชจ๋ธ์ ๊ตฌ์ฑ์์
โฐ ๊ทธ๋ํ๋ฅผ ๊ทธ๋ฆด ์ ์๊ฒ ๋๋ค๋ฉด, GraphQL์ ์ฌ์ฉํด ํธ๋ฆฌ๋ฅผ ์ถ์ถํ ์ ์๋ค.
โฐ ๊ธฐ๋ณธ์ ์ผ๋ก ํธ๋ฆฌ๋ ๋ฐฉํฅ์ฑ์ ์กด์ฌํ๋ ์ฌ์ดํด์ ์กด์ฌํ์ง ์๋ ๋น์ํ ๊ทธ๋ํ => ๋์ผํ ๋ ธ๋๋ก ๋์์ฌ ์ ์๋ค.
โ๏ธ ๊ทธ๋ํ์์ ํธ๋ฆฌ ์ถ์ถํ๋ ๋ฐฉ๋ฒ
query {
์ฑ
(ISBN์ด "9780674430006") {
์ฑ
์ด๋ฆ
์ ์ {
์ด๋ฆ
}
}
}
// ์์ ๊ทธ๋ํ์์ ์คํํ ์ ์๋ ์ฟผ๋ฆฌ
// ์ ์ฟผ๋ฆฌ๋ก ์์ฒญ์ ๋ณด๋ด๋ฉด
{
์ฑ
: {
์ฑ
์ด๋ฆ : "GraphQL์ ์ด๋ ต์ง ์๋ค",
์ ์ : [
{ ์ด๋ฆ : "๊น์ฝ๋ฉ"},
{ ์ด๋ฆ : "๋ฐํด์ปค"},
]
}
}
// ์ด๋ ๊ฒ ์ฟผ๋ฆฌ๊ฐ ๋์์จ๋ค.
1. ISBN ๋ฒํธ๋ฅผ ์ฌ์ฉํด์ ์ ํํ '์ฑ ' ๋ ธ๋์์ ์์ํ๋ค.
2. GraphQL์ ์ค์ฒฉ๋ ๊ฐ ํ๋๋ก ํ์๋ ๊ฐ์ ์ ๋ฐ๋ผ ๊ทธ๋ํ๋ฅผ ํ์ํ๊ธฐ ์์ํ๋ค.
3. ์ฟผ๋ฆฌ ๋ด ์ค์ฒฉ๋ “์ฑ ์ด๋ฆ” ํ๋๋ฅผ ํตํด ์ฑ ์ ์ ๋ชฉ์ด ์๋ ๋ ธ๋๋ก ์ด๋ํ๋ค.
4. “์ ์”๋ก ๋ ์ด๋ธ์ด ์ง์ ๋ “์ฑ ”์ ๊ฐ์ ์ ๋ฐ๋ผ๊ฐ “์ ์” ๋ ธ๋๋ฅผ ๊ฐ์ ธ์ค๊ณ , ๊ฐ ์ ์์ “์ด๋ฆ"์ ์ป์ด์จ๋ค.
โฐ GraphQL์ ํธ๋ฆฌ ๊ตฌ์กฐ๋ก ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ๊ธฐ ์ํด ๊ทธ๋ํ๋ฅผ ํ์ํ๋ ์ฟผ๋ฆฌ ์ธ์ด
๐ฐ. GraphQL์ ํน์ง
1๏ธโฃ GraphQL์ HTTP๋ฅผ ํตํด API ์๋ฒ๋ก ์์ฒญ์ ๋ณด๋ด๊ณ ์๋ต์ ๋ฐ๋๋ค.
2๏ธโฃ ์๋ต์ ๋ฐ์ ์, ๋ฐ์ดํฐ ๊ฒฐ๊ณผ๋ฅผ JSON ํ์์ผ๋ก ๋ฐ๋๋ค.
3๏ธโฃ GraphQL์ ์๋ฒ ๊ฐ๋ฐ์๊ฐ ์์ฑํ ๊ฐ ํ๋์ ๋์ํ๋ resolver ํจ์๋ก ๊ฐ ํ๋์ ๋ฐ์ดํฐ๋ฅผ ์กฐํํ ์ ์๋ค.
4๏ธโฃ GraphQL์ GraphQL ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์กฐํ ๋์ schema๊ฐ ์ ํจํ์ง ๊ฒ์ฌํ๋ค.
๐ฃ GraphQL vs REST API
Q. ์ด๋ฏธ REST API๋ผ๋ ๋ฐฉ๋ฒ๋ก ์ด ์กด์ฌํ๊ณ ์์์๋ ๋ถ๊ตฌํ๊ณ ์ GraphQL์ด ํ์ํ์๊น?
๐ญ. REST API์ ํ๊ณ
1๏ธโฃ Overfetch : ํ์ ์๋ ๋ฐ์ดํฐ๊น์ง ์ ๊ณตํ๋ค.
2๏ธโฃ Underfetch: endpoint ๊ฐ ํ์ํ ์ ๋ณด๋ฅผ ์ถฉ๋ถํ ์ ๊ณตํ์ง ๋ชปํ๋ค.
โฐ ํด๋ผ์ด์ธํธ๋ ํ์ํ ์ ๋ณด๋ฅผ ๋ชจ๋ ํ๋ณดํ๊ธฐ ์ํ์ฌ ์ถ๊ฐ์ ์ธ ์์ฒญ์ ๋ณด๋ด์ผ ํ๋ค.3๏ธโฃ ํด๋ผ์ด์ธํธ ๊ตฌ์กฐ ๋ณ๊ฒฝ ์ ์๋ํฌ์ธํธ ๋ณ๊ฒฝ ๋๋ ๋ฐ์ดํฐ ์์ ์ด ํ์ํ๋ค.
โฐ REST API์์๋ ์์์ ํฌ๊ธฐ์ ํํ๋ฅผ ์๋ฒ์์ ๊ฒฐ์ ํ๊ธฐ ๋๋ฌธ์ ํด๋ผ์ด์ธํธ๊ฐ ์ง์ ๋ฐ์ดํฐ์ ํํ๋ฅผ ๊ฒฐ์ ํ ์ ์๋ค.
โฐ ๋ง์ฝ ํด๋ผ์ด์ธํธ์์ ํ์ํ ๋ฐ์ดํฐ์ ๋ด์ฉ์ด ๋ณํ ๊ฒฝ์ฐ ๋ค๋ฅธ endpoint๋ฅผ ํตํด ๋ณ๊ฒฝ๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ฑฐ๋ ์์ ํด์ผํ๋ค.
๐ฎ. REST API์ GraphQL์ ๋ค๋ฅธ์
1๏ธโฃ REST API๋ Resource์ ๋ํ ํํ ์ ์์ ๋ฐ์ดํฐ ์์ฒญ ๋ฐฉ๋ฒ์ด ์ฐ๊ฒฐ๋์ด ์์ง๋ง, GraphQL์์๋ Resource์ ๋ํ ํํ ์ ์์ ๋ฐ์ดํฐ ์์ฒญ์ด ์์ ํ ๋ถ๋ฆฌ๋์ด ์๋ค.
2๏ธโฃ REST API๋ Resource์ ํฌ๊ธฐ์ ํํ๋ฅผ ์๋ฒ์์ ๊ฒฐ์ ํ์ง๋ง, GraphQL์์๋ Resource์ ๋ํ ์ ๋ณด๋ง ์ ์ํ๊ณ , ํ์ํ ํฌ๊ธฐ์ ํํ๋ ํด๋ผ์ด์ธํธ ๋จ์์ ์์ฒญ ์ ๊ฒฐ์ ํ๋ค.
3๏ธโฃ REST API๋ URI๊ฐ Resource๋ฅผ ๋ํ๋ด๊ณ Method๊ฐ ์์ ์ ์ ํ์ ๋ํ๋ด์ง๋ง, GraphQL์์๋ GraphQL Schema๊ฐ Resource๋ฅผ ๋ํ๋ด๊ณ Query, Mutation ํ์ ์ด ์์ ์ ์ ํ์ ๋ํ๋ธ๋ค.
4๏ธโฃ REST API๋ ์ฌ๋ฌ Resource์ ์ ๊ทผํ๊ณ ์ ํ ๋ ์ฌ๋ฌ ๋ฒ์ ์์ฒญ์ด ํ์ํ์ง๋ง, GraphQL์์๋ ํ๋ฒ์ ์์ฒญ์์ ์ฌ๋ฌ Resource์ ์ ๊ทผํ ์ ์๋ค.
5๏ธโฃ REST API์์ ๊ฐ ์์ฒญ์ ํด๋น ์๋ํฌ์ธํธ์ ์ ์๋ ํธ๋ค๋ง ํจ์๋ฅผ ํธ์ถํ์ฌ ์์ ์ ์ฒ๋ฆฌํ์ง๋ง, GraphQL์์๋ ์์ฒญ ๋ฐ์ ๊ฐ ํ๋์ ๋ํ resolver๋ฅผ ํธ์ถํ์ฌ ์์ ์ ์ฒ๋ฆฌํ๋ค.
๐ฏ. GraphQL์ ์ฅ์
1๏ธโฃ ํ๋์ endpoint ์์ฒญ
โฐ /graphql์ด๋ผ๋ ํ๋์ endpoint ๋ก ์์ฒญ์ ๋ฐ๊ณ ๊ทธ ์์ฒญ์ ๋ฐ๋ผ query , mutation์ resolver ํจ์๋ก ์ ๋ฌํด์ ์์ฒญ์ ์๋ตํ๋ค.
โฐ ๋ชจ๋ ํด๋ผ์ด์ธํธ ์์ฒญ์ POST ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ค.
2๏ธโฃ No under & overfetching
โฐ ์ฌ๋ฌ ๊ฐ์ endpoint ์์ฒญ์ ํ ํ์์์ด ํ๋์ endpoint์์ ์ฟผ๋ฆฌ๋ฅผ ์ด์ฉํด ์ํ๋ ๋ฐ์ดํฐ๋ฅผ ์ ํํ๊ฒ API์ ์์ฒญํ๊ณ ์๋ต์ผ๋ก ๋ฐ์ ์ ์๋ค.
3๏ธโฃ ๊ฐ๋ ฅํ playground
โฐ graphql ์๋ฒ๋ฅผ ์คํํ๋ฉด playground๋ผ๋ GUI๋ฅผ ์ด์ฉํด resolver ์ schema ๋ฅผ ํ ๋์ ๋ณด๊ณ ํ ์คํธ ํ ์ ์๋ค.
4๏ธโฃ ํด๋ผ์ด์ธํธ ๊ตฌ์กฐ ๋ณ๊ฒฝ์๋ ์ง์ฅ์ด ์๋ค.
โฐ ํด๋ผ์ด์ธํธ ๊ตฌ์กฐ๊ฐ ๋ฐ๋์ด๋ ํ์ํ ๋ฐ์ดํฐ๋ฅผ ๊ฒฐ์ ํ๊ณ ๋ฐ๋ ์ฃผ์ฒด๊ฐ ํด๋ผ์ด์ธํธ์ด๊ธฐ ๋๋ฌธ์ ์๋ฒ์ ์ง์ฅ์ด ์๋ค
โฐ ํด๋ผ์ด์ธํธ์์๋ ๋ฌด์จ ๋ฐ์ดํฐ๊ฐ ํ์ํ ์ง์ ๋ํด์๋ง ์๊ตฌ์ฌํญ์ ์ฟผ๋ฆฌ๋ก ์์ฑํ๋ฉด ๋๋ค.
๐ฐ. GraphQL์ ๋จ์
1๏ธโฃ REST API์ ์น์ํ ๊ฐ๋ฐ์์ ๊ฒฝ์ฐ GraphQL๋ฅผ ํ์ตํ๋ ๋ฐ ์๊ฐ์ด ํ์ํ๋ค.
2๏ธโฃ ์บ์ฑ์ด REST๋ณด๋ค ํจ์ฌ ๋ณต์กํ๋ค.
โฐ HTTP์์ ๊ฐ ๋ฉ์๋์ ๋ฐ๋ผ ์บ์ฑ์ด ๊ตฌํ๋์ด ์์ง๋ง GraphQL์์ POST ๋ฉ์๋๋ง์ ์ด์ฉํด ์์ฒญ์ ๋ณด๋ด๊ธฐ ๋๋ฌธ์ ๊ฐ ๋ฉ์๋์ ๋ฐ๋ฅธ ์บ์ฑ์ ์ง์๋ฐ์ ์ ์๋ค.
โฐ ์ด๋ฅผ ๋ณด์ํ๊ธฐ ์ํด Apollo ์์ง์ ์บ์ฑ๊ณผ ์์ ์ฟผ๋ฆฌ ๋ฑ์ด ๋ฑ์ฅํ๋ค.
3๏ธโฃ ๊ณ ์ ๋ ์์ฒญ๊ณผ ์๋ต๋ง ํ์ํ ๊ฒฝ์ฐ์๋ Query ๋ก ์ธํด ์์ฒญ์ ํฌ๊ธฐ๊ฐ RESTful API ์ ๊ฒฝ์ฐ๋ณด๋ค ๋ ์ปค์ง๋ค.
๐ฃ GraphQL ๊ตฌ์กฐ
๐ญ. ์ฟผ๋ฆฌ(query, ๋ฐ์ดํฐ ์กฐํ)
โ๏ธ ํ๋(field)
{
hero {
name
}
}
// hero์ name์ ์ฟผ๋ฆฌ
{
"data": {
"hero": {
"name": "R2-D2"
}
}
}
// ์ฟผ๋ฆฌ๋ฅผ ์คํํ์ ๋์ ๊ฒฐ๊ณผ
---------------------------------------------------------------
{
hero {
name
# ์ด๋ฐ ์์ผ๋ก GraphQL ๋ด์์ ์ฃผ์๋ ์์ฑํ ์ ์์ต๋๋ค.
friends {
name
}
}
}
// ํ์ด๋ก์ ์ด๋ฆ๊ณผ ํ์ด๋ก์ ์น๊ตฌ ์ด๋ฆ์ ๊ฐ์ด ์ฟผ๋ฆฌ
{
"data": {
"hero": {
"name": "R2-D2",
"friends": [
{
"name": "Luke Skywalker"
},
{
"name": "Han Solo"
},
{
"name": "Leia Organa"
}
]
}
}
}
// ํ์ด๋ก์ ์ด๋ฆ๊ณผ ํ์ด๋ก์ ์น๊ตฌ์ ์ด๋ฆ์ด ์กฐํ๋์ด ๋์จ๋ค.
โฐ ํ๋์ name์ String ํ์ ์ ๋ฐํํ๋ค.
โฐ ์ฟผ๋ฆฌ์ ๊ฒฐ๊ณผ๊ฐ ์ ํํ๊ฒ ๊ฐ์ ๋ชจ์์ ํ๊ณ ์์์ ํ์ธํ ์ ์๋๋ฐ, ์ด ๋ถ๋ถ์ GraphQL์ ์์ด์ ํ์์ ์ด๋ค.
โฐ GraphQL์ ์๋ฒ์ ์์ฒญํ์ ๋ ์์ํ๋ ๋๋ก ๋๋ ค๋ฐ๊ณ , ์๋ฒ๋ GraphQL์ ํตํด ํด๋ผ์ด์ธํธ๊ฐ ์๊ตฌํ๋ ํ๋๋ฅผ ์ ํํ ์ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
โฐ ๋ ๋ฒ์งธ ์์์ฒ๋ผ ์ํ๋ ํ๋๋ฅผ ์ค์ฒฉํ์ฌ ์ฟผ๋ฆฌํ๋ ๊ฒ๋ ๊ฐ๋ฅํ๋ค.
โฐ friends ํ๋๋ ๋ฐฐ์ด์ ๋ฐํํ๋ค.
โฐ GraphQL ์ฟผ๋ฆฌ๋ ๊ด๋ จ ๊ฐ์ฒด ๋ฐ ํ๋๋ฅผ ์ํํ ์ ์๊ธฐ ๋๋ฌธ์ ๊ณ ์ ์ ์ธ REST API์์ ๊ทธ๋ฌ๋ฏ์ด ๋ค์ํ endpoint๋ฅผ ๋ง๋ค์ด ๊ฐ๊ธฐ ์์ฒญ์ ๋ณด๋ด๋ ๋์ ํด๋ผ์ด์ธํธ๊ฐ ํ๋์ ์์ฒญ์ ๋ณด๋์ผ๋ก์จ ๊ด๋ จ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ ์ ์๋ค.
โ๏ธ ์ ๋ฌ์ธ์(Arguments)
โฐ ํ๋์ ์ธ์๋ฅผ ์ ๋ฌํ๋ ๋ถ๋ถ์ ์ถ๊ฐํ๊ฒ ๋๋ฉด ์ฟผ๋ฆฌ์ ํ๋ ๋ฐ ์ค์ฒฉ๋ ๊ฐ์ฒด๋ค์ ์ ๋ฌํ์ฌ ์ํ๋ ๋ฐ์ดํฐ๋ง ๋ฐ์์ฌ ์ ์๋ค.
{
human(id: "1000") {
name
height
}
}
// id๊ฐ 1000์ธ human์ name๊ณผ height๋ฅผ ์ฟผ๋ฆฌ
{
"data": {
"human": {
"name": "Luke Skywalker",
"height": 1.72
}
}
}
// ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ
โฐ id๊ฐ 1000์ธ human์ ์ด๋ฆ๊ณผ ํค๋ฅผ ์ฟผ๋ฆฌํด ์ฌ ์ ์๋ค.
โฐ REST API๋ฅผ ์ด์ฉํ๋ค๋ฉด ?id=1000 ์ด๊ฑฐ๋ /1000(/:id)์ผ ๋์ ๊ฐ์ ๋ชฉ์ ์ผ๋ก ์ฟผ๋ฆฌํ ์ ์๋ค.
โ๏ธ ๋ณ๋ช (Aliases)
โฐ ํ๋ ์ด๋ฆ์ ์ค๋ณตํด์ ์ฌ์ฉํ ์ ์์ผ๋ฏ๋ก, ํ๋ ์ด๋ฆ์ ์ค๋ณต์ผ๋ก ์ฌ์ฉํด์ ์ฟผ๋ฆฌ๋ฅผ ํด์ผ ํ ๋๋ ๋ณ๋ช ์ ๋ถ์ฌ์ ์ฟผ๋ฆฌ ํด์ผํ๋ค.
{
hero(episode: EMPIRE) {
name
}
hero(episode: JEDI) {
name
}
}
// ์ค๋ณต ์ฟผ๋ฆฌ๋ ๋ถ๊ฐ๋ฅ
{
empireHero: hero(episode: EMPIRE) {
name
}
jediHero: hero(episode: JEDI) {
name
}
}
// ์์ ์์๋ณผ ์ ์๋ ๋ณ๋ช
์ ๋ถ์ฌ์ฃผ๋ฉด ์ฟผ๋ฆฌํ ์ ์๋ค.
{
"data": {
"empireHero": {
"name": "Luke Skywalker"
},
"jediHero": {
"name": "R2-D2"
}
}
}
// ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ
โฐ ๋ค๋ฅธ ์ด๋ฆ์ผ๋ก ๋ณ๋ช ์ ์ง์ ํ๋ฉด ํ ๋ฒ์ ์์ฒญ์ผ๋ก ๋ ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ๋ชจ๋ ์ป์ ์ ์๋ค.
โ๏ธ ์คํผ๋ ์ด์ ๋ค์(Operation name)
โฐ ์ ์์๋ค์์๋ ์ฟผ๋ฆฌ์ ์ฟผ๋ฆฌ ๋ค์์ ๋ชจ๋ ์๋ตํ๋ ์ถ์ฝํ ๊ตฌ๋ฌธ์ ์ฌ์ฉํ์ง๋ง, ์ค์ ์ฑ์์๋ ์ฝ๋๋ฅผ ๋ชจํธํ์ง ์๊ฒ ์์ฑํ๋ ๊ฒ์ด ์ค์ํ๋ค.
query HeroNameAndFriends {
hero {
name
friends {
name
}
}
}
// query keyword์ query name์ ์์ฑํ๋ค.
{
"data": {
"hero": {
"name": "R2-D2",
"friends": [
{
"name": "Luke Skywalker"
},
{
"name": "Han Solo"
},
{
"name": "Leia Organa"
}
]
}
}
}
โฐ ์ ์์์ query๋ ์คํผ๋ ์ด์ ํ์ ์ด๋ฉฐ, ์คํผ๋ ์ด์ ํ์ ์๋ query ๋ฟ๋ง ์๋๋ผ mutation, subscription, describes ๋ฑ์ด ์๋ค.
โฐ ์ฟผ๋ฆฌ๋ฅผ ์ฝ์์ผ๋ก ์์ฑํ์ง ์๋ ํ ์ด๋ฐ ์คํผ๋ ์ด์ ํ์ ์ ๋ฐ๋์ ํ์ํ๋ค.
โฐ ์คํผ๋ ์ด์ ๋ค์์ ์์ฑํ ๋๋ ์คํผ๋ ์ด์ ํ์ ์ ๋ง๋ ์ด๋ฆ์ผ๋ก ์์ฑํ๋ ๊ฒ์ด ์ข๋ค.
โ๏ธ ๋ณ์(Variables)
โฐ ์ ์์๋ค์์๋ ๊ณ ์ ๋ ์ธ์๋ฅผ ๋ฐ์ ์ฟผ๋ฆฌํ์ง๋ง, ์ค์ ์ฑ์ ์ฌ์ฉํ ๋๋ ๊ณ ์ ๋ ์ธ์๋ฅผ ๋ฐ๋ ๊ฒ๋ณด๋ค๋ ๋์ ์ผ๋ก ์ธ์๋ฅผ ๋ฐ์ ์ฟผ๋ฆฌํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง๋ค.
โฐ ๋ณ์๋ ๊ทธ๋ฐ ์ธ์๋ค์ ๋์ ์ผ๋ก ๋ฐ๊ณ ์ถ์ ๋ ์ฌ์ฉํ๋ค.
query HeroNameAndFriends($episode: Episode) {
hero(episode: $episode) {
name
friends {
name
}
}
}
โฐ ์คํผ๋ ์ด์ ๋ค์ ์์ ๋ณ์๋ฅผ $๋ณ์ ์ด๋ฆ: ํ์ ํํ ๋ก ์ ์ํ๋ค.
๐ฎ. ๋ฎคํ ์ด์ (mutation, ๋ฐ์ดํฐ ์์ )
โ๏ธ GraphQL์ ์๋ฒ์ธก ๋ฐ์ดํฐ๋ฅผ ์์ ํ๊ธฐ๋ ํ๋ค.
โฐ mutation์ด๋ผ๋ ํค์๋๋ฅผ ์ฌ์ฉํ์ฌ ์๋ฒ ์ธก ๋ฐ์ดํฐ๋ฅผ ์์ ํ๋ค.
mutation CreateReviewForEpisode($ep: Episode!, $review: ReviewInput!) {
createReview(episode: $ep, review: $review) {
stars
commentary
}
}
๐ฏ. ์คํค๋ง/ํ์ (Schema/Type)
โ๏ธ ์คํค๋ง์ ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ๊ตฌ์ฑ ์์๋ ์๋น์ค์์ ๊ฐ์ ธ์ฌ ์ ์๋ ๊ฐ์ฒด์ ์ข ๋ฅ, ๊ทธ๋ฆฌ๊ณ ํฌํจํ๋ ํ๋๋ฅผ ๋ํ๋ด๋ ๊ฐ์ฒด ์ ํ์ด๋ค.
type Character {
name: String!
appearsIn: [Episode!]!
// !๊ฐ ๋ถ๋๋ค๋ฉด ์ด ํ๋๋ nullableํ์ง ์๊ณ ๋ฐ๋์ ๊ฐ์ด ๋ค์ด์จ๋ค๋ ์๋ฏธ
// ์ด๊ฒ์ ๋ถ์ฌ ์ฟผ๋ฆฌํ๋ค๋ฉด ๋ฐ๋์ ๊ฐ์ ๋ฐ์ ์ ์์ ๊ฒ์ด๋ผ๊ณ ์์ ํ ์ ์๋ค.
// ์ฌ๊ธฐ์ ์ด ๋ฐฐ์ด์ null ๊ฐ์ ํ์ฉํ์ง ์์ผ๋ฏ๋ก ํญ์ 0๊ฐ ์ด์์ ์์๋ฅผ ํฌํจํ ๋ฐฐ์ด์ ๊ธฐ๋ํ ์ ์๋ค.
}
โฐ Character๋ GraphQL ๊ฐ์ฒด ํ์ (ํ๋๊ฐ ์๋ ํ์ )์ด๋ค.
ใด ์คํค๋ง์ ์๋ ๋๋ถ๋ถ์ ํ์ ์ ๊ฐ์ฒด ํ์
โฐ name ๊ณผ appearIn ์ Character ํ์ ์ ํ๋์ด๋ค.
ใด name ๊ณผ appearIn ์ GraphQL ์ฟผ๋ฆฌ์ Character ํ์ ์ด๋์๋ ์ฌ์ฉํ ์ ์๋ ํ๋
โฐ String์ ๋ด์ฅ๋ ์ค์นผ๋ผ ํ์ ์ค ํ๋์ด๋ค.
ใด ๋จ์ผ ์ค์นผ๋ผ ๊ฐ์ฒด๋ก ํ์ธ๋๋ ์ ํ์ด๋ฉฐ ์ฟผ๋ฆฌ์์ ํ์ ์ ํ์ ๊ฐ์ง ์ ์๋ค.
ใด ์ค์นผ๋ผ ํ์ ์๋ ID, Int๋ ์๋ค.
๐ฐ. ๋ฆฌ์กธ๋ฒ(Resolver)
โ๏ธ ์์ฒญ์ ๋ํ ์๋ต์ ๊ฒฐ์ ํด์ฃผ๋ ํจ์๋ก, GraphQL์ ์ฌ๋ฌ ๊ฐ์ง ํ์ ์ค Query, Mutation, Subscription๊ณผ ๊ฐ์ ํ์ ์ ์ค์ ์ผํ๋ ๋ฐฉ์(๋ก์ง)์ ์์ฑํ๋ค.
const db = require("./../db")
const resolvers = {
Query: { // **Query :** ์ ์ฅ๋ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ (REST ์ GET ๊ณผ ๋น์ทํฉ๋๋ค.)
getUser: async (_, { email, pw }) => {
db.findOne({
where: { email, pw }
}) ... // ์ค์ ๋๋น์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๋ก์ง์ ์์ฑํฉ๋๋ค.
...
}
},
Mutation: { // **Mutation :** ์ ์ฅ๋ ๋ฐ์ดํฐ ์์ ํ๊ธฐ ( Create , Update , Delete )
createUser: async (_, { email, pw, name }) => {
...
}
}
Subscription: { // **Subscription :** ์ค์๊ฐ ์
๋ฐ์ดํธ
newUser: async () => {
...
}
}
};
โฐ GraphQL์์๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๊ตฌ์ฒด์ ์ธ ๊ณผ์ ์ ์ง์ ๊ตฌํํด์ผ ํ๋ฏ๋ก ์ด์ ๊ฐ์ ์์ ์ Resolver๊ฐ ๋ด๋นํ๋ค.
'CodeStates > learning contents' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
S4) Unit 8. [์ต์ ํ]์ต์ ํ ๊ธฐ๋ฒ (0) | 2023.03.30 |
---|---|
S4) Unit 7. [Testing] TDD (0) | 2023.03.29 |
S4) Unit 5. [์ปดํจํฐ ๊ณตํ] ์ด์์ฒด์ & ๋ฌธ์์ด๊ณผ ๊ทธ๋ํฝ & ๊ฐ๋น์ง ์ปฌ๋ ์ (1) | 2023.03.27 |
S4) Unit 5. [์ปดํจํฐ ๊ณตํ] ์ปดํจํฐ ๊ตฌ์กฐ (2) | 2023.03.27 |
S4) Unit 4. [React] React์ ๊ธฐ๋ฅ (0) | 2023.03.23 |