GraphQL ๊ตฌ์กฐ

๊น€๋‚จ๊ฒฝยท2023๋…„ 1์›” 30์ผ
1

network

๋ชฉ๋ก ๋ณด๊ธฐ
24/27

์ž‘๋™ ์›๋ฆฌ

๐Ÿ’ก Query๋ฅผ ์ด์šฉํ•ด ์›ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์š”์ฒญ
๐Ÿ’ก ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” Mutation์„ ์ด์šฉ
๐Ÿ’ก ๊ตฌ๋…(Subscription)์ด๋ผ๋Š” ๊ฐœ๋…์„ ์ œ๊ณตํ•˜๋ฉฐ ์ด๋ฅผ ์ด์šฉํ•ด ์‹ค์‹œ๊ฐ„ ์—…๋ฐ์ดํŠธ๋ฅผ ๊ตฌํ˜„
-Query ๋˜๋Š” Mutation๊ณผ ๋‹ฌ๋ฆฌ, ๋ฐœํ–‰/๊ตฌ๋…(pub/sub) ๋ชจ๋ธ
-ํด๋ผ์ด์–ธํŠธ๋Š” ์„œ๋ฒ„์™€ WebSocket์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ง€์†์ ์ธ ์—ฐ๊ฒฐ์„ ํ˜•์„ฑํ•˜๊ณ  ์œ ์ง€

Query

๐Ÿ“— ํ•„๋“œ(field)
์ฟผ๋ฆฌ์™€ ๊ฒฐ๊ณผ๊ฐ€ ์ •ํ™•ํ•˜๊ฒŒ ๊ฐ™์€ ๋ชจ์–‘์ด์–ด์•ผ ํ•จ

//query
{
  hero {
    name
    # ์ฃผ์„ ์ž‘์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•
    friends {
      name
    }
  }
}
//๊ฒฐ๊ณผ
{
  "data": {
    "hero": {
      "name": "R2-D2",
      "friends": [
        {
          "name": "Luke Skywalker"
        },
        {
          "name": "Han Solo"
        },
        {
          "name": "Leia Organa"
        }
      ]
    }
  }
}

โœ… ์›ํ•˜๋Š” ํ•„๋“œ๋ฅผ ์ค‘์ฒฉํ•˜์—ฌ ์ฟผ๋ฆฌํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅ

๐Ÿ“— ์ „๋‹ฌ์ธ์ž(Arguments)

//query
{
  human(id: "1000") {
    name
    height
  }
}
//๊ฒฐ๊ณผ
{
  "data": {
    "human": {
      "name": "Luke Skywalker",
      "height": 1.72
    }
  }
}

โœ… REST์™€ ๊ฐ™์€ ์‹œ์Šคํ…œ์—์„œ๋Š” ๋‹จ์ผ ์ธ์ˆ˜ ์ง‘ํ•ฉ(์š”์ฒญ์˜ ์ฟผ๋ฆฌ ๋งค๊ฐœ๋ณ€์ˆ˜ ๋ฐ URL ์„ธ๊ทธ๋จผํŠธ)๋งŒ ์ „๋‹ฌ ๊ฐ€๋Šฅ

๐Ÿ“— ๋ณ„๋ช…(Aliases)

//ํ‹€๋ฆฐ query
{
  hero(episode: EMPIRE) {
    name
  }
  hero(episode: JEDI) {
    name
  }
}
//query
{
  empireHero: hero(episode: EMPIRE) {
    name
  }
  jediHero: hero(episode: JEDI) {
    name
  }
}
//๊ฒฐ๊ณผ
{
  "data": {
    "empireHero": {
      "name": "Luke Skywalker"
    },
    "jediHero": {
      "name": "R2-D2"
    }
  }
}

โœ… ํ•„๋“œ ์ด๋ฆ„์„ ์ค‘๋ณตํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Œ

๐Ÿ“— ์˜คํผ๋ ˆ์ด์…˜ ๋„ค์ž„(Operation name)

//query
query HeroNameAndFriends {
  hero {
    name
    friends {
      name
    }
  }
}
//๊ฒฐ๊ณผ
{
  "data": {
    "hero": {
      "name": "R2-D2",
      "friends": [
        {
          "name": "Luke Skywalker"
        },
        {
          "name": "Han Solo"
        },
        {
          "name": "Leia Organa"
        }
      ]
    }
  }
}

โœ… ์˜คํผ๋ ˆ์ด์…˜ ํƒ€์ž…์—๋Š” query, mutation, subscription, describes ๋“ฑ ์กด์žฌ
โœ… ๋ชจํ˜ธํ•˜๊ฒŒ ํ‘œ๊ธฐํ•˜์ง€ ์•Š๋„๋ก

๐Ÿ“— ๋ณ€์ˆ˜(Variables)

query HeroNameAndFriends($episode: Episode) {
  hero(episode: $episode) {
    name
    friends {
      name
    }
  }
}

โœ… $๋ณ€์ˆ˜ ์ด๋ฆ„: ํƒ€์ž… ํ˜•ํƒœ
โœ… $episode: Episode! ๋Š” episode๋Š” ๋ฐ˜๋“œ์‹œ Episode

mutation

mutation CreateReviewForEpisode($ep: Episode!, $review: ReviewInput!) {
  createReview(episode: $ep, review: $review) {
    stars
    commentary
  }
}

Schema/Type

type Character {
  name: String!
  appearsIn: [Episode!]!
}

โœ… Character GraphQL ๊ฐ์ฒด ํƒ€์ž…(ํ•„๋“œ๊ฐ€ ์กด์žฌ)
โœ… name / appearIn Character ํƒ€์ž…์˜ ํ•„๋“œ
โœ… String ๋‚ด์žฅ๋œ ์Šค์นผ๋ผ ํƒ€์ž…(๊ทธ์™ธ ID, Int ๋“ฑ)
๋‹จ์ผ ์Šค์นผ๋ผ ๊ฐ์ฒด. ์ฟผ๋ฆฌ์—์„œ ํ•˜์œ„ ์„ ํƒ์ด ๋ถˆ๊ฐ€๋Šฅ
โœ… ! ์ด ํ•„๋“œ๋Š” nullableํ•˜์ง€ ์•Š๊ณ  ๋ฐ˜๋“œ์‹œ ๊ฐ’์ด ์กด์žฌ
โœ… [ ]๋Š” ๋ฐฐ์—ด

Resolver

์š”์ฒญ์— ๋Œ€ํ•œ ์‘๋‹ต์„ ๊ฒฐ์ •ํ•ด์ฃผ๋Š” ํ•จ์ˆ˜

const db = require("./../db")
const resolvers = {
  Query: {
		getUser: async (_, { email, pw }) => {
			db.findOne({
				where: { email, pw }
			}) ... 
			...
		}
  },
  Mutation: {
		createUser: async (_, { email, pw, name }) => {
			...
		}
  }
  Subscription: { 
    newUser: async () => {
      ...
		}
  }
};
profile
๊ธฐ๋ณธ์— ์ถฉ์‹คํ•˜๋ฉฐ ์•ž์œผ๋กœ ๋ฐœ์ „ํ•˜๋Š”

0๊ฐœ์˜ ๋Œ“๊ธ€