GraphQL๊ณผ Apollo ์ผ๊ณฑ๋ฒˆ์งธ ์ด์•ผ๊ธฐ - GraphQL Data Type์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์•„์š” ๐Ÿ˜€

2023. 11. 20. 22:39ใ†Back-End ์ž‘์—…์‹ค/๊ธฐํƒ€ ์ฐธ๊ณ  ์ž๋ฃŒ

728x90
๋ฐ˜์‘ํ˜•

 

 

์นด์นด์˜คํŽ˜์ด | ๋งˆ์Œ ๋†“๊ณ  ๊ธˆ์œตํ•˜๋‹ค

์—ฌ๊ธฐ๋ฅผ ๋ˆŒ๋Ÿฌ ๋งํฌ๋ฅผ ํ™•์ธํ•˜์„ธ์š”.

qr.kakaopay.com

 

 

 

 

 

GraphQL๊ณผ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋กœ ๊ฐœ๋ฐœํ•˜๋Š” ์›น ์„œ๋น„์Šค:์„ค๊ณ„๋ถ€ํ„ฐ ๊ฐœ๋ฐœ·๋ฐฐํฌ๊นŒ์ง€ ๋”ฐ๋ผ ํ•˜๋ฉฐ ์™„์„ฑํ•˜๋Š” ์›น ํ’€

COUPANG

www.coupang.com

"์ด ํฌ์ŠคํŒ…์€ ์ฟ ํŒก ํŒŒํŠธ๋„ˆ์Šค ํ™œ๋™์˜ ์ผํ™˜์œผ๋กœ, ์ด์— ๋”ฐ๋ฅธ ์ผ์ •์•ก์˜ ์ˆ˜์ˆ˜๋ฃŒ๋ฅผ ์ œ๊ณต๋ฐ›์Šต๋‹ˆ๋‹ค."

 




๐Ÿ—‚ ๋ชฉ์ฐจ

โœ… GraphQL๊ณผ Apollo ์ฒซ๋ฒˆ์งธ ์ด์•ผ๊ธฐ - ๊ฐœ๋… ์ตํžˆ๊ธฐ
โœ… GraphQL๊ณผ Apollo ๋‘๋ฒˆ์งธ ์ด์•ผ๊ธฐ - REST API๋ž€?
โœ… GraphQL๊ณผ Apollo ์„ธ๋ฒˆ์งธ ์ด์•ผ๊ธฐ - GraphQL์˜ ์ •๋ณด ์ฃผ๊ณ  ๋ฐ›๋Š” ๋ฐฉ์‹

โœ… GraphQL๊ณผ Apollo ๋„ค๋ฒˆ์งธ ์ด์•ผ๊ธฐ - Apollo๋ž€?
โœ… GraphQL๊ณผ Apollo ๋‹ค์„ฏ๋ฒˆ์งธ ์ด์•ผ๊ธฐ - GraphQL์„ ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ตฌํ˜„ํ•ด ๋ณด์•„์š” ๐Ÿ˜€
โœ… GraphQL๊ณผ Apollo ์—ฌ์„ฏ๋ฒˆ์งธ ์ด์•ผ๊ธฐ - GraphQL Moduleํ™”์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์•„์š” ๐Ÿ˜€
โœ… GraphQL๊ณผ Apollo ์ผ๊ณฑ๋ฒˆ์งธ ์ด์•ผ๊ธฐ - GraphQL Data Type์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์•„์š” ๐Ÿ˜€
โœ… GraphQL๊ณผ Apollo ์—ฌ๋Ÿ๋ฒˆ์งธ ์ด์•ผ๊ธฐ - GraphQL Union๊ณผ Interface ๊ทธ๋ฆฌ๊ณ  ์ธ์ž์™€ ์ธํ’‹ ํƒ€์ž…์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์•„์š” ๐Ÿ˜€
โœ… GraphQL๊ณผ Apollo ์•„ํ™‰๋ฒˆ์งธ ์ด์•ผ๊ธฐ - Java + Spring Boot์—์„œ GraphQL ์‚ฌ์šฉํ•ด ๋ณด๊ธฐ - ์‹ค์Šต ํ™˜๊ฒฝ ๊ตฌ์„ฑ
โœ… GraphQL๊ณผ Apollo ์—ด๋ฒˆ์งธ ์ด์•ผ๊ธฐ - Java + Spring Boot์—์„œ GraphQL ์‚ฌ์šฉํ•ด ๋ณด๊ธฐ - ์‹ค์Šต ํ•ด๋ณด๊ธฐ
โœ… GraphQL๊ณผ Apollo ์—ด ํ•œ๋ฒˆ์งธ ์ด์•ผ๊ธฐ - TypeScript + Nest.js์—์„œ GraphQL ์‚ฌ์šฉํ•ด ๋ณด๊ธฐ - ์‹ค์Šต ํ™˜๊ฒฝ ๊ตฌ์„ฑ
โœ… 
GraphQL๊ณผ Apollo ์—ด ๋‘๋ฒˆ์งธ ์ด์•ผ๊ธฐ - TypeScript + Nest.js์—์„œ GraphQL ์‚ฌ์šฉํ•ด ๋ณด๊ธฐ - ์‹ค์Šต ํ™˜๊ฒฝ ํ…Œ์ŠคํŠธ
โœ… GraphQL๊ณผ Apollo ์—ด ์„ธ๋ฒˆ์งธ ์ด์•ผ๊ธฐ - TypeScript + Nest์—์„œ GraphQL ์‚ฌ์šฉํ•ด ๋ณด๊ธฐ - ์‹ค์Šต ํ•ด๋ณด๊ธฐ
โœ… 
GraphQL๊ณผ Apollo ์—ด ๋„ค๋ฒˆ์งธ ์ด์•ผ๊ธฐ - React์™€ Apollo Client
โœ… GraphQL๊ณผ Apollo ์—ด๋‹ค์„ฏ๋ฒˆ์งธ ์ด์•ผ๊ธฐ - React์™€ Apollo Client - Query์™€ Mutation ์‚ฌ์šฉํ•˜์—ฌ ์›น ํŽ˜์ด์ง€ ๋งŒ๋“ค๊ธฐ
โœ… GraphQL๊ณผ Apollo ์—ด ์—ฌ์„ฏ๋ฒˆ์งธ ์ด์•ผ๊ธฐ - Kotlin + Spring Boot์—์„œ GraphQL ์‚ฌ์šฉํ•ด ๋ณด๊ธฐ - ์‹ค์Šต ํ™˜๊ฒฝ ๊ตฌ์„ฑ
โœ… GraphQL๊ณผ Apollo ์—ด ์ผ๊ณฑ๋ฒˆ์งธ ์ด์•ผ๊ธฐ - Kotlin + Spring Boot์—์„œ GraphQL ์‚ฌ์šฉํ•ด ๋ณด๊ธฐ - ์‹ค์Šต ํ•ด๋ณด๊ธฐ


๐Ÿค” ๋‚ด๊ฐ€ ๋งŒ๋‚œ ๋ฌธ์ œ

โš ๏ธ [Nest.js] TypeORM Table ๊ด€๊ณ„๊ฐ€ ๋งบ์–ด์กŒ์„ ๋•Œ, Seeding (feat. Migration)
โš ๏ธ [Spring Boot 3.0] Could not resolve org.springframework.boot:spring-boot-gradle-plugin
โš ๏ธ [Spring Boot 3] Spring Doc(Swagger) White Label Error


๐Ÿ“‹ ๋ถ€๋ก

๐Ÿ” [Nest.js] ์ดˆ๊ธฐ ํ™˜๊ฒฝ ๊ตฌ์„ฑ (feat. TypeORM, QueryBuilder, GraphQL, Apollo)
๐Ÿ” [SOLID][Nest.js][Java + Spring] Interface๋ฅผ ํ™œ์šฉํ•œ ๊ฒฐํ•ฉ๋„ ๋ถ„๋ฆฌ (Interface๋ฅผ ์ด์šฉํ•œ Dependency Injection - DI)

 

 

 

๐Ÿš€ GraphQL๊ณผ Apollo ์ผ๊ณฑ๋ฒˆ์งธ ์ด์•ผ๊ธฐ

    ๐Ÿ”ฝ GraphQL Data Type์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์•„์š” ๐Ÿ˜€

        ๐Ÿ“ฆ Scala Type

์ด๋ฒˆ์—๋Š” GraphQL์—์„œ ์‚ฌ์šฉ๋˜๋Š” Type ์ฆ‰, ์ž๋ฃŒํ˜•์— ๋Œ€ํ•ด ๊ณต๋ถ€ํ•ด ๋ณด๋ ค๊ณ  ํ•ด์š”.

equipments.js


์ด ์ „ ์‹œ๊ฐ„์— ๊ตฌ์„ฑํ–ˆ๋˜ ํ”„๋กœ์ ํŠธ๋ฅผ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•ด์„œ ๊ณต๋ถ€ํ•ด ๋ณผ๊ฒŒ์š”.

์ตœ์ดˆ Equipments.js์—์„œ Equipment Schema๋ฅผ ๋ณด๋ฉด ์•„์ง Type์„ ์•Œ๊ธฐ ์ „์ด์˜€๊ธฐ ๋•Œ๋ฌธ์— ์ผ๋‹จ String๊ณผ Integer๋กœ๋งŒ Schema๋ฅผ ํ‘œํ˜„ํ•œ ๊ฑธ ๋ณผ ์ˆ˜ ์žˆ์–ด์š”.

์—ฌ๊ธฐ์— ๋‹ค์–‘ํ•œ Type์„ ๋จผ์ € ์ด์šฉํ•ด ๋ณผ๊ฒŒ์š”.

equipments.js


equipments.js 12 ~ 18๋ฒˆ์งธ ์ค„์— ์ƒˆ๋กœ์šด Type์„ ์ถ”๊ฐ€ํ•ด ์ฃผ์—ˆ์–ด์š”.

GraphQL์—์„œ ์ฃผ์–ด์ง€๋Š” ๋‚ด์žฅ๋œ ๊ธฐ๋ณธ ์ž๋ฃŒํ˜• Type์„ Scala Type์ด๋ผ๊ณ  ํ•ด์š”.

์ž๋ฃŒํ˜• ํƒ€์ž… ์„ค๋ช…
ID ๊ธฐ๋ณธ์ ์œผ๋กœ String(๋ฌธ์ž์—ด)์ด์ง€๋งŒ, ๊ณ ์œ  ์‹๋ณ„์ž ํ‘œํ˜„.
String UTF-8 ๋ฌธ์ž์—ด
Int ๋ถ€ํ˜ธ๊ฐ€ ์žˆ๋Š” 32Bit ์ •์ˆ˜
Float ๋ถ€ํ˜ธ๊ฐ€ ์žˆ๋Š” ๋ถ€๋™์†Œ์ˆ˜์ 
Boolean True or False(์ฐธ๊ณผ ๊ฑฐ์ง“)


String๊ณผ Int, Boolean์€ ์‰ฌ์šฐ๋‹Œ๊นŒ ๋„˜์–ด๊ฐ€๊ณ , ID๋Š” ์ปดํ“จํ„ฐ ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” String ์ž๋ฃŒํ˜•์œผ๋กœ ๋™์ž‘ํ•˜๋Š”๋ฐ, ์ด๋Š” ๊ฐœ๋ฐœ์ž๋“ค์—๊ฒŒ ๋ฐ์ดํ„ฐ์˜ ๊ณ ์œ  ์‹๋ณ„์ž๋ฅผ ๋‚˜ํƒ€๋‚ด๊ธฐ ์œ„ํ•œ ์•ฝ์†์ด๋ผ๊ณ  ๋ณด๋ฉด ๋ผ์š”.

์Œ.. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ ์˜ˆ๋ฅผ ๋“ค๋ฉด PK(Primary Key)์™€ ๊ฐ™์€ ๊ฐœ๋…์ด์—์š”.
์ฆ‰, Unique(์œ ์ผ) ํ•ด์•ผํ•œ๋‹ค๋Š” ๊ฑฐ์—์š”.

Float์€ ์†Œ์ˆ˜์  ํ˜•ํƒœ์˜ ์ˆซ์ž๋ฅผ ๋‚˜ํƒ€๋‚ด๊ธฐ ์œ„ํ•œ ์ž๋ฃŒํ˜•์ด์—์š”.

๊ทผ๋ฐ! ๋Š๋‚Œํ‘œ(!)๋Š” ๋ญ˜๊นŒ์š”?

๋Š๋‚Œํ‘œ๊ฐ€ ๋ถ™์€ ๊ฒƒ์€ Non Null์ด๋ผ๋Š” ์˜๋ฏธ๋กœ Null์ด ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์—†๋‹ค๋Š” ์˜๋ฏธ์—์š”.
์ฆ‰, Null Safety ํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•จ์ด์—์š”.

๋งŒ์•ฝ ๋Š๋‚Œํ‘œ๋ฅผ ๋ถ™ํ˜”๋Š”๋ฐ, Null์ด ๋ฐ˜ํ™˜๋˜๋ฉด Error๊ฐ€ ํ„ฐ์ ธ๋ฒ„๋ฆด๊ฑฐ์—์š”.

Playgroud


ํ•œ๊ฐ€์ง€ ์ฃผ๋ชฉํ•ด์•ผ ํ•  ์ ์€ ์œ„์™€ ๊ฐ™์ด Schema๋ฅผ ๋งŒ๋“ค์–ด ๋ฒ„๋ฆฌ๋ฉด ๊ธฐ์กด์— ๋ฐ˜ํ™˜๋˜๋Š” ๋ฐ์ดํ„ฐ์™€ ์ž๋ฃŒํ˜• Type์ด ๋‹ฌ๋ผ์ง€๊ฒŒ ๋ ๊ฑฐ์—์š”.
์™œ๋ƒํ•˜๋ฉด Float, Boolean Type์˜ ์ž๋ฃŒํ˜•์ด ๊ธฐ์กด ๋ฐ˜ํ™˜๊ฐ’์—๋Š” ์—†๊ธฐ ๋•Œ๋ฌธ์ด์—์š”.

์ด๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์ ์ ˆํ•œ resolver๋ฅผ ์ž‘์„ฑํ•ด ๋ณด๋„๋ก ํ• ๊ฒŒ์š”.

equipments.js

728x90
const resolvers = {
    Query: {
        equipments: (parent, args) => dbWorks.getEquipments(args),

        equipmentAdvs: (parent, args) => dbWorks.getEquipments(args).map((equipment) => {
            if (equipment.used_by === 'developer') {
                equipment.use_rate = Math.random().toFixed(2);
            }

            equipment.is_new = equipment.new_or_used === 'new';
            return equipment;
        })
    },

    Mutation: {
        deleteEquipment: (parent, args) => dbWorks.deleteItem('equipments', args),
    }
}


์œ„์™€ ๊ฐ™์ด equipmentAdvs๋ฅผ ๋งŒ๋“ค์–ด ์ฃผ์—ˆ์–ด์š”.

์ฝ”๋“œ๋ฅผ ๋ถ„์„ํ•ด ๋ณด๋ฉด


๊ธฐ์กด์— ์œ„์™€ ๊ฐ™์ด ๋ฐ˜ํ™˜๋˜๋˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”์ถœํ•ด ๊ฐ๊ฐ map()์„ ์ด์šฉํ•˜์—ฌ used_by๊ฐ€ 'developer' ์ธ์ง€ ํ™•์ธํ•˜๊ณ , 
๋งž๋‹ค๋ฉด use_rate๋ผ๋Š” ํ•ญ๋ชฉ์„ Random์œผ๋กœ ๋งŒ๋“ค์–ด ๋„ฃ์–ด์ฃผ๊ณ , use_new๋ผ๋Š” ํ•ญ๋ชฉ์„ ์ถ”๊ฐ€ํ•ด new_or_used๊ฐ€ 'new'๋ผ๋ฉด ์ฐธ์„ ๋ฐ˜ํ™˜ํ•˜๊ณ , ์•„๋‹ˆ๋ฉด ๊ฑฐ์ง“์„ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ํ•ด์ค€ ๋ถ€๋ถ„์ด์—์š”.


์—ฌ๊ธฐ๊นŒ์ง€๋งŒ ํ•ด๋†จ๋‹ค๋ฉด ํ„ฐ๋ฏธ๋„์€ ๋‚œ๋ฆฌ๊ฐ€ ๋‚ฌ์„๊ฑฐ์—์š”. ์™œ๋ƒํ•˜๋ฉด Root Query Type์— ์ง€์ •ํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์ด์—์š”.

_queries.js

const { gql } = require('apollo-server')

const typeDefs = gql`
    type Query {
        equipments: [Equipment],
        supplies: [Supply],
        equipmentAdvs: [EquipmentsAdv]
    }
`

module.exports = typeDefs


์œ„์™€ ๊ฐ™์ด 7๋ฒˆ์งธ ์ค„์— ํ•ด๋‹น ๋‚ด์šฉ์„ ์ถ”๊ฐ€ํ•ด ์ฃผ์—ˆ์–ด์š”.

Playgroud

 

query {
  equipmentAdvs {
    id
    used_by
    count
    use_rate
    is_new
  }
}

 

{
  "data": {
    "equipmentAdvs": [
      {
        "id": "machanical keyboard",
        "used_by": "developer",
        "count": 24,
        "use_rate": 0.65,
        "is_new": false
      },
      {
        "id": "pen tablet",
        "used_by": "designer",
        "count": 15,
        "use_rate": null,
        "is_new": false
      },
      {
        "id": "notebook",
        "used_by": "planner",
        "count": 37,
        "use_rate": null,
        "is_new": true
      },
      {
        "id": "ergonomic mouse",
        "used_by": "designer",
        "count": 31,
        "use_rate": null,
        "is_new": false
      },
      {
        "id": "dual monitor",
        "used_by": "developer",
        "count": 20,
        "use_rate": 0.6,
        "is_new": false
      },
      {
        "id": "whiteboard",
        "used_by": "planner",
        "count": 12,
        "use_rate": null,
        "is_new": false
      },
      {
        "id": "sketchboard",
        "used_by": "designer",
        "count": 48,
        "use_rate": null,
        "is_new": true
      }
    ]
  }
}


์œ„์™€ ๊ฐ™์ด Query๋ฅผ ๋‚ ๋ ค๋ณด๋ฉด ์œ„์™€ ๊ฐ™์ด ์‘๋‹ต์ด ์˜ค๋Š”๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”.

์ž ๊น! ๊ทผ๋ฐ use_rate์— Null์ด ์žˆ์Œ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ , Error๊ฐ€ ๋‚˜์ง€ ์•Š๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ผ๊นŒ์š”?

equipments.js


๊ทธ๊ฑด ๋ฐ”๋กœ Schema์—์„œ ์œ„์™€ ๊ฐ™์ด use_rate ์ž๋ฃŒํ˜•์— ๋Š๋‚Œํ‘œ(!)๋ฅผ ๋„ฃ์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์ด์—์š”.

equipments.js


์œ„์™€ ๊ฐ™์ด ๋Š๋‚Œํ‘œ(!)๋ฅผ ๋ถ™์ด๊ณ , ๋‹ค์‹œ ์š”์ฒญ์„ ๋ณด๋‚ด๋ณด๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ์š”?

Playgroud

{
  "errors": [
    {
      "message": "Cannot return null for non-nullable field EquipmentsAdv.use_rate.",
      "locations": [
        {
          "line": 6,
          "column": 5
        }
      ],
      "path": [
        "equipmentAdvs",
        1,
        "use_rate"
      ],
      "extensions": {
        "code": "INTERNAL_SERVER_ERROR",
        "exception": {
          "stacktrace": [
            "Error: Cannot return null for non-nullable field EquipmentsAdv.use_rate.",
            "    at completeValue (/Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:561:13)",
            "    at resolveField (/Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:474:19)",
            "    at executeFields (/Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:294:18)",
            "    at collectAndExecuteSubfields (/Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:749:10)",
            "    at completeObjectValue (/Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:739:10)",
            "    at completeValue (/Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:592:12)",
            "    at /Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:626:25",
            "    at from (<anonymous>)",
            "    at completeListValue (/Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:613:49)",
            "    at completeValue (/Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:574:12)"
          ]
        }
      }
    },
    {
      "message": "Cannot return null for non-nullable field EquipmentsAdv.use_rate.",
      "locations": [
        {
          "line": 6,
          "column": 5
        }
      ],
      "path": [
        "equipmentAdvs",
        2,
        "use_rate"
      ],
      "extensions": {
        "code": "INTERNAL_SERVER_ERROR",
        "exception": {
          "stacktrace": [
            "Error: Cannot return null for non-nullable field EquipmentsAdv.use_rate.",
            "    at completeValue (/Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:561:13)",
            "    at resolveField (/Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:474:19)",
            "    at executeFields (/Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:294:18)",
            "    at collectAndExecuteSubfields (/Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:749:10)",
            "    at completeObjectValue (/Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:739:10)",
            "    at completeValue (/Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:592:12)",
            "    at /Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:626:25",
            "    at from (<anonymous>)",
            "    at completeListValue (/Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:613:49)",
            "    at completeValue (/Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:574:12)"
          ]
        }
      }
    },
    {
      "message": "Cannot return null for non-nullable field EquipmentsAdv.use_rate.",
      "locations": [
        {
          "line": 6,
          "column": 5
        }
      ],
      "path": [
        "equipmentAdvs",
        3,
        "use_rate"
      ],
      "extensions": {
        "code": "INTERNAL_SERVER_ERROR",
        "exception": {
          "stacktrace": [
            "Error: Cannot return null for non-nullable field EquipmentsAdv.use_rate.",
            "    at completeValue (/Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:561:13)",
            "    at resolveField (/Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:474:19)",
            "    at executeFields (/Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:294:18)",
            "    at collectAndExecuteSubfields (/Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:749:10)",
            "    at completeObjectValue (/Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:739:10)",
            "    at completeValue (/Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:592:12)",
            "    at /Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:626:25",
            "    at from (<anonymous>)",
            "    at completeListValue (/Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:613:49)",
            "    at completeValue (/Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:574:12)"
          ]
        }
      }
    },
    {
      "message": "Cannot return null for non-nullable field EquipmentsAdv.use_rate.",
      "locations": [
        {
          "line": 6,
          "column": 5
        }
      ],
      "path": [
        "equipmentAdvs",
        5,
        "use_rate"
      ],
      "extensions": {
        "code": "INTERNAL_SERVER_ERROR",
        "exception": {
          "stacktrace": [
            "Error: Cannot return null for non-nullable field EquipmentsAdv.use_rate.",
            "    at completeValue (/Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:561:13)",
            "    at resolveField (/Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:474:19)",
            "    at executeFields (/Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:294:18)",
            "    at collectAndExecuteSubfields (/Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:749:10)",
            "    at completeObjectValue (/Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:739:10)",
            "    at completeValue (/Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:592:12)",
            "    at /Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:626:25",
            "    at from (<anonymous>)",
            "    at completeListValue (/Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:613:49)",
            "    at completeValue (/Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:574:12)"
          ]
        }
      }
    },
    {
      "message": "Cannot return null for non-nullable field EquipmentsAdv.use_rate.",
      "locations": [
        {
          "line": 6,
          "column": 5
        }
      ],
      "path": [
        "equipmentAdvs",
        6,
        "use_rate"
      ],
      "extensions": {
        "code": "INTERNAL_SERVER_ERROR",
        "exception": {
          "stacktrace": [
            "Error: Cannot return null for non-nullable field EquipmentsAdv.use_rate.",
            "    at completeValue (/Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:561:13)",
            "    at resolveField (/Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:474:19)",
            "    at executeFields (/Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:294:18)",
            "    at collectAndExecuteSubfields (/Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:749:10)",
            "    at completeObjectValue (/Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:739:10)",
            "    at completeValue (/Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:592:12)",
            "    at /Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:626:25",
            "    at from (<anonymous>)",
            "    at completeListValue (/Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:613:49)",
            "    at completeValue (/Users/junyss/Programming/study/yalco-inflearn-graphql-apollo/3-1-server-modularized/node_modules/graphql/execution/execute.js:574:12)"
          ]
        }
      }
    }
  ],
  "data": {
    "equipmentAdvs": [
      {
        "id": "machanical keyboard",
        "used_by": "developer",
        "count": 24,
        "use_rate": 0.71,
        "is_new": false
      },
      null,
      null,
      null,
      {
        "id": "dual monitor",
        "used_by": "developer",
        "count": 20,
        "use_rate": 0.45,
        "is_new": false
      },
      null,
      null
    ]
  }
}



์œ„์™€ ๊ฐ™์ด Error๊ฐ€ ๋ฐ˜ํ™˜๋˜๋Š” ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”.
Error ๋‚ด์šฉ์„ ๋ณด๋ฉด EquipmentsAdv์˜ use_rate๊ฐ€ Null์„ ๋ฐ˜ํ™˜ํ•˜๋ฉด ์•ˆ๋˜๋Š”๋ฐ, Null์„ ๋ฐ˜ํ™˜ํ•ด์„œ ๋ฌธ์ œ๋ผ๋Š” ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”.

 

 

 

        ๐Ÿ“ฆ Enum Type

์ด๋ฒˆ์—๋Š” Enum(์—ด๊ฑฐํ˜•) ์ž๋ฃŒํ˜•์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๋„๋ก ํ• ๊ฒŒ์š”.
์—ด๊ฑฐํ˜• ์ž๋ฃŒํ˜•์€ ๋ฏธ๋ฆฌ ์ •ํ•ด๋‘” ํŠน์ • ๊ฐ’๋งŒ ๋ฐ˜ํ™˜ํ•˜๋ ค๊ณ  ํ•  ๋•Œ, ์‚ฌ์šฉํ•˜๋Š” ์ž๋ฃŒํ˜•์ด์—์š”.

Playgroud

๋ฐ˜์‘ํ˜•
query {
  equipments {
    id
    new_or_used
    count
    used_by
  }
  equipmentAdvs{
    id
    used_by
    count
    use_rate
    is_new
  }
}

 

{
  "data": {
    "equipments": [
      {
        "id": "machanical keyboard",
        "new_or_used": "used",
        "count": 24,
        "used_by": "developer"
      },
      {
        "id": "pen tablet",
        "new_or_used": "used",
        "count": 15,
        "used_by": "designer"
      },
      {
        "id": "notebook",
        "new_or_used": "new",
        "count": 37,
        "used_by": "planner"
      },
      {
        "id": "ergonomic mouse",
        "new_or_used": "used",
        "count": 31,
        "used_by": "designer"
      },
      {
        "id": "dual monitor",
        "new_or_used": "used",
        "count": 20,
        "used_by": "developer"
      },
      {
        "id": "whiteboard",
        "new_or_used": "used",
        "count": 12,
        "used_by": "planner"
      },
      {
        "id": "sketchboard",
        "new_or_used": "new",
        "count": 48,
        "used_by": "designer"
      }
    ],
    "equipmentAdvs": [
      {
        "id": "machanical keyboard",
        "used_by": "developer",
        "count": 24,
        "use_rate": 0.42,
        "is_new": false
      },
      {
        "id": "pen tablet",
        "used_by": "designer",
        "count": 15,
        "use_rate": null,
        "is_new": false
      },
      {
        "id": "notebook",
        "used_by": "planner",
        "count": 37,
        "use_rate": null,
        "is_new": true
      },
      {
        "id": "ergonomic mouse",
        "used_by": "designer",
        "count": 31,
        "use_rate": null,
        "is_new": false
      },
      {
        "id": "dual monitor",
        "used_by": "developer",
        "count": 20,
        "use_rate": 0.75,
        "is_new": false
      },
      {
        "id": "whiteboard",
        "used_by": "planner",
        "count": 12,
        "use_rate": null,
        "is_new": false
      },
      {
        "id": "sketchboard",
        "used_by": "designer",
        "count": 48,
        "use_rate": null,
        "is_new": true
      }
    ]
  }
}


equiments ๋ฐ˜ํ™˜๊ฐ’์„ ํ™•์ธํ•ด ๋ณด๋ฉด used_by์˜ ๊ฒฝ์šฐ ๊ฐœ๋ฐœ์ž๋‚˜ ๋””์ž์ด๋„ˆ ํ˜น์€ ๊ธฐํš์ž ๋”ฑ ์„ธ๊ฐ€์ง€๋งŒ ์žˆ๋Š”๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”.
๋˜ํ•œ, new_or_used๋ฅผ ๋ณด๋ฉด used ํ˜น์€ new๋กœ๋งŒ ๋ฐ˜ํ™˜๋˜๋Š” ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”.

์ด๋Ÿด๋•Œ๋Š” ์—ด๊ฑฐํ˜• ์ž๋ฃŒํ˜•์„ ์‚ฌ์šฉํ•ด ์ฃผ๋ฉด ์•„์ฃผ ์ข‹์•„์š”.

_enums.js


์ตœ์ดˆ ์œ„์™€ ๊ฐ™์ด _enums.js๋ฅผ ๋งŒ๋“ค์–ด ์ค„๊ฒŒ์š”.

_enums.js

const { gql } = require('apollo-server');
const typeDefs = gql`
    enum Role {
        developer,
        designer,
        planner
    }
    
    enum NewOrUsed {
        new, used
    }`

module.exports = typeDefs;


์œ„์™€ ๊ฐ™์ด ์ฝ”๋“œ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์—ˆ์–ด์š”.

equipments.js


์ด ์ „๊นŒ์ง€๋Š” ์œ„์™€ ๊ฐ™์ด Type์ด๋ผ๊ณ  ์„ ์–ธํ•œ Schema์™€ ๋‹ฌ๋ฆฌ ์•ž์— enum์„ ๋ถ™ํ˜€์ฃผ์—ˆ๊ณ , ๊ทธ ์•ˆ์— ๋ฐ˜ํ™˜๋  ๋ฌธ์ž์—ด์„ ์ž…๋ ฅํ•œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”.


index.js


index.js 8๋ฒˆ์งธ ์ค„์— _enums.js์—์„œ ๋‚ด๋ณด๋‚ด๊ธฐํ•œ typeDefs ๊ฐ์ฒด๋ฅผ ๋ฐ›์•„ enums๋ผ๋Š” ์ƒ์ˆ˜ ๋ณ€์ˆ˜์— ๋‹ด๊ณ , ์ด๋ฅผ typeDefs๋ผ๋Š” ์ƒ์ˆ˜ ๋ฐฐ์—ด ๋ณ€์ˆ˜์— ๋‹ด์•„์ฃผ์—ˆ์–ด์š”.

equipments.js


equipments.js์— 7, 9, 14๋ฒˆ์งธ์ค„์— ์œ„์—์„œ ๋งŒ๋“  ์—ด๊ฑฐํ˜• ์ž๋ฃŒํ˜•์„ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ ์–ตํ•ด ์ฃผ์—ˆ์–ด์š”. 

Playgroud


๋‹ค์‹œ Playgroud์—์„œ Query๋ฅผ ๋‚ ๋ ค๋ณด๋ฉด ๋™์ผํ•˜์ง€๋งŒ, ์ •์ƒ์ ์œผ๋กœ ๊ฒฐ๊ณผ๊ฐ’์„ ๋ฐ›์•„์˜ค๋Š” ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”.

equipments.csv


Mock ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ 2๋ฒˆ์งธ ์ค„๊ณผ ๊ฐ™์ด ๊ธฐ์กด์— developer๋ฅผ developers๋กœ ๋ฐ”๊พธ๊ณ  ๋‹ค์‹œ ํ…Œ์ŠคํŠธ ํ•ด๋ณด๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ์š”?

Playgroud


์œ„์™€ ๊ฐ™์ด Error๊ฐ€ ๋ฐ˜ํ™˜๋˜๋Š”๋ฐ, Error ๋‚ด์šฉ์€ Enum์˜ Role์€ develpers๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์—†์–ด์š”! ๋ผ๊ณ  ๋‚˜์˜ค๋Š” ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”.


 

 

        ๐Ÿ“ฆ List Type

์ด๋ฒˆ์—๋Š” List Type์—์„œ ์•Œ์•„๋ณผ๊ฒŒ์š”.
์ด ์ž๋ฃŒํ˜•์€ ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ๋˜๋Š”๋ฐ, ์ด๋ฏธ ์ง€๋‚œ ๊ธ€์—์„œ ์•Œ์•„๋ณด๊ธด ํ–ˆ์—ˆ์–ด์š”.

equipments.js


์œ„์™€ ๊ฐ™์ด 18๋ฒˆ์งธ ์ค„์— users: [String!]์„ ์ถ”๊ฐ€ํ•ด ์ฃผ์—ˆ๋Š”๋ฐ, ์‚ฌ์šฉ์ž๋“ค์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฌธ์ž์—ด ๋ฐฐ์—ด๋กœ ๋ฐ˜ํ™˜ ๋ฐ›์„ ์ˆ˜ ์žˆ๋„๋ก ํ•ด๋ณผ๊ฒŒ์š”.

equipments.js

const resolvers = {
    Query: {
        equipments: (parent, args) => dbWorks.getEquipments(args),

        equipmentAdvs: (parent, args) => dbWorks.getEquipments(args).map((equipment) => {
            if (equipment.used_by === 'developer') {
                equipment.use_rate = Math.random().toFixed(2);
            }

            equipment.is_new = equipment.new_or_used === 'new';

            if (Math.random() > 0.5) {
                equipment.users = [];
                dbWorks.getPeople(args).forEach((person) => {
                    if (person.role === equipment.used_by && Math.random() < 0.2) {
                        equipment.users.push(person.last_name);
                    }
                })
            }

            return equipment;
        })
    },

    Mutation: {
        deleteEquipment: (parent, args) => dbWorks.deleteItem('equipments', args),
    }
}


equipments.js์— resolver์— ์œ„์™€ ๊ฐ™์ด ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ด ์ฃผ์—ˆ์–ด์š”.

์œ„ ์ฝ”๋“œ๋Š” 50% ํ™•๋ฅ ๋กœ equipment ํ•ญ๋ชฉ์— User๋ผ๋Š” ๋ฐฐ์—ด์„ ์ถ”๊ฐ€ํ•œ ๋‹ค์Œ ์‚ฌ๋žŒ๋“ค ์ค‘ ์—ญํ• ์ด equipment.used_by์— ์ผ์น˜ํ•˜๋Š” ์‚ฌ๋žŒ๋“ค ์ค‘ 20% ํ™•๋ฅ ๋กœ ํ•ด๋‹น ๋ฐฐ์—ด์„ ์ถ”๊ฐ€ํ•˜๋ผ๋Š” ์˜๋ฏธ์—์š”.

Playgroud

query {
  equipmentAdvs {
    id
    used_by
    count
    use_rate
    is_new
    users
  }
}

 

{
  "data": {
    "equipmentAdvs": [
      {
        "id": "machanical keyboard",
        "used_by": "developer",
        "count": 24,
        "use_rate": 0.91,
        "is_new": false,
        "users": null
      },
      {
        "id": "pen tablet",
        "used_by": "designer",
        "count": 15,
        "use_rate": null,
        "is_new": false,
        "users": [
          "Reynolds",
          "Simpson"
        ]
      },
      {
        "id": "notebook",
        "used_by": "planner",
        "count": 37,
        "use_rate": null,
        "is_new": true,
        "users": null
      },
      {
        "id": "ergonomic mouse",
        "used_by": "designer",
        "count": 31,
        "use_rate": null,
        "is_new": false,
        "users": null
      },
      {
        "id": "dual monitor",
        "used_by": "developer",
        "count": 20,
        "use_rate": 0.69,
        "is_new": false,
        "users": [
          "Adams"
        ]
      },
      {
        "id": "whiteboard",
        "used_by": "planner",
        "count": 12,
        "use_rate": null,
        "is_new": false,
        "users": null
      },
      {
        "id": "sketchboard",
        "used_by": "designer",
        "count": 48,
        "use_rate": null,
        "is_new": true,
        "users": [
          "Reynolds",
          "Willson",
          "Bennett",
          "Jones",
          "Cole",
          "Fisher",
          "Lawrence"
        ]
      }
    ]
  }
}


์œ„์™€ ๊ฐ™์ด Query Request๋ฅผ ๋˜์ ธ๋ณด๋ฉด users ๋ผ๋Š” ๋ฐฐ์—ด์ด ๋ฐ˜ํ™˜๋˜๋Š” ๊ฑธ ๋ณผ ์ˆ˜ ์žˆ๊ณ , ์–ด๋–ค ๊ฐ์ฒด๋Š” Null๋กœ ๋ฐ˜ํ™˜๋˜๊ณ , ์–ด๋–ค ๊ฐ์ฒด๋Š” ์‚ฌ๋žŒ ์ด๋ฆ„์ด ๋ฌธ์ž์—ด๋กœ ๋‹ด๊ธด ๋ฐฐ์—ด์ด ๋ฐ˜ํ™˜๋˜๋Š” ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”.

์œ„์—์„œ ์ด์•ผ๊ธฐ ํ•œ๋Œ€๋กœ 50% ํ™•๋ฅ ์— ๋“ค์ง€ ๋ชปํ•œ ๋ฐ์ดํ„ฐ๋Š” Users์— Null์ด ๋‹ด๊ธฐ๋Š” ๊ฑฐ์—์š”.

์„ ์–ธ๋ถ€ users: null users: [ ] users: [ ..., null ]
[String] โœ… โœ… โœ…
[String!] โœ… โœ… โŒ
[String]! โŒ โœ… โœ…
[String!]! โŒ โœ… โŒ


์œ„ ํ‘œ์™€ ๊ฐ™์ด ๋ฌธ์ž์—ด ๋ฐฐ์—ด์„ ๋‚˜ํƒ€๋‚ธ๋‹ค๊ณ  ํ–ˆ์„ ๋•Œ, ๋Š๋‚Œํ‘œ๊ฐ€ ์•ˆ ๋ถ™์„ ์ˆ˜๋„ ์žˆ๊ณ , ๋ฐฐ์—ด ์•ˆ์ชฝ์— ๋ถ™์„ ์ˆ˜๋„ ์žˆ๊ณ , ๋ฐ”๊นฅ์ชฝ์— ๋ถ™์ผ์ˆ˜๋„ ์žˆ๊ณ , ์•ˆ์ชฝ๊ณผ ๋ฐ”๊นฅ์ชฝ ๋ชจ๋‘ ๋ถ™์ผ ์ˆ˜๋„ ์žˆ์–ด์š”.

๋Š๋‚Œํ‘œ๊ฐ€ ๋ถ™์ง€ ์•Š์•˜๋‹ค๋ฉด Users ๊ฐ์ฒด๋Š” Null์ด ๋  ์ˆ˜ ์žˆ๊ณ , ํ˜น์€ ๊ทธ ์•ˆ์— ๋ฐฐ์—ด์€ ๋“ค์–ด๊ฐ€์ง€๋งŒ ๋ฐฐ์—ด ์š”์†Œ ์ค‘์— Null์ด ๋“ค์–ด๊ฐˆ ์ˆ˜๋„ ์žˆ์–ด์š”.

๋งŒ์•ฝ ๋ฐฐ์—ด ์•ˆ์— ๋Š๋‚Œํ‘œ๊ฐ€ ๋ถ™์—ˆ๋‹ค๋ฉด ์ด ๋ฐฐ์—ด ์•ˆ์— ์žˆ๋Š” ์š”์†Œ๋Š” ์ ˆ๋Œ€ Null์ด ๋“ค์–ด๊ฐˆ ์ˆ˜ ์—†์–ด์š”.
์ฐธ๊ณ ๋กœ ๋ฐฐ์—ด์ด ๋น„์—ˆ๋‹ค๋Š” ๊ฒƒ๊ณผ๋Š” ์ƒ๊ด€์ด ์—†์–ด์š”. ๋ฐฐ์—ด์ด ๋น„์—ˆ๋‹ค๋Š” ๊ฒƒ๊ณผ ๊ทธ ๋ฐฐ์—ด ์•ˆ์— ์š”์†Œ๊ฐ€ Null์ด๋ผ๋Š” ๊ฒƒ์€ ์•„์˜ˆ ๋‹ค๋ฅธ ์ด์•ผ๊ธฐ์ด๊ธฐ ๋•Œ๋ฌธ์ด์—์š”.


๋ฐฐ์—ด ๋ฐ”๊นฅ์— ๋Š๋‚Œํ‘œ๊ฐ€ ๋ถ™์—ˆ๋‹ค๋ฉด ์ด๊ฑด ๋ฐฐ์—ด์— ๋Š๋‚Œํ‘œ๊ฐ€ ๋ถ™์€๊ฑด๋ฐ, Users๋ผ๋Š” ๊ฐ์ฒด์— Null์ด ๋“ค์–ด๊ฐˆ ์ˆ˜ ์—†๋‹ค๋Š” ์˜๋ฏธ์—์š”.
์ด ์—ญ์‹œ ๋ฐฐ์—ด์ด ๋น„์—ˆ๋‹ค๋Š” ๊ฒƒ๊ณผ๋Š” ๋‹ค๋ฅธ ์˜๋ฏธ์—์š”. ๋นˆ ๋ฐฐ์—ด์ด ๋“ค์–ด ์žˆ๋Š” ๊ฑด ํ—ˆ์šฉ์ด์ง€๋งŒ, Null์ด ์˜ค๋ฉด ์•ˆ๋˜๋Š” ๊ฒƒ์ด์—์š”.

๋งˆ์ง€๋ง‰์œผ๋กœ ์•ˆ์ชฝ๊ณผ ๋ฐ”๊นฅ ์ชฝ ๋ชจ๋‘ ๋Š๋‚Œํ‘œ๊ฐ€ ๋ถ™์—ˆ๋‹ค๋ฉด users ๊ฐ์ฒด๋„ ๊ทธ๋ ‡๊ณ , ๋ฐฐ์—ด ์š”์†Œ๋„ ๋ชจ๋‘ Null์ด ์˜ฌ ์ˆ˜ ์—†๋‹ค๋Š” ์˜๋ฏธ์ด๊ณ , ๋นˆ ๋ฐฐ์—ด์€ ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๋‹ค๋Š” ์˜๋ฏธ์—์š”.


 

        ๐Ÿ“ฆ Object Type

์ด๋ฏธ ์šฐ๋ฆฌ๊ฐ€ ๊ณ„์† ์‚ฌ์šฉํ–ˆ๋˜ ์ž๋ฃŒํ˜•์ด์—์š”. ์ด๋Š” ์‚ฌ์šฉ์ž์— ์˜ํ•ด ์ •์˜๋œ ๊ฐ์ฒด ์ž๋ฃŒํ˜•์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ์–ด์š”.

equipments.js


๋ฐ”๋กœ ์œ„์™€ ๊ฐ™์ด ์„ ์–ธํ•œ Schema Type์ด ๊ฐ์ฒด ์ž๋ฃŒํ˜•์ธ ๊ฒƒ์ด์—์š”.

์ฆ‰, GraphQL์„ ์‚ฌ์šฉํ•  ๋•Œ, Scala Type์œผ๋กœ ์ด๋ค„์ง„ ์—ฌ๋Ÿฌ ๊ฐ์ฒด Type๋“ค์„ ์ •์˜ํ•ด์„œ ์„œ๋ฒ„๋ฅผ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ๊ฑฐ์—์š”.

 

 

 

 

GraphQL๊ณผ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋กœ ๊ฐœ๋ฐœํ•˜๋Š” ์›น ์„œ๋น„์Šค:์„ค๊ณ„๋ถ€ํ„ฐ ๊ฐœ๋ฐœ·๋ฐฐํฌ๊นŒ์ง€ ๋”ฐ๋ผ ํ•˜๋ฉฐ ์™„์„ฑํ•˜๋Š” ์›น ํ’€

COUPANG

www.coupang.com

"์ด ํฌ์ŠคํŒ…์€ ์ฟ ํŒก ํŒŒํŠธ๋„ˆ์Šค ํ™œ๋™์˜ ์ผํ™˜์œผ๋กœ, ์ด์— ๋”ฐ๋ฅธ ์ผ์ •์•ก์˜ ์ˆ˜์ˆ˜๋ฃŒ๋ฅผ ์ œ๊ณต๋ฐ›์Šต๋‹ˆ๋‹ค."

 

 

 

๐Ÿง ์ฐธ๊ณ  ์ž๋ฃŒ

ํ•ด๋‹น ๋‚ด์šฉ์€ ์•„๋ž˜ ๊ฐ•์˜๋ฅผ ๊ณต๋ถ€ํ•˜๋ฉด์„œ ์ •๋ฆฌํ•œ ๋‚ด์šฉ์ž„์„ ์•Œ๋ ค ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

 

[๋ฌด๋ฃŒ] ์–„ํŒํ•œ GraphQL๊ณผ Apollo - ์ธํ”„๋Ÿฐ | ๊ฐ•์˜

โšก ์งง๊ณ  ๊ตต์€ ์ „์ฒด 90๋ถ„ ๊ฐ•์ขŒ! ์‚ฌ์ดํŠธ์˜ ์ฝ”๋“œ๋“ค์„ ๋ณต๋ถ™ํ•˜๋ฉฐ ๋น ๋ฅด๊ฒŒ GraphQL์„ ๋ฐฐ์šฐ๊ณ  ์•„ํด๋กœ ์‚ฌ์šฉ๋ฒ•์„ ์ตํžˆ์„ธ์š”., โฑ ์—ฌ๋Ÿฌ๋ถ„์˜ ์‹œ๊ฐ„์€ ์†Œ์ค‘ํ•ฉ๋‹ˆ๋‹ค. [์‚ฌ์ง„] ๐ŸŽข  GraphQL์ด ๋ญ”๊ฐ€์š”? ์„œ๋น„์Šค๋ฅผ ๊ตฌ์„ฑํ•˜๋Š”

www.inflearn.com

 

 

 

 

์นด์นด์˜คํŽ˜์ด | ๋งˆ์Œ ๋†“๊ณ  ๊ธˆ์œตํ•˜๋‹ค

์—ฌ๊ธฐ๋ฅผ ๋ˆŒ๋Ÿฌ ๋งํฌ๋ฅผ ํ™•์ธํ•˜์„ธ์š”.

qr.kakaopay.com

 

 

 

 

728x90
๋ฐ˜์‘ํ˜•