$30 off During Our Annual Pro Sale. View Details »

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

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

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

Masahiro Wakame

August 10, 2018
Tweet

More Decks by Masahiro Wakame

Other Decks in Technology

Transcript

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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
    }
    }
    }

    View Slide

  7. େࣄͳ͜ͱ
    •ΘΓͱ੍໿͋Δ (N+1ରࡦͱ͔)
    •ແݶʹૣ͘ͳ͍
    •REST APIͷ্Ґޓ׵Ͱ͸ͳ͍
    •ࠩҟΛΑ͘ཧղ͠Α͏

    View Slide

  8. ϝϧΧϦͰ࢖ͬͯΔʁ
    •C Sπʔϧ PHP+webonyx/graphql-php
    •US ϝϧΧϦWeb ???
    •MicroserviceԽ CSπʔϧ Go+gqlgen
    •ϝϧΧϦWeb Node.js+Apollo
    •ϝϧϖΠ CSπʔϧ(ݕ౼த) Go+gqlgen
    ٕज़ॻయWeb΋࣮ݧதͰ͢

    View Slide

  9. ClientͷྲྀΕ
    •·ͣSchema(+αʔό)͕͋Δ
    •ͦ͜ʹOperationΛ౤͛Δ
    •Query, Mutation, Subscribe ͷ3छ
    •ཁٻͨ͠௨ΓͷܗࣜͰσʔλདྷΔ

    View Slide

  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"
    }
    ]
    }
    }
    }
    }
    ରԠͨ͠ߏ଄͕ฦΔ

    View Slide

  11. ClientͷྲྀΕ
    •ͭ·Γ…
    •ΫΤϦʹΑͬͯಘΒΕΔσʔλ͕มΘΔ
    •ΫΤϦݸผʹฦΓ஋ͷσʔλͷܕཉ͍͠
    •→ݴޠʹΑͬͯ͸࢖͍ͮΒ͍Մೳੑʁ
    ·͊JSͱ૬ੑྑͦ͞͏ͳͷ͸Θ͔Δ

    View Slide

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

    View Slide

  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
    }
    }

    View Slide

  14. ͬ͘͟ΓServerݪཧ
    Resolverͷू߹
    ʹ
    αʔόͷ࣮૷

    View Slide

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

    View Slide

  16. GitHub v4 APIΛ৮Δ

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  26. gqlgenͷαϙʔτൣғ
    •Query
    •Mutation
    •Subscription
    •Directive
    •import syntax
    •type extend
    ͋Δ ΄͍͠
    ͦͷ͏ͪ΍Γ·͢
    committer͔ͩΒͶ

    View Slide

  27. σϞ
    •gqlgen init ͯ͠ΈΔ
    •มߋΛՃ͑ͯΈΔ
    •gqlgen gen ͯ͠ΈΔ
    •࣮ࡍʹୟ͍ͯΈΔ
    ࣌ؒ…͋Δʁ
    gqlgen.com/
    getting-started/

    View Slide

  28. ύʔπͷղઆ
    •Resolver
    •Directive
    •Middleware
    •ErrorPresenter

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  33. RelayΛษڧ͢΂͠
    •Relay spec 3ܑఋ
    •cursor, global object, input object
    •specຊମ͡Όͳ͍ͷͰཤमಀ͕ͪ͠
    •GitHub΋౿ऻ͍ͯ͠Δ
    •bit.ly/2npeSdv

    View Slide

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

    View Slide

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

    View Slide

  36. REST APIͱͷରൺ
    •REST API = RPC
    •GraphQL = QueryLanguage
    •Τϥʔʹର͢Δߟ͑ํ͕ࠜຊతʹҧ͏
    •“ਖ਼͍͠Requestͷ౤͛ํ” ͱ͍͏֓೦
    •ڻ͖࠷খͷݪଇ & σόοΨϏϦςΟ

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  40. ·ͩΘ͔ΒΜ

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  46. ࢀߟࢿྉ

    View Slide

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

    View Slide

  48. ͓͠·͍

    View Slide