Upgrade to Pro — share decks privately, control downloads, hide ads and more …

GraphQL を利用したアーキテクチャの勘所 / Architecture practice...

qsona
April 21, 2021

GraphQL を利用したアーキテクチャの勘所 / Architecture practices with GraphQL

iCARE Dev Meetup 20 で発表した資料です #icare_meetup

p.7,8,61 https://graphql.org/
p.18 https://twitter.com/a_suenami/status/1379270185207484417
p.33 [SQLQL - Qiita](https://qiita.com/yancya/items/4b7979d83cbf6af9b819)
p.33 https://twitter.com/onk/status/912491093127598080
p.35 [【エンジニアブログ】ダイニーのエンジニアリング3カ条|dinii(ダイニー)公式|note](https://note.com/dinii/n/n9be778bd7da3)
p.36 [Smart UI パターンが再評価される世界 - id:onk のはてなブログ](https://onk.hatenablog.jp/entry/2020/11/11/024531)
p.41 [Sam Newman - Backends For Frontends](https://samnewman.io/patterns/architectural/bff/)
p.43 [GraphQL for server-side resource aggregation | Technology Radar | ThoughtWorks](https://www.thoughtworks.com/radar/techniques/graphql-for-server-side-resource-aggregation)
p.47 [DroidKaigi 2019 登壇報告 "Server-side Kotlin for Frontend: 複雑なAndroidアプリ開発に対するアプローチ"|qsona|note](https://note.com/qsona/n/nf927588011b4)
p.50 [Quipper Japan | 採用情報](https://career.quipper.com/jp/)
p.54 [Schema-Driven Development とアジャイルなチーム|qsona|note](https://note.com/qsona/n/nfc73a8e82dff)

qsona

April 21, 2021
Tweet

More Decks by qsona

Other Decks in Programming

Transcript

  1. whoami • @qsona • Web Engineer at Quipper Ltd •

    Microservices / Rails / Node.js / GraphQL ※ ຊࢿྉʹొ৔͢ΔϦϯΫ͸ Speaker Deck ͷ֓ཁཝʹ
 ͢΂ͯࡌ͓͖ͤͯ·͢
  2. Agenda • 1. GraphQL ͱΞʔΩςΫνϟ • Better Web API ͱͯ͠ͷ

    GraphQL • GraphQL as a Service (Hasura / AppSync) • 2. GraphQL ஫ҙ͢΂͖ύλʔϯू
  3. ※ Usecaseͱ͸? Resourceͱ͸? (SBQI2-2VFSZ (SBQI2-4DIFNBBOE5ZQFT 6TFDBTF 3FTPVSDF 1SFTFOUBUJPO %PNBJO 4ZTUFNPG&OHBHFNFOU

    4ZTUFNPG3FTPVSDF 'SPOUFOE #BDLFOE ྨࣅͷ֓೦
 (ࣅͨΑ͏ͳํ๏ Ͱେ͖͘ೋ෼͠ ͍ͯΔྫ)
  4. Usecase-based Web API ͷ໰୊఺ • ࣅͨΑ͏ͳAPI͕ཚཱ͠΍͍͢ • ຖ౓API࡞Δͷ͕໘౗ =>
 ෳ਺ͷϢʔεέʔεʹରԠ͢Δ

    ਆAPI ͕Ͱ͖Δ܏޲ • Usecase ͸มΘΓ΍͍͕͢ɺͦΕʹԠͯ͡ຖ౓APIΛमਖ਼͢Δඞཁ͕͋Δ • ޙํޓ׵ੑΛอͭͨΊʹɺमਖ਼Ͱ͸ͳ͘৽نAPI௥Ճ͕ඞཁʹͳΔ͜ͱ΋ ଟ͍
  5. Resource-based Web API • ΞϓϦέʔγϣϯͦͷ΋ͷͷ࢓༷ʹ߹Θͤͯ Web API Λ࡞Δ • (جຊతʹ͸

    API ఏڙଆͷ౎߹Ͱ࡞Δ) • ྫ: (஫ҙਂ͘ઃܭ͞Εͨ) RESTful API
  6. GraphQL Web API ઃܭͷצॴ • جຊతʹ Resource-based API ͱͯ͠࡞Δ (GraphQL

    ͷྑ͞Λ׆͔ͨ͢Ίʹ) • GraphQL Schema / Types ͕ Resource Λද͢ • query ͕ Usecase Λද͢ • Query Type ͷ field ͕ endpoint Ͱ͋Δ • ͭ·ΓɺResource ϕʔεͷAPIͱ Usecase ϕʔεͷAPIͷ
 ྑ͍ͱ͜ΖΛཱ྆Ͱ͖Δ!
  7. GraphQL Web API ઃܭͷצॴ • ஫ҙਂ͘ Resource (≒ GraphQL Schema,

    Types) Λ
 ఆ͍ٛͯ͘͠ඞཁ͕͋Δ • ৗʹߴ͍ϨϕϧͷϞσϦϯάྗ͕ٻΊΒΕΔ • Type ͷཻ౓Λ੔͑Δ (ςʔϒϧͱ1:1ͱ͸ݶΒͳ ͍) • (஫ҙਂ͘) RESTful API Λ࡞Δͱ͖ͱɺجຊతʹ͸ม ΘΒͳ͍
  8. ஫ҙਂ͍ Resource ઃܭ (※ ݸਓతͳϓϥΫςΟεͰ͢) • ·ͣ͸ Usecase Λ͖ͪΜͱཧղ͢Δ •

    ಉ࣌ʹɺσʔλઃܭΛΠϝʔδ͢Δ • ҎԼΛຬͨ͢εΩʔϚΛߟ͑Δ • ϢʔεέʔεΛࣗવʹຬͨͤΔ (ඞཁҎ্ʹෳࡶͳ query ΍ client ࣮૷ʹͳΒͳ͍) • σʔλઃܭ͔Βࣗવʹ resolvers ͷ࣮૷͕Ͱ͖Δ • Ϗδωεతͳڞ௨ཧղɾڞ௨ݴޠΛਖ਼͘͠൓ө͍ͯ͠Δ
  9. GraphQL Web API ࣮૷ͷ೰Έॴ (֓ཁ) • (RESTful API ʹൺ΂ͯ) ΫΤϦͷࣗ༝౓͕ߴ͗͢Δ͜ͱʹΑΓ


    ύϑΥʔϚϯε௿ԼΛҾ͖ى͜͢Մೳੑ͕͋Δ • యܕతʹ͸ N+1 ໰୊ • ରॲ๏ • Dataloader Pattern • Ϣʔεέʔεͷ؅ཧͱଥڠ
  10. RESTful API ͷ৔߹ Α͋͘Δઃܭख๏ • Ұཡը໘: GET /posts • ഑ྻΛฦ͢

    • 1݅ͣͭͷ৘ใྔ͸গͳ͍ • ৄࡉը໘: GET /posts/:id • ৘ใྔΛଟ͘͢Δ
  11. GraphQL API ͷ৔߹ • Schema ͸ 1ͭͰ྆ํʹରԠ͢Δ • Usecase Λجຊతʹҙࣝ͠ͳ͍

    • Ұཡը໘ɺৄࡉը໘ͦΕͧΕͰ
 ඞཁͳσʔλΛऔಘ͢Δ query Λॻ͘
  12. Dataloader ύλʔϯ • యܕతʹ͸ Dataloader ύλʔϯΛద༻͢΂͖ • resolver Λ஗ԆධՁ͠ɺόονͰ࣮ߦ͢Δ࢓૊Έ •

    ͕ɺͦ͏؆୯ʹ͍͔ͳ͍৔߹΋͋Δ • ྫ: author Ͱ͸ͳ͘ authors (ෳ਺) Ͱɺ
 ιʔεͱͳΔςʔϒϧ͕ෳ਺͋Γɺ͞Βʹιʔτ͕ඞཁ...
 ͷΑ͏ͳෳࡶͳέʔεͩͱ Dataloader Λద༻͢Δͷ͕೉͍͠৔߹͕͋Δ
  13. Persisted Queries (ҎԼ͸ӡ༻ํ๏ͷҰྫ) • ΫϥΠΞϯτ͕౤͛͏ΔΫΤϦΛɺࣄલʹ GraphQL API αʔόʔʹొ࿥͢Δख๏ • ΫϥΠΞϯτͷϏϧυɾσϓϩΠ࣌ʹ

    Pull Request Λ౤͛Δ • Backend ΤϯδχΞ͕֬ೝ͠ɺ໰୊ͳ͚Ε͹Ϛʔδ • N+1 ໰୊ෆՄආͷΑ͏ͳΫΤϦͷ৔߹ɺFrontend ΤϯδχΞͱ૬ஊ͠ɺͲ͏ͯ͠΋ඞཁͳΒ αʔόʔଆͰରԠ͢Δ • ొ࿥͞ΕͨΫΤϦҎ֎͸ɺ஄͘Α͏ʹ͓ͯ͘͠
  14. Persisted Queries Λར༻͢ΔϝϦοτ • ϢʔεέʔεΛαʔόʔαΠυͰ؅ཧͰ͖Δ • αʔόʔαΠυͰ࠷దԽ͢΂͖ resolvers ͕ͲΕ͔Θ͔Δ •

    API ͷഁյతมߋ/ഇࢭ͕εϜʔζʹߦ͑Δ • ϦΫΤετͷϖΠϩʔυΛݮΒͤΔ • Query ͝ͱʹ id ΛৼͬͨΓ hash ஋Λܭࢉ͓͖ͯ͠ɺ
 ࣮ࡍͷϦΫΤετͰ͸ Query ͦͷ΋ͷͰ͸ͳ͘ id / hash஋ΛૹΔ • POST Ͱ͸ͳ͘ GET ϦΫΤετ΋࢖͑ΔΑ͏ʹͳΔ => ΩϟογϡՄೳʹ
  15. Better Web API ͱͯ͠ͷ GraphQL ઃܭख๏ ·ͱΊ • Resource-based API

    ͱͯ͠ઃܭ͢Δ • ҰํɺUsecase (query) ͷ͜ͱ΋
 ͋Δఔ౓ཧղ͠ͳ͕Βઃܭ͢ΔͱΑ͍ • ࢖͍΍͍͢ API ʹͳΔ • ࠷దԽΛޙճ͠ʹͰ͖Δ
  16. GraphQL as a Service • ΋ͱ΋ͱ GraphQL ͸ Web API

    Λ૝ఆͯ͠࡞ΒΕͨ • ͦͷޙɺDatastore ʹରͯ͠ GraphQL ͱͯ͠ΫΤϦͰ͖Δ
 ϥΠϒϥϦ/੡඼͕ొ৔ͨ͠ • Graphcool (ऴྃ), Prisma 1 (৽ن։ൃͳ͠), PostGraphile • Web API Λࣗ෼Ͱ࣮૷͠ͳͯ͘΋ɺσʔλετΞΛ༻ҙ͢Δ͚ͩͰ
 ؆୯ʹ GraphQL Web API ΛఏڙͰ͖ΔαʔϏε͕ొ৔ͨ͠ • Hasura, AppSync (͜ΕΒΛҰ୴উखʹ GraphQL as a Service ͱݺͿ͜ͱʹ͠·͢)
  17. ֦ுੑͷߴ͍ GraphQL as a Service • Resolvers ͱͯ͠ɺσʔλετΞݺͼग़͠Ҏ֎΋બ୒Ͱ͖Δ • AppSync:

    AWS Lambda, HTTP resolvers • Hasura: Remote Schema • ಛʹ Hasura ͷ৔߹ɺ࠷ऴతʹ͸୯ͳΔ GraphQL Gateway
 ͱͯ͠ଘࡏͰ͖Δ
  18. ࣄྫ: dinii ࣾ͞Μͷ Hasura ͷ࢖͍ํ • গ਺ (5%) ͷ Query

    ͱ
 ଟ਺ (80%) ͷ Mutation Λ
 ผཱͯͷGraphQL αʔόʔʹྲྀ ͍ͯ͠Δ • ։ൃ͕ෳࡶԽ͢ΔʹͭΕɺ͜ͷ ׂ߹͸૿͍͑ͯ͘ͷͰ͸ͳ͍͔ (qsona ͷݟղͰ͢) Ҿ༻ݩ: ʲΤϯδχΞϒϩάʳμΠχʔͷΤϯδχΞϦϯά3Χ৚ʛdiniiʢμΠχʔʣެࣜʛnote https://note.com/dinii/n/n9be778bd7da3
  19. Command - Query Separation • Query ͷ΄ͱΜͲͰ Hasura Λ
 ௚઀࢖͍͑ͯΔɺศར

    • ҰํͰ Mutation ͸جຊతʹಛ༗ ͷυϝΠϯϩδοΫ͕ඞཁʹͳͬ ͯ͘Δ͜ͱ͕ଟ͍ • => CQS ύλʔϯʹ͍ۙ
  20. ॳظ࣮૷ίετ௿ + কདྷతͳ֦ு˕ Hasura ͷྑͦ͞͏ͳͱ͜Ζ • ॳظ͸ Hasura ͷ API

    Λͦͷ··࢖͏͜ͱͰɺ࣮૷ίετΛԼ͛ΒΕΔ • ࣮૷͕ෳࡶʹͳ͖ͬͯͨΒ Remote Schema Λ׆༻͠ɺ
 ϩδοΫΛόοΫΤϯυʹد͍ͤͯ͘ɻ
 কདྷతͳ֦ுੑ΋୲อͰ͖Δ • (ݸਓతʹ͸ Firebase ΑΓ΋༗๬ࢹ͍ͯ͠·͕͢ɺͲͪΒ΋·ͩ࢖ͬͨ͜ͱͳ͍...)
  21. BFF (Backends for Frontends) • Microservices จ຺ͰΑ͘ొ৔͢Δ • Frontend ͷͨΊʹαʔόʔΛཱͯɺ

    Backend Services Λू໿ͯ͠ Frontend ޲͚ͷ API Λఏڙ͢Δύλʔϯ • Frontend ΤϯδχΞ͕։ൃɾӡ༻͢Δ ͜ͱ͕ਪ঑͞ΕΔ
  22. GraphQL as BFF • Backend APIs ͸యܕతʹ͸ REST ΍ gRPC

    ͳͲͰఏڙ͞Ε͍ͯΔͱ͢Δ • BFF ͱͯ͠ GraphQL API αʔόʔΛ ࡞Δύλʔϯ
  23. GraphQL for server-side resource aggregation | Technology Radar | ThoughtWorks

    https://www.thoughtworks.com/radar/techniques/graphql-for-server-side-resource-aggregation
  24. GraphQL for server-side resource aggregation | Technology Radar | ThoughtWorks

    https://www.thoughtworks.com/radar/techniques/graphql-for-server-side-resource-aggregation HOLD (qsona ͷݟղͰ͢)
  25. GraphQL as BFF ͷ໰୊఺ • BFF ͱ͸ͦ΋ͦ΋ Frontend ͷͨΊͷ Usecase

    Λఆٛ͢Δ૚ • GraphQL Λར༻͢Δͱɺquery ͕ Usecase ʹͳΔ • => Usecase ͕2૚ʹͳΓɺ໾ׂ͕ඃΔ
  26. GraphQL as BFF ͷ۩ମతͳ໰୊఺ • Backend APIs (REST/RPC) Λ GraphQL

    ʹม׵͢Δίετ͕ߴ͍ • ୯ͳΔϓϩτίϧͷม׵͚ͩͰͳ͘ɺ GraphQL resolvers ʹม׵͢Δ্Ͱຊ࣭తͳΠϯ ϐʔμϯεϛεϚον͕ଘࡏ͢Δ • ͞·͟·ͳ Usecase ʹରԠ͠͏Δ Schema Λ
 ϝϯςφϯε͚ͭͮ͠Δίετ • ҰํͰɺ࢖ΘΕΔ Usecase ͸ݶΒΕ͍ͯΔ • ࢖͏ͷ͸ࣗ෼͚ͨͪͩ (શੈքʹެ։͢ΔΘ͚Ͱ͸ͳ͍)
  27. ୅ସख๏ͷఏҊ (1) • BFF Λ Usecase-based API ͱͯ͠࡞Δ • ϓϩτίϧ͸

    JSON over HTTP Ͱ΋͍͍͠ɺ
 RPC ܥͷԿ͔Λ࢖ͬͯ΋Α͍ • GraphQL ͸ར༻͠ͳ͍ • (͜ͷ࿏ઢͰ BFF Λ࡞Δ৔߹ɺ
 ྑ͚Ε͹ӈͷࢿྉΛࢀߟʹͯ͠Έ͍ͯͩ͘͞)
  28. ୅ସख๏ͷఏҊ (2) • Backend Services GraphQL API ͱ࣮ͯ͠૷͢Δ • GraphQL

    Gateway αʔϏεΛஔ͘ • ٕज़ͱͯ͠͸ Schema Stitching ΍ Apollo Federation Λݕ౼ • => ϓϩτίϧͷม׵ΛखͰ΍Δඞཁ͕ͳ͘ͳΔ • GraphQL Gateway ͸ Backend دΓͷΤϯδχΞ͕؅ཧ͢Δ • جຊతʹ Backend ͷ΋ͷΛ࢖͍΍͘͢͢Δ͚ͩͰɺϩδοΫ͸جຊతʹஔ͔ͳ͍
  29. ৽ن։ൃϓϩδΣΫτʹ͍ͭͯ • ։ൃ͢Δ΋ͷ • iOS / Android / PC Web

    Apps • Backend APIs • ίϯςϯπΛ؅ཧ͢ΔγεςϜ • ։ൃظؒ: > 1೥ • ։ൃऀͷਓ਺: > 10ਓ
  30. ৽ن։ൃʹ GraphQL Λશ໘࠾༻ • client => gateway => backends
 શମͰ

    GraphQL Λ࠾༻ • gateway ͸ schema stitching Λར༻͍ͯ͠Δ • ͦͷଞར༻ٕज़ • Ruby on Rails • Node.js + TypeScript + Apollo Server + Prisma 2 • React, Apollo Client
  31. GraphQL ࠾༻ͷಈػ • native devs (iOS/Android) ͱ web devs (Backend

    + Web Frontend) Ͱ
 ͏·͘ڠಇͰ͖ΔΑ͏ʹ͔ͨͬͨ͠ • => Schema-Driven Development Λ࠾༻͍ͨ͠ • (ҰํͰ BFF ύλʔϯΛճආ͔ͨͬͨ͠) • ͞ΒʹɺͰ͖Δ͚ͩશମͷ։ൃ޻਺΋ݮΒ͍ͨ͠
  32. GraphQL Λશ໘࠾༻ͯ͠Α͔ͬͨ͜ͱ • Schema-Driven Development ʹΑΓ
 ίϛϡχέʔγϣϯͷϩε͕গͳ͘ɺ
 ҆ఆͯ͠։ൃΛਐΊΒΕͨ • ܨ͗͜Έ͕௒εϜʔζ

    • backend / frontend ͦΕͧΕ ~9ϲ݄։ൃͨ͠΋ͷΛ
 1िؒͰશ෦ܨ͗͜Έ׬ྃͨ͠ • GraphQL Gateway ͕ͱͯ΋ศརͰɺ͔ͭ
 ։ൃ޻਺͕΄΅͔͔Βͳ͍
  33. We're hiring! • ͻ͖͖ͭͮɺઈࢍ৽ن։ൃதͰ͢! • ӡ༻ϑΣʔζʹ޲͚ͯɺ͞ΒͳΔٕज़νϟϨϯδΛ͍͖͍ͯͨ͠ • ྫ) Persisted Queries

    ͷϑϩʔ੔උ, Apollo Federation ͷݕ౼, etc... • GraphQL, Microservices ͸΋ͪΖΜ
 ϑϩϯτΤϯυ͔ΒόοΫΤϯυ·Ͱ
 ޿͍ٕज़ʹ৮ΕΒΕΔػձ͋Γ • ·ͣ͸ΧδϡΞϧ໘ஊ͔Βɺͥͻ͝Ԡื͍ͩ͘͞ 😁
  34. Repository ύλʔϯ • API ݺͼग़͠(ͳͲ)Λϥοϓ͠ɺ
 Domain Model Λฦ͢ϨΠϠʔ • Usecase

    ͔Β࢖ΘΕΔ • API ҎԼͷ۩ମతͳৄࡉΛӅṭ͢Δ͜ͱ͕Ͱ͖Δ • "෗ഊ๷ࢭ૚"
  35. Repository ύλʔϯͱ GraphQL • ͋·Γ૬ੑ͕Α͘ͳ͍ • Usecase ==> Repository ==[query]==>

    GraphQL API • query ͸ Usecase Ͱ͋Δͱଊ͑Δͱ
 Domain ͷ૚͕ Usecase Λ஌͍ͬͯΔ͜ͱʹͳΓɺ͓͔͍͠ • => query ͕ Usecase Λදͤͳ͘ͳΓɺGraphQL ͷྑ͕͞ੜ͖ʹ͍͘ • over-fetching ͳͲͷ໰୊͕ى͖΍͘͢ͳΔ
  36. Fragment Colocation • ྫ: 1ը໘಺ʹෳ਺ͷ Usecase / Component ͕͋Γɺ
 ͦΕΒͷσʔλऔಘΛ1ϦΫΤετʹ·ͱΊ͍ͨ

    • Usecase (Component) ͸
 ଟஈʹͳ͍ͬͯΔ (ωετ) ͜ͱ΋͋Δ • ֤ Usecase / Component ͝ͱʹ fragment Λ΋ͭ (colocation) • ্Ґͷ Usecase Ͱ fragment Λ·ͱΊͯ1ͭͷ query ʹ͢Δ
  37. GraphQL ͱΞʔΩςΫνϟ·ͱΊ • query ͕ Usecase
 Schema / Types ͕

    Resource Ͱ͋Δɺͱଊ͑Α͏ • ͦͷ্Ͱɺطଘͷઃܭख๏ͱ૊Έ߹Θͤͯߟ͑Α͏ • Client / Server ͷہॴతͳࢹ఺͚ͩͰͳ͘ɺ
 େہతʹݟͯઃܭ͠Α͏