(์ถ์ฒ: https://maggieappleton.com/graphql)
{
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"
}
]
}
}
}
[์ฝ๋] ํ์ด๋ก์ ์ด๋ฆ๊ณผ ํ์ด๋ก์ ์น๊ตฌ์ ์ด๋ฆ์ด ์กฐํ๋์ด ๋์ด
ํ๋์ ์ธ์๋ฅผ ์ ๋ฌํ๋ ๋ถ๋ถ์ ์ถ๊ฐํ๊ฒ ๋๋ฉด ์ฟผ๋ฆฌ์ ํ๋ ๋ฐ ์ค์ฒฉ๋ ๊ฐ์ฒด๋ค์ ์ ๋ฌํ์ฌ ์ํ๋ ๋ฐ์ดํฐ๋ง ๋ฐ์์ฌ ์ ์๋ค. ๐
{
human(id: "1000") {
name
height
}
}
[์ฝ๋] id๊ฐ 1000์ธ human์ name๊ณผ height๋ฅผ ์ฟผ๋ฆฌ
{
"data": {
"human": {
"name": "Luke Skywalker",
"height": 1.72
}
}
}
[์ฝ๋] ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ
- ํ๋ ์ด๋ฆ์ ์ค๋ณตํด์ ์ฌ์ฉํ ์ ์์ผ๋ฏ๋ก, ํ๋ ์ด๋ฆ์ ์ค๋ณต์ผ๋ก ์ฌ์ฉํด์ ์ฟผ๋ฆฌ๋ฅผ ํด์ผ ํ ๋๋ ๋ณ๋ช ์ ๋ถ์ฌ์ ์ฟผ๋ฆฌ
- ๋ค๋ฅธ ์ด๋ฆ์ผ๋ก ๋ณ๋ช ์ ์ง์ ํ๋ฉด ํ ๋ฒ์ ์์ฒญ์ผ๋ก ๋ ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ๋ชจ๋ ์ป์ด๋ผ ์ ์๋ค.
โ
{
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"
}
}
}
์ฟผ๋ฆฌ ๊ฒฐ๊ณผ
์ฌํ๊ป ์ฟผ๋ฆฌ์ ์ฟผ๋ฆฌ ๋ค์์ ๋ชจ๋ ์๋ตํ๋ ์ถ์ฝํ ๊ตฌ๋ฌธ์ ์ฌ์ฉํ์ต๋๋ค๋ง, ์ค์ ์ฑ์์๋ ์ฝ๋๋ฅผ ๋ชจํธํ์ง ์๊ฒ ์์ฑํ๋ ๊ฒ์ด ์ค์
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
๋ฟ๋ง ์๋๋ผ mutation
, subscription
, describes
๋์ ์ผ๋ก ์ธ์๋ฅผ ๋ฐ์ ์ฟผ๋ฆฌํ๋ ๊ฒฝ์ฐ (๋๋ค์)
query HeroNameAndFriends($episode: Episode) {
hero(episode: $episode) {
name
friends {
name
}
}
}
[์ฝ๋] ๋ณ์๋ฅผ ์จ์ ์์ฑ๋ ์ฟผ๋ฆฌ
$๋ณ์ ์ด๋ฆ: ํ์
ํํ
๋ก ์ ์$episode: Episode
์ผ ๋, ๋ค์ !
๊ฐ ๋ถ๋๋ค๋ฉด episode
๋ ๋ฐ๋์ Episode
์ฌ์ผ ํ๋ค๋ ๋ป (!
๋ ์ต์
๋ํ ์ฌํญ)
mutation CreateReviewForEpisode($ep: Episode!, $review: ReviewInput!) {
createReview(episode: $ep, review: $review) {
stars
commentary
}
}
REST API์์ GET
์์ฒญ์ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์์ ํ์ง ์๊ณ ,
POST
ํน์ PUT
์์ฒญ์ ์ฌ์ฉํ๋ ๊ฒ์ฒ๋ผ GraphQL๋ ์ ์ฌ
GraphQL์ mutation
์ด๋ผ๋ ํค์๋๋ฅผ ์ฌ์ฉํ์ฌ ์๋ฒ ์ธก ๋ฐ์ดํฐ๋ฅผ ์์
GraphQL ์คํค๋ง์ ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ๊ตฌ์ฑ ์์๋ ์๋น์ค์์ ๊ฐ์ ธ์ฌ ์ ์๋ ๊ฐ์ฒด์ ์ข ๋ฅ, ๊ทธ๋ฆฌ๊ณ ํฌํจํ๋ ํ๋๋ฅผ ๋ํ๋ด๋ ๊ฐ์ฒด ์ ํ
type Character {
name: String!
appearsIn: [Episode!]!
}
Character
๋ GraphQL ๊ฐ์ฒด ํ์
์ด๋ฉฐ, ์ฆ ํ๋๊ฐ ์๋ ํ์
์์ ์๋ฏธ (์คํค๋ง์ ์๋ ๋๋ถ๋ถ์ ํ์
์ ๊ฐ์ฒด ํ์
)name
๊ณผ appearIn
์ Character
ํ์
์ ํ๋๋ก, ์ฆ name
๊ณผ appearIn
์ GraphQL ์ฟผ๋ฆฌ์ Character
ํ์
์ด๋์๋ ์ฌ์ฉํ ์ ์๋ ํ๋String
์ ๋ด์ฅ๋ ์ค์นผ๋ผ ํ์
์ค ํ๋๋ก ๋จ์ผ ์ค์นผ๋ผ ๊ฐ์ฒด๋ก ํ์ธ๋๋ ์ ํ์ด๋ฉฐ ์ฟผ๋ฆฌ์์ ํ์ ์ ํ์ ๊ฐ์ง ์ ์๋ค. ์ค์นผ๋ผ ํ์
์๋ ID
, Int
๋ ์๋ค.!
๊ฐ ๋ถ๋๋ค๋ฉด ์ด ํ๋๋ nullableํ์ง ์๊ณ ๋ฐ๋์ ๊ฐ์ด ๋ค์ด์จ๋ค๋ ์๋ฏธ โก๏ธ ์ด๊ฒ์ ๋ถ์ฌ ์ฟผ๋ฆฌํ๋ค๋ฉด ๋ฐ๋์ ๊ฐ์ ๋ฐ์ ์ ์์ ๊ฒ์ด๋ ์์์ ํ ์ ์๋ค.[ ]
๋ ๋ฐฐ์ด์ ์๋ฏธํฉ๋๋ค. ๋ฐฐ์ด์๋ !
๊ฐ ๋ถ์ ์ ์๋ค. ์ฌ๊ธฐ์๋ !
์ด ๋ค์ ๋ถ์ด ์์ด null ๊ฐ์ ํ์ฉํ์ง ์์ผ๋ฏ๋ก ํญ์ 0๊ฐ ์ด์์ ์์๋ฅผ ํฌํจํ ๋ฐฐ์ด์ ๊ธฐ๋ํ ์ ์๊ฒ ๋๋ค
์คํค๋ง๋ฅผ ์ ์ํ๋ฉด ๊ทธ ์คํค๋ง ํ๋์ ์ฌ์ฉ๋๋ ํจ์์ ์ค์ ํ๋์ Resolver์์ ์ ์
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 () => {
...
}
}
};