-
Notifications
You must be signed in to change notification settings - Fork 5
Apollo server flow
์์ฑ์: J054 ๊น์ง๊ด
์ ํํ๊ฒ Apollo server์ ๋ํ ๋์ ๋ฐฉ์์ ๋ํด ์์ธํ๊ฒ ์ค๋ช ํ๊ณ ์๋ ๊ธ์ ์ฐพ๊ธฐ ํ๋ค์ด์ GraphQL query๊ฐ ์ ๋ฐ์ ์ผ๋ก ์ด๋ป๊ฒ ์คํ๋๋์ง์ ๋ํด์ ์ ๋ฆฌํ๋ค. ์๋ง Apollo๋ GraphQL์ ๊ตฌํ์ฒด๋ก query๋ฅผ implementํ๊ณ ์คํํ๋๋ฐ ๋์์ ์ฃผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด์ง ์์๊น ํ๋ ์๊ฐ์ ํ๊ณ ์๋ค.
validation ์ดํ์ GraphQL query๋ GraphQL server์ ์ํด ๋๊ฐ JSON๊ณผ ๊ฐ์ ํ์์ผ๋ก ์์ฒญ query์ ๋ชจ์ต๊ณผ ๋ง์ฐฌ๊ฐ์ง์ ๋ชจ์ต์ผ๋ก ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋ค.
GraphQL์ type system ์์ด query๋ฅผ ์คํํ ์ ์๋ค.
์์ ๋ก ๋ค์๊ณผ ๊ฐ์ด type์ ์ ์ํ๋ค.
type Query {
human(id: ID!): Human
}
type Human {
name: String
appearsIn: [Episode]
starships: [Starship]
}
enum Episode {
NEWHOPE
EMPIRE
JEDI
}
type Starship {
name: String
}
query๊ฐ ์ด๋ค์์ผ๋ก ๋์ํ๋์ง ์์๋ณด๊ธฐ ์ ์ ์์ฒญ๊ณผ ์๋ต์ ๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
// request
{
human(id: 1002) {
name
appearsIn
starships {
name
}
}
}
// response
{
"data": {
"human": {
"name": "Han Solo",
"appearsIn": [
"NEWHOPE",
"EMPIRE",
"JEDI"
],
"starships": [
{
"name": "Millenium Falcon"
},
{
"name": "Imperial shuttle"
}
]
}
}
}
GraphQL query์ field๋ next type์ ๋ฐํํ๋ previous type์ function์ด๋ method๋ผ๊ณ ์๊ฐํ ์ ์๋ค. type์ ๊ฐ field๋ GraphQL server developer๊ฐ ์ ์ํ resolver์ ๋ถ๋ฅด๋ ํจ์๋ก ๋ท๋ฐ์นจ๋๋ค. field๊ฐ ์คํ๋ ๋, ๋์๋๋ resolver๊ฐ ๋ถ๋ ค์ง๊ณ ๋ค์ value๋ฅผ ๋ฐํํ๋ค.
field๊ฐ scalar type์ ๋ฐํํ๋ฉด ์คํ์ ์๋ฃ๋๋ค. ํ์ง๋ง field๊ฐ ํน์ object๋ฅผ ๋ฐํํ๋ค๋ฉด scalar๋ฅผ ๋ฐํํ ๋๊น์ง ์ด๋ฅผ ๋ฐ๋ณตํ๋ค.
GraphQL server์ ์ต์์ ๋ ๋ฒจ์ GraphQL API๋ก ์ ๊ทผํ ์ ์๋ ๋ชจ๋ entry point๋ฅผ ๋ํ๋ด๋ type์ด๋ค. ์ด๋ Root type ๋๋ Query type์ด๋ผ๊ณ ๋ถ๋ฅธ๋ค.
Query: {
human(obj, args, context, info) {
return context.db.loadHumanByID(args.id).then(
userData => new Human(userData)
)
}
}
์์ ์์ ์์, Query type์ human field๋ฅผ ์ ๊ณตํ๊ณ ์๋ค. ์ด field์ ๋ํ resolver๋ database์ ์ ์ํด์ Human ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ค. ์์ ๋ Javascript๋ก ์์ฌ์ก๊ณ , GraphQL server๋ ๋ง์ ๋ค๋ฅธ ์ธ์ด๋ฅผ ์ง์ํ๋ค.
resolver function์ ๋ค์ 4๊ฐ์ ์ธ์๋ฅผ ๋ฐ๋๋ค.
-
obj
: ์ด์ (๋ถ๋ชจ) object๋ก root Query์์๋ ์ฌ์ฉํ์ง ์๋๋ค. -
args
: ์ด GraphQL query์ ์ ๋ฌ๋ arguments -
context
: ๋ชจ๋ resolver๊ฐ ๊ณต์ ํ๋ ๊ฐ์ผ๋ก ์ฃผ๋ก ๋ก๊ทธ์ธํ user, database๋ก์ ์ ๊ทผ ๋ฑ๊ณผ ๊ฐ์ contextual information์ ๋ด๊ณ ์๋ค. -
info
: ํ์ฌ query์ ๊ด๋ จ๋ field์ ๋ํ ๊ตฌ์ฒด์ ์ธ ์ ๋ณด๋ฅผ ๋ด๊ณ ์๋ ๊ฐ
DB์์ ์ ๊ทผ๊ณผ ๊ฐ์ด ๋น๋๊ธฐ ์์ ์ ์ํด์ resolver๋ Promise, Futures, Tasks์ ๊ฐ์ ๋์์ ์๊ณ ์์ ํ์๊ฐ ์๋ค. ํ์ง๋ง Query๋ ๋จ์ง ์ ์ํ field๋ฅผ ๋ฐํํ๊ธธ ๊ธฐ๋ํ๊ณ ์๊ธฐ ๋๋ฌธ์ Query ์์ฒด๋ Promise ๊ฐ์ ๋์์ ์ดํดํ ํ์๊ฐ ์๋ค. ๋จ์ง ์คํ ์ค์ Promise์ ๊ฐ์ ๋์์ด ๋ฐ์ํ๋ฉด ๋ค์์ผ๋ก ๋์ด๊ฐ๊ธฐ ์ ๊น์ง ์ด๋ฅผ ๊ธฐ๋ค๋ ค์ ์ต์ ์ ๋์์ฑ์ ๋ฌ์ฑํ ์ ์๋ค.
์ด์ Human ๊ฐ์ฒด๊ฐ ์ฌ์ฉ๊ฐ๋ฅํด์ก์ ๋ GraphQL์ ๋ค์ field์ ๋ํ ์์ฒญ์ ์ํํ๋ค.
Human: {
name(obj, args, context, info) {
return obj.name
}
}
GraphQL server๋ type system์ ์ํด ๋ค์์ ํ ์์ ์ด ์ด๋ฏธ ๊ฒฐ์ ๋์ด ์๋ค. Query type์์ human field์ ์๋ฌด๊ฒ๋ ๋ฐํ๋์ง ์์ ์ํ์์๋ GraphQL์ ๋ค์์ resolveํ field๊ฐ ๋ฌด์์ธ์ง ์๊ณ ์๋ค.
Human field์์ name์ resolveํ๋ ๊ฒฝ์ฐ๋ ๋ค์ ์ง๊ด์ ์ด๋ค. name resolver๊ฐ ๋ถ๋ ค์ง๊ณ obj ์ธ์์ Human ๊ฐ์ฒด๊ฐ ๋์ด๊ฐ๋ค.
๋๋ถ๋ถ์ GraphQL ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์ด์ ๋์ resolver๋ ๋ฐ๋ก ์ ์ํ์ง ์์๋ ์๋์ผ๋ก ์ํํ๋ค. ๋ง์ฝ resolver๊ฐ ์ ์๋์ง ์์ ๊ฒฝ์ฐ ๋ฐํ๋ object์์ ๋์ผํ ์ด๋ฆ์ field๋ฅผ ์ฝ์ด์ ๋ฐํํ๋ค.(์ด ๋ถ๋ถ์ Apollo Server๊ฐ ์ํํ๋ ์ผ์ด ๋ ๊ฒ ๊ฐ๋ค.)
name
field๊ฐ resolve๋๋ ๋์์ appearsIn
๊ณผ starships
field๊ฐ ๋์์ resolve๋๋ค. appearsIn
field ๋ํ trivial resolver๋ฅผ ๊ฐ๊ณ ์๋ค.
Human: {
appearsIn(obj) {
return obj.appearsIn // returns [ 4, 5, 6 ]
}
}
type system์ appearsIn
์ด Enum values๋ฅผ ๋ฐํํด์ผ ํ๋ค๋ ๊ฒ์ ์๊ณ ์๋ค. ํ์ง๋ง ์ด ํจ์๋ ์ซ์๋ค์ ๋ฐํํ๊ณ ์๋ค.
์์ ์์ ๊ฐ scalar coercion์ด๋ค. type system์ ๊ธฐ๋ํ๋ ๊ฐ๊ณผ API contract์ ๋ฐ๋ผ resolver ํจ์์ ์ํด ์ ์ ํ ๊ฐ์ผ๋ก ๋ณํํ์ฌ ๋ฐํํ๋ค. ์ด ๊ฒฝ์ฐ ์ฐ๋ฆฌ๊ฐ ์ ์ํ Enum์ ๋ด๋ถ์ ์ผ๋ก 4, 5, 6์ ์ฌ์ฉํ๊ณ ์๋ ๊ฒ์ด๋ค.
Human: {
starships(obj, args, context, info) {
return obj.starshipIDs.map(
id => context.db.loadStarshipByID(id).then(
shipData => new Starship(shipData)
)
)
}
}
starships
field๋ Promise์ ๋ฆฌ์คํธ๋ฅผ ๋ฐํํ๋ค. Human ๊ฐ์ฒด๋ Starships์ id์ ๋ฆฌ์คํธ๋ฅผ ๊ฐ๊ณ ์์ง๋ง, ์ฐ๋ฆฌ๋ ์ค์ Startship ๊ฐ์ฒด์ id๋ก ์ ๊ทผํด์ ๊ฐ์ ธ์์ผ ํ๋ค.
GraphQL์ ๋ค์์ผ๋ก ๋์ด๊ฐ์ง ์ ๊น์ง ๊ธฐ๋ค๋ฆฐ๋ค.
leaf์์ ๋ฐํํ ๊ฐ๋ค์ด root๊น์ง ํ๊ณ ์ฌ๋ผ๊ฐ๋ฉด์ key-value๋ก mapping๋์ ๋ฐํํ๋ค. ์ด๋ ๊ฒ ๋ชจ์ฌ์ง ๊ฒฐ๊ณผ๋ ์์ฒญ query์ ๋์ผํ ํํ๋ก ๋ฐํ๋๋ค.
์ถ์ฒ
๐กHome
- Apollo References
- Schema Directives
- Apollo Client - Local State
- GraphQL Execution
- Apollo Server Execution
- Apollo Client Cache
- Apollo Client Execution
- Mongoose-Populate