©2021 Wantedly, Inc.GraphQL ಋೖͷলͱ࠶ઓSponsor LTJSConf JP 20212021-11-27 @izumin5210
View Slide
©2021 Wantedly, Inc.@izumin5210‣ "SDITRVBE8BOUFEMZ *OD #BDLFOE 8FC'SPOUFOEͷ5FDI-FBEతͳ͜ͱ͍ͯ͠·͢ ද࡞ HSBQJ(PͷH31$TFSWFS༻ϚΠΫϩϑϨʔϜϫʔΫ 6*σβΠϯγεςϜͷ3FBDU࣮ͷઃܭ (SBQI2-(BUFXBZͷઃܭɾ࣮ ˡࠓ͜ͷʣ‣ ͖ͳ5$QSPQPTBM&SSPS$BVTF IUUQTHJUIVCDPNUDQSPQPTBMFSSPSDBVTF ͍ͭͷ·ʹ͔4UBHFʹͳͬͯͨ
©2021 Wantedly, Inc.JavaScript and Wantedlyhttps://speakerdeck.com/wantedly/for-engineers?slide=22
©2021 Wantedly, Inc.JavaScript and WantedlyόοΫΤϯυͰҰ෦ར༻ ʢQVQQFUFFSʹΑΔը૾ੜͳͲʣੈʹ͔Ε͍ͯΔ͕ɺ࠷৽ͷͷ/FYUKTʹҠߦ 👉 IUUQTEPDTXBOUFEMZEFWfiFMETBQQMJDBUJPOGSPOUFOEBSDIJUFDUVSFhttps://speakerdeck.com/wantedly/for-engineers?slide=22
©2021 Wantedly, Inc.JavaScript and WantedlyόοΫΤϯυͰҰ෦ར༻ ʢQVQQFUFFSʹΑΔը૾ੜͳͲʣੈʹ͔Ε͍ͯΔ͕ɺ࠷৽ͷͷ/FYUKTʹҠߦ 👉 IUUQTEPDTXBOUFEMZEFWfiFMETBQQMJDBUJPOGSPOUFOEBSDIJUFDUVSFhttps://speakerdeck.com/wantedly/for-engineers?slide=22https://docs.wantedly.dev/fields/application/frontend-architecture
©2021 Wantedly, Inc.JavaScript and Wantedlyhttps://speakerdeck.com/wantedly/for-engineers?slide=22ࠓ͜Εͷ
©2021 Wantedly, Inc.GraphQL and Wantedly࠷ॳͷ GraphQL ಋೖ‣ 2019͡Ί͝ΖͰɺWantedly Visit ͷاۀଆը໘ʹಋೖͨ͠ͷ͕࠷ॳ‣ Web Frontend ʹ͓͚Δ՝Λղܾ͢ΔͨΊʹಋೖ- Web Frontend Ͱܕ͖ͷεΩʔϚͰɺੜ࢈ੑߴ͘։ൃ͍ͨ͠- ෳϚΠΫϩαʔϏε͔ΒͷσʔλΛू͠ɺϑϩϯτΤϯυͰ͍͍͢ܗʹม͍ͨ͠‣ ͍ΘΏΔ “BFF” తͳΘΕํ- ϑϩϯτΤϯυدΓͷ։ൃऀ͕εΩʔϚઃܭɾ࣮Λ͓͜ͳ͏- ʢϞόΠϧͰͬͯͳ͔ͬͨͷɺ୯७ʹݕূͰ͖ͯͳ͔ͬͨͷ͋Δʣ
©2021 Wantedly, Inc.GraphQL and WantedlyWeb Frontend GraphQL servermicroservicemicroservicemicroserviceJSON / HTTPProtobuf / gRPC
©2021 Wantedly, Inc.GraphQL and WantedlyৼΓฦΓ - ࠷ॳͷ GraphQL ಋೖ‣ Web Frontend ʹ͓͚Δੜ࢈ੑ͔֬ʹ্ͨ͠- εΩʔϚ͔Βਖ਼͍͠ܕ͕ੜ͞Εͯศར- ঢ়ଶཧ Apollo Client ʹͤΔ͜ͱ͕Ͱ͖ͨ‣ ҰํͰɺΞʔΩςΫνϟશମͱͯ͠࠷దͳܗʹͳ͔ͬͨผ‣ Wantedly People(mobile app), Profile ଆͷνʔϜ͕ BFF Λར༻͢Δͱ͖ʹ͕ݦࡏԽͨ͠
©2021 Wantedly, Inc.Wantedly People(mobile app) ArchitectureMobile appgRPCservermicroservicemicroservicemicroserviceJSON / HTTPProtobuf / gRPCgrpc-gatewaygRPCservergrpc-gatewaymicroservicemicroservice
©2021 Wantedly, Inc.Wantedly People(mobile app) ArchitecturegRPCservermicroservicemicroservicemicroserviceJSON / HTTPProtobuf / gRPCgrpc-gatewaygRPCservergrpc-gatewaymicroservicemicroserviceMobile app‣ όοΫΤϯυͱϞόΠϧ͕ڠಇͯ͠εΩʔϚΛઃܭ͢Δ- ओಋόοΫΤϯυʹͳΔ͜ͱଟ͍- ϚΠΫϩαʔϏεɾΞʔΩςΫνϟͰɺόοΫΤϯυͷγεςϜؒ௨৴εΩʔϚ͕ॏཁ‣ Protobuf IDL ͔Β OpenAPI ͷεΩʔϚੜͰ͖ΔͨΊɺϞόΠϧଆͰεΩʔϚΛ׆༻ՄೳProtobuf ʹΑΔεΩʔϚۦಈ։ൃ
©2021 Wantedly, Inc.Wantedly People(mobile app) ArchitecturegRPCservermicroservicemicroservicemicroserviceJSON / HTTPProtobuf / gRPCgrpc-gatewaygRPCservergrpc-gatewaymicroservicemicroserviceMobile app‣ όοΫΤϯυͱϞόΠϧ͕ڠಇͯ͠εΩʔϚΛઃܭ͢Δ- ओಋόοΫΤϯυʹͳΔ͜ͱଟ͍- ϚΠΫϩαʔϏεɾΞʔΩςΫνϟͰɺόοΫΤϯυͷγεςϜؒ௨৴εΩʔϚ͕ॏཁ‣ Protobuf IDL ͔Β OpenAPI ͷεΩʔϚੜͰ͖ΔͨΊɺϞόΠϧଆͰεΩʔϚΛ׆༻ՄೳProtobuf ʹΑΔεΩʔϚۦಈ։ൃhttps://www.wantedly.com/companies/wantedly/post_articles/309513
©2021 Wantedly, Inc.Wantedly People(mobile app) ArchitectureMobile app gRPCservermicroserviceJSON / HTTPProtobuf / gRPCgrpc-gatewaymicroserviceWeb Frontend GraphQL servermicroservicemicroservice
©2021 Wantedly, Inc.Multi-application and Microservices and GraphQLMobile app gRPC- ʮͲ͕ͬͪ࠷৽͚ͩͬʁʯ‣ Protobuf to GraphQL ͷมίʔυΊͬͪΌॻ͘ϋϝʹͳΔGraphQL εΩʔϚΛ࣋ͭProtobuf εΩʔϚΛ࣋ͭ
©2021 Wantedly, Inc.Mobile app gRPCservermicroserviceJSON / HTTPProtobuf / gRPCgrpc-gatewaymicroserviceGraphQL servermicroservicemicroserviceWeb Frontendͦͦ…‣ GraphQL ಋೖͷେ͖ͳϝϦοτͱͯ͋ͬͨ͠ͷ…- ʮ ܕͷ͋ΔεΩʔϚͱ͔ͦ͜Βͷ࣮ͷੜʯ‣ Protobuf Λར༻͢ΕɺࣅͨΑ͏ͳ͜ͱͰ͖ͯ͠·͏
©2021 Wantedly, Inc.Reconsider “GraphQL”GraphQL ΛೖΕΔతΛ࠶ߟ͢Δ‣ GraphQL ͷϝϦοτ࠶ߟ- ܕͷ͋ΔεΩʔϚͱɺ͔ͦ͜Βͷίʔυੜ- ϑΟʔϧυɾؔ࿈ΦϒδΣΫτΛબతʹɾॊೈʹऔಘͰ͖ΔΠϯλϑΣʔε- σʔλܗࣜɾ௨৴ํࣜͱʹҰൠతͳϑΥʔϚοτʢJSON over HTTPʣͳͷͰɺͲ͜Ͱಈ͘‣ Wantedly ͰकΓ͍ͨͱ͜Ζ- όοΫΤϯυͷγεςϜؒ௨৴ͰεΩʔϚۦಈ։ൃ͍ͨ͠ʢطଘͷࢿ࢈Λ͍͍ͨͷͰɺgRPC ͍͍ͨʣ- 1ͭͷεΩʔϚΛઈରతͳιʔεͱͯ͠ѻ͍͍ͨ
©2021 Wantedly, Inc.Reconsider “GraphQL”GraphQL ΛೖΕΔతΛ࠶ߟ͢Δ‣ GraphQL ͷϝϦοτ࠶ߟ- ܕͷ͋ΔεΩʔϚͱɺ͔ͦ͜Βͷίʔυੜ- ϑΟʔϧυɾؔ࿈ΦϒδΣΫτΛબతʹɾॊೈʹऔಘͰ͖ΔΠϯλϑΣʔε- σʔλܗࣜɾ௨৴ํࣜͱʹҰൠతͳϑΥʔϚοτʢJSON over HTTPʣͳͷͰɺͲ͜Ͱಈ͘‣ Wantedly ͰकΓ͍ͨͱ͜Ζ- όοΫΤϯυͷγεςϜؒ௨৴ͰεΩʔϚۦಈ։ൃ͍ͨ͠ʢطଘͷࢿ࢈Λ͍͍ͨͷͰɺgRPC ͍͍ͨʣ- 1ͭͷεΩʔϚΛઈରతͳιʔεͱͯ͠ѻ͍͍ͨProtobuf IDL Ͱهड़͞ΕͨεΩʔϚʹυϝΠϯ͕ࣝө͞Ε͍ͯΔυΩϡϝϯτ͕ࣗવݴޠͰهड़͞Ε͍ͯΔwantedly/apis ͱ͍͏ϦϙδτϦͰதԝཧ͞Ε͓ͯΓɺ͔ͦ͜Β֤ݴޠ࣮͕ࣗಈੜ͞ΕΔ͜ͷϦϙδτϦʹ͋ΒΏΔ͕ࣝूੵ͞ΕɺϓϩμΫτ։ൃΛՃ͍ͤͯ͞Δʢৄ͘͠ʮProtocol Buffers ʹΑΔϓϩμΫτ։ൃͷεεϝ - API ։ൃͷࠓੲ - | Wantedly Engineer BlogʯΛࢀরʣʢ…ͷͰɺεΩʔϚ̎ॏཧʹΑΓ৴པੑ͕طଘ͞ΕΔͷࠔΔʣ
©2021 Wantedly, Inc.Wantedly ͷϓϩμΫτੑ࣭https://speakerdeck.com/wantedly/for-engineers?slide=22
©2021 Wantedly, Inc.Wantedly ͷϓϩμΫτੑ࣭https://speakerdeck.com/wantedly/for-engineers?slide=22‣ Web ͱϞόΠϧͰυϝΠϯઃܭಉ͡- ϓϩμΫτΛލ͍Ͱʢڞ௨෦ʣಉ͡‣ ΞϓϦɾػೳʹΑͬͯใྔͷଟՉ͕͋Δ- e.g. ϢʔβଆϓϩϑΟʔϧͱاۀଆϓϩϑΟʔϧʢεΧτૹΔͱ͖ʹݟΔͭʣใྔ͕ҧ͏
©2021 Wantedly, Inc.Reconsider “GraphQL”GraphQL ΛೖΕΔతΛ࠶ߟ͢Δ‣ GraphQL ͷϝϦοτ࠶ߟ• ܕͷ͋ΔεΩʔϚͱɺ͔ͦ͜Βͷίʔυੜ- ϑΟʔϧυɾؔ࿈ΦϒδΣΫτΛબతʹɾॊೈʹऔಘͰ͖ΔΠϯλϑΣʔε- σʔλܗࣜɾ௨৴ํࣜͱʹҰൠతͳϑΥʔϚοτʢJSON over HTTPʣͳͷͰɺͲ͜Ͱಈ͘‣ Wantedly ͰकΓ͍ͨͱ͜Ζ• όοΫΤϯυͷγεςϜؒ௨৴ͰεΩʔϚۦಈ։ൃ͍ͨ͠ʢطଘͷࢿ࢈Λ͍͍ͨͷͰɺgRPC ͍͍ͨʣ• 1ͭͷεΩʔϚΛઈରతͳιʔεͱͯ͠ѻ͍͍ͨ
©2021 Wantedly, Inc.GraphQL Gateway ߏVisit app(iOS)microserviceJSON / HTTPProtobuf / gRPCWeb Frontend (user)GraphQL gatewaymicroservicemicroserviceWeb Frontend (client)Visit app(Android)
©2021 Wantedly, Inc.GraphQL Gateway ߏVisit app(iOS)microserviceJSON / HTTPProtobuf / gRPCWeb Frontend (user)GraphQL gatewaymicroservicemicroserviceWeb Frontend (client)Visit app(Android)1ͭͷ GraphQL εΩʔϚΛશϑϩϯτΤϯυͰڞ༗͢Δ͜ͱͰɺࣅͨΑ͏ͳ API Λྔ࢈͢ΔίετΛݮΒ͢ʢ͋Δ͍ɺෆཁͳϑΟʔϧυΛऔಘͯ͠༨ܭͳϨΠςϯγ͕ൃੜ͢ΔͷΛ͙ʣ
©2021 Wantedly, Inc.GraphQL Gateway ߏVisit app(iOS)microserviceJSON / HTTPProtobuf / gRPCWeb Frontend (user)GraphQL gatewaymicroservicemicroserviceWeb Frontend (client)Visit app(Android)υϝΠϯϩδοΫόοΫΤϯυʹ࣮͞ΕΔʢෳͷϑϩϯτΤϯυͰಉ͡ϩδοΫΛ࣮͢ΔͷΛ͙ʣใͷू GraphQL gateway Ͱ1ͭͷάϥϑΛ৴͢Δ͚ͩͳͷͰɺ֤ϑϩϯτΤϯυ͚ͷ API Λߏங͢Δඞཁͳ͍ʢbelongs to user ͳΦϒδΣΫτʹ user Λೖ͢Δॲཧͱ͔ॻ͖͕͚ͪͩͲɺͦΕΛ͠ͳͯ͘ྑ͘ͳΔʣ
©2021 Wantedly, Inc.GraphQL Gateway ߏVisit app(iOS)microserviceJSON / HTTPProtobuf / gRPCWeb Frontend (user)GraphQL gatewaymicroservicemicroserviceWeb Frontend (client)Visit app(Android).proto le.proto le.proto leGraphQL schema.proto ͔Β GraphQL schema ͱ࣮Λੜ͢ΔπʔϧΛࣗ࡞͠ɺSchema ཧͱ GraphQL server ࣮ͷίετΛݮΒ͢
©2021 Wantedly, Inc.graphql-gateway‣ Protobuf ʹ͋ΔใͳΔ͘ GraphQL ʹҾ͖ܧ͙- ίϝϯτͪΖΜ͢ʢGraphiQL ΫϥΠΞϯτଆͷ VSCode ্ͰݟΕͯศརʣ- Nullability- (gRPC ʹ non-null Λએݴ͢ΔΈඪ४Ͱଘࡏ͠ͳ͍͕ɺίϝϯτ extension ʹͦΕΛهड़͠Α͏ʂͱ͍͏نΛಋೖ͍ͯ͠Δ →https://google.aip.dev/203ʣ- Abstraction: oneof -> union‣ ΦϒδΣΫτ Protobuf ͔Βੜ͠ɺΦϒδΣΫτͱΦϒδΣΫτͷଓ TypeScript Ͱهड़‣ কདྷతʹ։ൃͷεέʔϥϏϦςΟ୲อͷͨΊʹ GraphQL Federation ͱ͔ͨ͘͠ͳΓͦ͏‣ ͱΓ͋͑ͣ1ՕॴʹೖΕͯΈͯݕূ- ΞʔΩςΫνϟʹେ͖ͳมߋΛೖΕΔͱ͖ఫୀՄೳʹ͓ͯ͘͠ͷ͕େ‣ Node.js (TypeScript + GraphQL Nexus)- Go Rust બࢶͱ͕ͯ͋ͬͨ͠ɺϦϑΝϨϯε࣮Ͱ͋Δ graphql-js Λ͏͜ͱΛ༏ઌ- ͋ͱͰม͑ͨ͘ͳͬͯɺGraphQL ͷεΩʔϚ͕कΕ͍ͯΕͳΜͱ͔ͳΔ- Apollo Server ͳͲͱΓ͋͑ͣΘͳ͍ʢඞཁʹͳΓͦ͏ͳλΠϛϯάͰߟ͑Δʣ- Envelop ͍͍ͨ https://www.envelop.dev/‣ Resolver Ͱ gRPC Λୟ͘- औಘܥجຊతʹ DataLoader Λܦ༝͠ɺ͍ΘΏΔ N+1 Λ͙- όοΫΤϯυ͕ FieldMask pattern ʹରԠ͍ͯ͠Δ߹ɺGraphQL ΫΤϦ͔Βݡ͘ FieldMask ΛΈཱͯΔ
©2021 Wantedly, Inc.graphql-gateway‣ Protobuf ʹ͋ΔใͳΔ͘ GraphQL ʹҾ͖ܧ͙- ίϝϯτͪΖΜ͢ʢGraphiQL ΫϥΠΞϯτଆͷ VSCode ্ͰݟΕͯศརʣ- Nullability- (gRPC ʹ non-null Λએݴ͢ΔΈඪ४Ͱଘࡏ͠ͳ͍͕ɺίϝϯτ extension ʹͦΕΛهड़͠Α͏ʂͱ͍͏نΛಋೖ͍ͯ͠Δ →https://google.aip.dev/203ʣ- Abstraction: oneof -> union‣ ΦϒδΣΫτ Protobuf ͔Βੜ͠ɺΦϒδΣΫτͱΦϒδΣΫτͷଓ TypeScript Ͱهड़‣ কདྷతʹ։ൃͷεέʔϥϏϦςΟ୲อͷͨΊʹ GraphQL Federation ͱ͔ͨ͘͠ͳΓͦ͏‣ ͱΓ͋͑ͣ1ՕॴʹೖΕͯΈͯݕূ- ΞʔΩςΫνϟʹେ͖ͳมߋΛೖΕΔͱ͖ఫୀՄೳʹ͓ͯ͘͠ͷ͕େ‣ Node.js (TypeScript + GraphQL Nexus)- Go Rust બࢶͱ͕ͯ͋ͬͨ͠ɺϦϑΝϨϯε࣮Ͱ͋Δ graphql-js Λ͏͜ͱΛ༏ઌ- ͋ͱͰม͑ͨ͘ͳͬͯɺGraphQL ͷεΩʔϚ͕कΕ͍ͯΕͳΜͱ͔ͳΔ- Apollo Server ͳͲͱΓ͋͑ͣΘͳ͍ʢඞཁʹͳΓͦ͏ͳλΠϛϯάͰߟ͑Δʣ- Envelop ͍͍ͨ https://www.envelop.dev/‣ Resolver Ͱ gRPC Λୟ͘- औಘܥجຊతʹ DataLoader Λܦ༝͠ɺ͍ΘΏΔ N+1 Λ͙- όοΫΤϯυ͕ FieldMask pattern ʹରԠ͍ͯ͠Δ߹ɺGraphQL ΫΤϦ͔Βݡ͘ FieldMask ΛΈཱͯΔࣗຫ͍͍ͨͨ͜͠͠ͱແݶʹ͋Δ͕͕࣌ؒΓͳ͍
©2021 Wantedly, Inc.graphql-gateway‣ Protobuf ʹ͋ΔใͳΔ͘ GraphQL ʹҾ͖ܧ͙- ίϝϯτͪΖΜ͢ʢGraphiQL ΫϥΠΞϯτଆͷ VSCode ্ͰݟΕͯศརʣ- Nullability- (gRPC ʹ non-null Λએݴ͢ΔΈඪ४Ͱଘࡏ͠ͳ͍͕ɺίϝϯτ extension ʹͦΕΛهड़͠Α͏ʂͱ͍͏نΛಋೖ͍ͯ͠Δ →https://google.aip.dev/203ʣ- Abstraction: oneof -> union‣ ΦϒδΣΫτ Protobuf ͔Βੜ͠ɺΦϒδΣΫτͱΦϒδΣΫτͷଓ TypeScript Ͱهड़‣ কདྷతʹ։ൃͷεέʔϥϏϦςΟ୲อͷͨΊʹ GraphQL Federation ͱ͔ͨ͘͠ͳΓͦ͏‣ ͱΓ͋͑ͣ1ՕॴʹೖΕͯΈͯݕূ- ΞʔΩςΫνϟʹେ͖ͳมߋΛೖΕΔͱ͖ఫୀՄೳʹ͓ͯ͘͠ͷ͕େ‣ Node.js (TypeScript + GraphQL Nexus)- Go Rust બࢶͱ͕ͯ͋ͬͨ͠ɺϦϑΝϨϯε࣮Ͱ͋Δ graphql-js Λ͏͜ͱΛ༏ઌ- ͋ͱͰม͑ͨ͘ͳͬͯɺGraphQL ͷεΩʔϚ͕कΕ͍ͯΕͳΜͱ͔ͳΔ- Apollo Server ͳͲͱΓ͋͑ͣΘͳ͍ʢඞཁʹͳΓͦ͏ͳλΠϛϯάͰߟ͑Δʣ- Envelop ͍͍ͨ https://www.envelop.dev/‣ Resolver Ͱ gRPC Λୟ͘- औಘܥجຊతʹ DataLoader Λܦ༝͠ɺ͍ΘΏΔ N+1 Λ͙- όοΫΤϯυ͕ FieldMask pattern ʹରԠ͍ͯ͠Δ߹ɺGraphQL ΫΤϦ͔Βݡ͘ FieldMask ΛΈཱͯΔότϧ͍ͨ͠Λฉ͖͍ͨɾ͍ٞͨ͜͠ͱ͕͋ΔਓΛฉ͖ʹདྷ͍ͯͩ͘͞ʂʢSpatial Chat ʹ͍·͢ʣhttps://www.wantedly.com/projects/748998
©2021 Wantedly, Inc.·ͱΊɾ·ͳͼ‣ ٕज़ͷಋೖɺԿͷΛղܾ͢Δͷ͕తͳͷ͔Λҙࣝ͠Α͏- ʮѱ͘ͳͬͨʂΊΔʂʯͰͳ͘ɺ݁ہʮԿΛղܾͨͯ͘͠ʯʮԿͱίϯϑϦΫτ͍ͯ͠Δͷ͔ʯΛߟ͑Δ‣ ͱ͍͑ఫୀ͢Δ༐ؾେࣄ- େ͖ͳٕज़ಋೖɺఫୀ͍͢͠Α͏ʹখ͘͢͢͞ΊΔͷϙΠϯτ- ࣮ڥͰಈ͔͞ͳ͍ͱΘ͔Βͳ͍͜ͱ͋Δ‣ GraphQL (ͱ͍͏͔ API ٕज़શൠʣʹ͍ͭͯ৭Μͳਓͱ͍ٞͨ͠Ͱ͢ʂͥͻདྷͯͶʂ