GoでGraphQLサーバを立てるぞ! / Building GraphQL server by go

GoでGraphQLサーバを立てるぞ! / Building GraphQL server by go

mercari.go #2 登壇資料です
https://mercari.connpass.com/event/95665/

0e797080b64e6b03ed00964cf69b5058?s=128

Masahiro Wakame

August 10, 2018
Tweet

Transcript

  1. GoͰGraphQLαʔόΛཱͯΔͧʂ mercari.go #2 Θ͔Ί ·͞ͻΖ #mercarigo bit.ly/2vyiluP

  2. Θ͔Ί ·͞ͻΖ @v vakame Masahiro Wakame GAE/Go TypeScript ٕज़ॻయ

  3. TL;DR •GraphQLͬͯԿʁ •GitHub v4 APIΛ৮ͬͯΈΔ •github.com/99designs/gqlgen •ઃܭϕετϓϥΫςΟε ΫϥΠΞϯτͷ࿩͸͠ͳ͍

  4. GraphQLͬͯԿʁ ࡉ͔͍͜ͱ͸ ࠷ޙͷࢀߟࢿྉूͰʂ

  5. GraphQLͬͯԿʁ •Facebook͕2015೥ʹެ։ͨ͠࢓༷ •άϥϑߏ଄ʹର͢ΔQuery Language •༑ୡͷ༑ୡΛ5ਓͣͭऔಘ͢Δͱ͔ •Client→Serverͷσʔλཁٻ࣌ʹ࢖͏

  6. GraphQLͬͯԿʁ RESTͳΒ3RPCඞཁ
 GraphQLͳΒ1ճ { circle(id: "Q2lyY2xlRXhoaWJpdEluZm86MTIzNAo") { name spaces penName

    webSiteURL genre genreFreeFormat products(first: 9) { pageInfo { hasNextPage endCursor } nodes { name description type page price relatedURLs firstAppearanceEventName firstAtTechBookFest images { url height width } } } loginUserChecked { checked } } }
  7. େࣄͳ͜ͱ •ΘΓͱ੍໿͋Δ (N+1ରࡦͱ͔) •ແݶʹૣ͘ͳ͍ •REST APIͷ্Ґޓ׵Ͱ͸ͳ͍ •ࠩҟΛΑ͘ཧղ͠Α͏

  8. ϝϧΧϦͰ࢖ͬͯΔʁ •C Sπʔϧ PHP+webonyx/graphql-php •US ϝϧΧϦWeb ??? •MicroserviceԽ CSπʔϧ Go+gqlgen

    •ϝϧΧϦWeb Node.js+Apollo •ϝϧϖΠ CSπʔϧ(ݕ౼த) Go+gqlgen ٕज़ॻయWeb΋࣮ݧதͰ͢
  9. ClientͷྲྀΕ •·ͣSchema(+αʔό)͕͋Δ •ͦ͜ʹOperationΛ౤͛Δ •Query, Mutation, Subscribe ͷ3छ •ཁٻͨ͠௨ΓͷܗࣜͰσʔλདྷΔ

  10. Queryͷྫ { viewer { id login name location bio company

    repositoriesContributedTo(first: 2) { nodes { owner { login } name } } } } { "data": { "viewer": { "id": "MDQ6VXNlcjEyNTMzMg==", "login": "vvakame", "name": "Masahiro Wakame", "location": "Tokyo, Japan", "bio": "TypeScript and GAE/Go", "company": "Merpay, Inc.", "repositoriesContributedTo": { "nodes": [ { "owner": { "login": "mruby" }, "name": "mruby" }, { "owner": { "login": "DefinitelyTyped" }, "name": "DefinitelyTyped" } ] } } } } ରԠͨ͠ߏ଄͕ฦΔ
  11. ClientͷྲྀΕ •ͭ·Γ… •ΫΤϦʹΑͬͯಘΒΕΔσʔλ͕มΘΔ •ΫΤϦݸผʹฦΓ஋ͷσʔλͷܕཉ͍͠ •→ݴޠʹΑͬͯ͸࢖͍ͮΒ͍Մೳੑʁ ·͊JSͱ૬ੑྑͦ͞͏ͳͷ͸Θ͔Δ

  12. ͬ͘͟ΓServerݪཧ •Query͕དྷΔ •ฦ͢σʔλ͸Treeߏ଄ʹͳΔ •Treeͷઅ(ͱ͔)ຖʹResolverΛఆٛ͢Δ •Resolver͕ཁٻ͞ΕͨNodeΛੜ੒͠ฦ͢ •Resolverͷू߹ == αʔόͷ࣮૷

  13. ͬ͘͟ΓServerݪཧ type ResolverRoot interface { Query() QueryResolver User() UserResolver CircleExhibitInfo()

    CircleExhibitInfoResolver ProductInfo() ProductInfoResolver } type QueryResolver interface { Circle(ctx context.Context, id string) (*CircleExhibitInfo, } type CircleExhibitInfoResolver interface { ID(ctx context.Context, obj *CircleExhibitInfo) (string, err Products(ctx context.Context, obj *CircleExhibitInfo, first } type ProductInfoResolver interface { ID(ctx context.Context, obj *ProductInfo) (string, error) Images(ctx context.Context, obj *ProductInfo) ([]Image, erro } query { circle(id: "Q2lyY2xlRXhoaWJpdEluZm86MTIzNAo") { name spaces penName webSiteURL genre genreFreeFormat products(first: 9) { pageInfo { hasNextPage endCursor } nodes { name description type page price relatedURLs firstAppearanceEventName firstAtTechBookFest images { url height width } } } loginUserChecked { checked } }
  14. ͬ͘͟ΓServerݪཧ Resolverͷू߹ ʹ αʔόͷ࣮૷

  15. ͜͜޷͖ •୯ҰΤϯυϙΠϯτ •Introspection •SchemaΛ஌Δʹ΋GraphQL͕࢖͑Δ •ڧ͍ܕ෇͚ʂ

  16. GitHub v4 APIΛ৮Δ

  17. ৮Γ·͠ΐ͏ •developer.github.com/v4/explorer/ •GraphiQLʹ৮ΕΔ •GitHubͷߟ͑ͨ࠷ڧͷઃܭʹ৮ΕΔ •͋ΘΑ͘͹࢖ͬͯΈΔ

  18. σϞ •ϩάΠϯϢʔβͷ໊લग़͢ •೚ҙͷϦϙδτϦ͕࡞ΒΕͨ೔ग़͢ •GraphQLʹؔ࿈ͷ͋ΔUserΛநग़͢Δ

  19. ίʔυ͔Β •ద౰ʹPOST͢Δ͚ͩ •Authorization: bearer ${PersonalAccessToken} •https://api.github.com/graphql •https://github.com/settings/tokens bit.ly/2Oo8DlD

  20. github.com/99designs/gqlgen I’m committer!

  21. ͳͥGoͳͷ͔ʁ •Go͸΍͍͠ฒߦॲཧ؆୯ͩ͠ •Microservice܈͕GoͳͷͰ…ʂ •GAE/GoͰಈ͘ͷͰ…ʂ •ࣾ಺ʹ͸PHP੎΍Node.js੎΋͍·͢ •Frontend Engineer؅׋

  22. GoओཁϥΠϒϥϦൺֱ •github.com/graph-gophers/graphql-go •github.com/graphql-go/graphql •github.com/samsarahq/thunder •github.com/99designs/gqlgen

  23. GoओཁϥΠϒϥϦൺֱ •github.com/graph-gophers/graphql-go •github.com/graphql-go/graphql •github.com/samsarahq/thunder •github.com/99designs/gqlgen ػೳ͕ͪΐͬͱශऑ GoͷίʔυͰSchemaॻ͖ͨ͘ͳ͍ ಉ্ ΘΓͱྑͦ͞͏ʁ

  24. ͳͥgqlgen͔ʁ •ϘΠϥʔϓϨʔτ͸ݏʂ •׬શίʔυੜ੒΋ݏʂ •ίʔυੜ੒+खॻ͖ΛఔΑ͘… •ΑΖ͍͠ͳΒ͹gqlgenͩʂ

  25. gqlgen͸ྑ͍ͷ͔ʁ ྑ͘͠·ͨ͠❤ Ͱcommitterʹͳͬͨ

  26. gqlgenͷαϙʔτൣғ •Query •Mutation •Subscription •Directive •import syntax •type extend ͋Δ

    ΄͍͠ ͦͷ͏ͪ΍Γ·͢ committer͔ͩΒͶ
  27. σϞ •gqlgen init ͯ͠ΈΔ •มߋΛՃ͑ͯΈΔ •gqlgen gen ͯ͠ΈΔ •࣮ࡍʹୟ͍ͯΈΔ ࣌ؒ…͋Δʁ

    gqlgen.com/ getting-started/
  28. ύʔπͷղઆ •Resolver •Directive •Middleware •ErrorPresenter

  29. ύʔπͷղઆ •Resolver •Directive •Middleware •ErrorPresenter ੜ੒͞Εͨinterface࣮૷ͯ͠ʂ ੜ੒͞ΕͨDirectiveʹ࣮૷Λ༩͑ͯʂ ద౰ʹϩΪϯάͱ͔ʹ࢖͑·͢ ΤϥʔͷΧελϚΠζͰ͖·͢ gitter.im/gqlgen/Lobby

    gqlgen.com
  30. Middleware •ResolverMiddleware •Resolverͷಈ࡞લޙʹॲཧΛڬΉ •RequestMiddleware •Req,RespʹॲཧΛڬΉ(ओʹϩΪϯά) bit.ly/2MmjbEE

  31. ઃܭϕετϓϥΫςΟε ຊ౰ʹϕετ͔͸͠ΒΜʂ

  32. RelayΛษڧ͢΂͠ •RelayΛ࠾༻͠ͳͯ͘΋ษڧͯ͠ •Server͚ͩߟ͑ΔͱΠϛϑͳ࢓༷͕͋Δ •ओʹFragmentपΓ •UIଆΛඒ͘͠ઃܭ͢ΔͨΊ TSαϙʔτ͖ͨ github.com/facebook/relay/pull/2293

  33. RelayΛษڧ͢΂͠ •Relay spec 3ܑఋ •cursor, global object, input object •specຊମ͡Όͳ͍ͷͰཤमಀ͕ͪ͠

    •GitHub΋౿ऻ͍ͯ͠Δ •bit.ly/2npeSdv
  34. N+1໰୊ •Πϕϯτ3ͭ×αʔΫϧ100݅×൦෍෺9ݸ •1+3×1+3×100×1 = 304ճͷDBΞΫηε •ؤுͬͯ࠷దԽ͢Δͱ 1+1+1 ??

  35. N+1໰୊ •gqlgen͸ResolverΛฒྻॲཧ͢Δ •→ू໿͕೉͍͠ʂ •github.com/vektah/dataloaden •ࢦఆظؒͷϦΫΤετΛҰׅԽ •·ͩະධՁ… ྑ͍ํ๏ࢥ͍ͭ͘ʁ

  36. REST APIͱͷରൺ •REST API = RPC •GraphQL = QueryLanguage •Τϥʔʹର͢Δߟ͑ํ͕ࠜຊతʹҧ͏

    •“ਖ਼͍͠Requestͷ౤͛ํ” ͱ͍͏֓೦ •ڻ͖࠷খͷݪଇ & σόοΨϏϦςΟ
  37. REST APIͱͷରൺ •Τϥʔʹର͢Δߟ͑ํϚδॏཁ •େࣄͳ͜ͱͳͷͰ2ճݴ͍·ͨ͠ •GraphiQLͰ׬݁͢ΔσόοΨϏϦςΟ •੍ޚ͸ͳΔ΂͘DirectiveϨϕϧͰ ϑϧεΫϥονͰ͖ΔͳΒͦΕ͕Α͍

  38. Schemaઃܭ •Schema͔ΒಡΈऔΕΔ৘ใΛ૿΍͢ •DirectiveΛ࢖ͬͨScope੍ޚͱ͔ •DBͷ1table=1typeʹ͢Δͱ͔ •มʹ߹ମͤͨ͞Γ෼ׂͨ͠Γ͠ͳ͍

  39. AuthपΓ •ಛʹܾ·ͬͨ࢓༷͕ͳ͍ •ͷͰɺී௨ʹHTTP͢Δ •ηογϣϯ, OAuth2 etc…

  40. ·ͩΘ͔ΒΜ

  41. ςετͲ͏͢Δʁ •ࠓͷͱ͜Ζgolden testingͯ͠Δ •Resolver, DirectiveΛݸผʹςετʁ

  42. Mock? •αʔόଆ࣮૷͕͋ͱʹͳΔ৔߹ •ΫϥΠΞϯτଆʹͲ͏ ָͤ͞Δ΂͖ʁ

  43. BFF vs ௚࣮૷ •جຊ௚࣮૷ͷ΄͏ָ͕ͦ͏ •Backend Engineerతʹ͸ •Microserviceͷͱ͖ʁ •݁ہBFFతଘࡏʹͳΔͷͰ͸…ʁ

  44. ӡ༻ͷ࿩ •ϝτϦΫεऔΓ͍ͨʁ •ϩάऔΓ͍ͨʁ •stats෼ੳ͍ͨ͠ʁ

  45. ΫϥΠΞϯτଆϫʔΫϑϩʔ •ͳʹ΋͔΋Θ͔ΒΜ •ಛʹAndroid, iOSͷ஌ݟ͕ͳ͍ •Web͸ద౰ʹ΍ͬͯ΄͍͠

  46. ࢀߟࢿྉ

  47. ࢀߟࢿྉू •b.hatena.ne.jp/vvakame/GraphQL •graphql.org •www.howtographql.com •ٕज़ॻయ5Ͱຊग़͢…ʁ(མͪͳ͍Ͱ ͜Ε͖͢

  48. ͓͠·͍