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

Web API に秩序を与える Protocol Buffers / Protocol Buffers for Web API #builderscon

Web API に秩序を与える Protocol Buffers / Protocol Buffers for Web API #builderscon

builderscon tokyo 2019 で「Web API に秩序を与える Protocol Buffers」というタイトルで発表した資料です。

Protocol Buffers を利用して Web API の Schema 管理をするという観点で、豊富な実例とともにその手法やメリット・デメリットについて話しました。

cf. https://builderscon.io

追記: 61ページ目で Protocol Buffers を利用する際の注意点として後方互換性が壊れるケースの話をしましたが、自分たちが経験したのは gRPC + grpc-gateway 構成特有のケースだったので記述を修正しました。

Nao Minami

August 30, 2019
Tweet

More Decks by Nao Minami

Other Decks in Technology

Transcript

  1. ©2019 Wantedly, Inc.
    8FC"1*ʹடংΛ༩͑Δ
    1SPUPDPM#VGGFST
    30.Aug.2019 - Nao Minami (@south37) Wantedly, Inc.
    builderscon tokyo 2019

    View Slide

  2. ©2019 Wantedly, Inc.
    /BP.JOBNJ
    *OGSBTUSVDUVSF&OHJOFFS 8BOUFEMZ
    (JU)VCTPVUI
    5XJUUFSTPVUI
    43&ͱͯ͠ͷ໾ׂ
    ։ൃج൫ͱͯ͠ͷ໾ׂ
    1SPUPDPM#V⒎FSTΛར༻ͨ͠
    ϚΠΫϩαʔϏε։ൃʹऔΓ૊Ή

    View Slide

  3. ©2019 Wantedly, Inc.
    ͸͡Ίʹ

    View Slide

  4. ©2019 Wantedly, Inc.
    ಥવͰ͕͢
    8FC"1*ͷ4DIFNB؅ཧΛ
    ͍ͯ͠·͔͢ʁ

    View Slide

  5. ©2019 Wantedly, Inc.
    4DIFNBͱ͸
    "1*ͷৼΔ෣͍Λهड़ͨ͠΋ͷ
    w QBUI΍ϝιουɺSFRVFTUSFTQPOTFͷ಺༰ͳͲΛએݴతʹهड़
    w ͍͔ͭ͘ͷํ๏͕஌ΒΕ͍ͯΔ
    w FH0QFO"1* +40/"1* 1SPUPDPM#V⒎FST FUD

    View Slide

  6. ©2019 Wantedly, Inc.
    Ͳ͏͍ͬͨ࣌ʹ
    4DIFNB؅ཧΛͨ͘͠ͳΔͷ͔ʁ

    View Slide

  7. ©2019 Wantedly, Inc.
    4DIFNB%SJWFO%FWFMPQNFOU
    4DIFNBΛ࠷ॳʹఆٛͯ͠։ൃ
    w 8FC"1*ͷ4DIFNBΛఆ͔ٛͯ͠Βɺ4DIFNBΛຬͨ͢TFSWFSɺ
    ར༻͢ΔDMJFOUΛಉ࣌ʹ։ൃ
    w 4DIFNB͕ʮ৴པͰ͖ΔυΩϡϝϯτʯͱͳΓίϛϡχέʔγϣϯ
    ͷ伴ͱͳΔ
    ߴ͍ੜ࢈ੑͰ։ൃՄೳ
    4DIFNB
    4FSWFS։ൃ
    $MJFOU։ൃ

    View Slide

  8. ©2019 Wantedly, Inc.
    .JDSPTFSWJDFT"SDIJUFDUVSF
    .JDSPTFSWJDFͷৼΔ෣͍Λ؅ཧ͍ͨ͠
    w .JDSPTFSWJDFT"SDIJUFDUVSFͰ͸ଟ਺ͷ.JDSPTFSWJDF "1*
    ͕ଘࡏ
    w ૄ݁߹ੑΛߴΊɺ࠶ར༻͠΍͘͢͢ΔͨΊʹ΋4DIFNBͷએݴతهड़
    ͕ॏཁ
    3BJMT
    (P
    5ZQF4DSJQU

    View Slide

  9. ©2019 Wantedly, Inc.
    1SPUPDPM#VGGFSTΛར༻ͯ͠
    4DIFNB؅ཧΛ͢Δํ๏ʹ͍ͭͯ
    ࿩͠·͢

    View Slide

  10. ©2019 Wantedly, Inc.
    1SPUPDPM#VGGFSTͱ͸ʁ

    View Slide

  11. ©2019 Wantedly, Inc.

    View Slide

  12. ©2019 Wantedly, Inc.
    (PPHMF੡ͷ4FSJBMJ[BUJPO-JCSBSZ
    *OUFSGBDF%FpOJUJPO-BOHVBHF *%-

    w *%-Ͱ"1*4DIFNBΛهड़͠ɺTFSJBMJ[BUJPOEFTFSJBMJ[BUJPOίʔυ
    Λࣗಈੜ੒
    w *%-Ͱهड़ͨ͠಺༰ʢQSPUPpMFʣ͸ɺ"1*ʹର͢Δ੩తܕ෇͚ͱͳΔ
    w 1SPUPDPM#V⒎FSTίϯύΠϥʢQSPUPDʣ͸QMVHJOͰ༷ʑͳػೳ֦ு
    ͕Մೳ
    w TXBHHFSKTPOͷੜ੒ H31$ར༻ FUD
    w ༷ʑͳݴޠͰར༻Մೳ
    w $$ (P +BWB 1ZUIPO 3VCZ /PEF FUD
    1SPUPDPM#VGGFSTͱ͸ʁ

    View Slide

  13. ©2019 Wantedly, Inc.
    ྫͱͯ͠A(&5CPPLTJEAͱ͍͏
    "1*ͷ4DIFNBΛ
    QSPUPpMFʹهड़ͯ͠ΈΔ

    View Slide

  14. ©2019 Wantedly, Inc.
    service BookService {
    rpc getBook (getBookRequest) returns (Book) {
    option (google.api.http) = {
    get: "/api/books/{id}"
    };
    }
    }
    message getBookRequest {
    int64 id = 1;
    }
    message Book {
    int64 id = 1;
    string title = 2;
    }
    #PPL"1*ͷ4DIFNBΛQSPUPGJMFʹهड़

    View Slide

  15. ©2019 Wantedly, Inc.
    QSPUPDͰίʔυࣗಈੜ੒
    w ͦΕͧΕͷNFTTBHFΛTFSJBMJ[FEFTFSJBMJ[F͢ΔSVOUJNFMJCSBSZ
    ͷίʔυΛࣗಈੜ੒
    ྫQSPUPGJMF͔Βίʔυࣗಈੜ੒
    Google::Protobuf::DescriptorPool.xxx do
    add_message "books.GetBookRequest" do
    optional :id, :int64, 1
    end
    add_message "books.Book" do
    optional :id, :int64, 1
    optional :title, :string, 2
    end
    end
    module Books
    GetBookRequest =
    XXX(“books.GetBookRequest”).msgclass
    Book = XXX(“books.Book").msgclass
    end
    message getBookRequest {
    int64 id = 1;
    }
    message Book {
    int64 id = 1;
    string title = 2;
    }
    QSPUPpMF 3VCZ

    View Slide

  16. ©2019 Wantedly, Inc.
    [1] book = Book.new(id: 2, title: "Hello, Book")
    =>
    [2] book.to_proto
    => "\b\x02\x12\vHello, Book”
    [3] book.to_json
    => "{\"id\":2,\"title\":\"Hello, Book\”}"
    [4] Book.decode("\b\x02\x12\vHello, Book")
    =>
    3VCZ
    message Book {
    int64 id = 1;
    string title = 2;
    }
    QSPUPpMF

    View Slide

  17. ©2019 Wantedly, Inc.
    ࣗಈੜ੒ίʔυͰCJOBSZ΍+40/ͷ
    4FSJBMJ[F%FTFSJBMJ[FΛ࣮ݱ

    View Slide

  18. ©2019 Wantedly, Inc.
    service BookService {
    rpc getBook (getBookRequest) returns (Book) {
    option (google.api.http) = {
    get: "/api/books/{id}"
    };
    }
    }
    TXBHHFSQMVHJOͰ+40/Λࣗಈੜ੒
    w HSQDHBUFXBZQSPUPDHFOTXBHHFSQMVHJOΛར༻
    w ҎԼͷQSPUPpMFͷ಺༰Λ൓өͨ͠TXBHHFSKTPOΛੜ੒
    ྫQSPUPGJMF͔ΒTXBHHFSKTPOΛࣗಈੜ੒

    View Slide

  19. ©2019 Wantedly, Inc.
    {
    "swagger": “2.0",
    …,
    "paths": {
    "/api/books/{id}": {
    "get": {
    "operationId": "GetBook",
    "responses": {
    "200": {
    "description": …
    "schema": {
    "$ref": "#/definitions/booksBook"
    }
    }
    },
    “parameters": [
    {
    "name": "id",
    "in": "path",
    "required": true,
    "type": "string",
    "format": "int64"
    }
    ],
    "tags": …
    }
    }
    },
    "definitions": {
    "booksBook": {
    "type": "object",
    "properties": {
    "id": {
    "type": "string",
    "format": "int64"
    },
    "title": {
    "type": "string"
    }
    }
    }
    }
    }

    View Slide

  20. ©2019 Wantedly, Inc.
    ͦͷ΄͔ʹ΋ɺQSPUPpMFΛ
    TJOHMFTPVSDFPGUSVUIͱͯ͠
    ༷ʑͳίʔυࣗಈੜ੒͕Մೳ

    View Slide

  21. ©2019 Wantedly, Inc.
    ͳͥ1SPUPDPM#VGGFSTΛ
    ར༻͢Δͷ͔ʁ

    View Slide

  22. ©2019 Wantedly, Inc.
    ͳͥ1SPUPDPM#VGGFSTΛར༻͢Δͷ͔ʁ
    ࣗಈੜ੒ίʔυར༻ʹΑΔ"1*
    4DIFNBͷอূ
    4FSJBMJ[FS%FTFSJBMJ[FSͷػೳ
    QSPUPDͷ๛෋ͳQMVHJO

    View Slide

  23. ©2019 Wantedly, Inc.
    ͳͥ1SPUPDPM#VGGFSTΛར༻͢Δͷ͔ʁ
    ࣗಈੜ੒ίʔυར༻ʹΑΔ"1*
    4DIFNBͷอূ
    w QSPUPpMFΛਖ਼֬ʹ൓өͨ͠4FSJBMJ[FS%FTFSJBMJ[FSΛར༻͢ΔͷͰ
    ʮ࣮૷ͱ4DIFNBͷڍಈ͕ͣΕΔʯͱ͍͏ࣄ͕ݪཧతʹൃੜ͠ͳ͍
    w 4XBHHFSͷ༷ʹUFTU΍WBMJEBUJPOͰ୲อ͢ΔͷͰ͸ͳ͘ɺͨͩ
    QSPUPD͕ੜ੒͢ΔίʔυΛར༻͢Ε͹ྑ͍
    ʮੜ͖ͯΔυΩϡϝϯτʯΛ؆୯͔࣮ͭ֬ʹ࡞Δ͜ͱ͕Ͱ͖Δ

    View Slide

  24. ©2019 Wantedly, Inc.
    4FSJBMJ[FS%FTFSJBJM[FSͷػೳ
    w pFMEͷ௥Ճ΍ϦωʔϜ͸ޙํޓ׵ੑΛյ͞ͳ͍
    w ݹ͍QSPUPpMF͔Βੜ੒ͨ͠%FTFSJBMJ[FSͰ΋৽͍͠
    CJOBSZΛ%FTFSJBMJ[FͰ͖Δɻͦͷٯ΋વΓɻ
    ෳ਺ϚΠΫϩαʔϏεͷಉ࣌EFQMPZͳͲΛۃྗݮΒͤΔ
    w CJOBSZGPSNBU͸+40/ΑΓ΋TFSJBMJ[FEFTFSJBMJ[F͕ૣ͘ɺ
    EBUBTJ[F΋খ͍͞
    4FSJBMJ[FS%FTFSJBMJ[FSͷػೳ͕༏Ε͍ͯΔ
    ͳͥ1SPUPDPM#VGGFSTΛར༻͢Δͷ͔ʁ

    View Slide

  25. ©2019 Wantedly, Inc.
    ͳͥ1SPUPDPM#VGGFSTΛར༻͢Δͷ͔ʁ
    QSPUPDͷ๛෋ͳQMVHJO
    w QMVHJOʹΑ༷ͬͯʑͳػೳ֦ு͕Մೳ
    w FHTXBHHFSKTPOͷੜ੒
    w FHQSPUPpMFͷ಺༰Λ+40/ܗࣜ΁ม׵
    w FHH31$ HSQDHBUFXBZͷར༻
    w ಛʹɺTXBHHFSKTPO͸ݩʑ8FC'SPOUFOE .PCJMF"QQνʔϜͱͷ
    ίϛϡχέʔγϣϯʹར༻͍ͯͨ͠ͷͰɺԸܙ͕େ͖͔ͬͨ
    w QSPUPDQMVHJOΤίγεςϜ͕࡞ΒΕ͖͍ͯͯΔ

    View Slide

  26. ©2019 Wantedly, Inc.
    1SPUPDPM#VGGFSTΛ
    Ͳ͏ར༻͍ͯ͠Δͷ͔ʁ

    View Slide

  27. ©2019 Wantedly, Inc.
    1SPUPDPM#VGGFSTΛͲ͏ར༻͍ͯ͠Δͷ͔ʁ
    #SPXTFS .PCJMF"QQ
    ϚΠΫϩαʔϏεͷ಺ଆͱ֎ଆ
    ྆ํͷ௨৴ʹ1SPUPDPM#VGGFSTΛར༻
    QSPUPpMFͷ಺༰Λ൓өͨ͠
    +40/PWFS)551
    1SPUPDPM#V⒎FSTPWFS)551
    PS
    QSPUPpMFͷ಺༰Λ൓өͨ͠
    +40/PWFS)551

    View Slide

  28. ©2019 Wantedly, Inc.
    ϚΠΫϩαʔϏε։ൃͰ͸
    ओʹ(Pͱ3VCZΛར༻

    View Slide

  29. ©2019 Wantedly, Inc.
    (PΛར༻ͨ͠ϚΠΫϩαʔϏεͰ͸
    Ͳ͏͍ͯ͠Δ͔ʁ

    View Slide

  30. ©2019 Wantedly, Inc.

    View Slide

  31. ©2019 Wantedly, Inc.
    HSBQJΛར༻
    w HSBQJ"TVSQSJTJOHMZFBTZ"1*TFSWFSBOEHFOFSBUPSJOH31$
    BOE(P
    w ฐࣾΤϯδχΞ!J[VNJO࡞ͷϑϨʔϜϫʔΫ
    w H31$HSQDHBUFXBZͷߏ੒Ͱ(PαʔόʔΛ؆୯ʹߏஙՄೳ
    (PΛར༻ͨ͠ϚΠΫϩαʔϏε։ൃ

    View Slide

  32. ©2019 Wantedly, Inc.
    (PPHMF੡31$ϑϨʔϜϫʔΫ
    w QSPUPpMFʹهड़ͨ͠TFSWJDFEFpOJUJPO͔ΒDMJFOUTFSWFS
    ίʔυ͓ΑͼTFSJBMJ[FSEFTFSJBMJ[FSίʔυΛࣗಈੜ੒
    4DIFNBͱ࣮૷ͷҰகΛอূ
    H31$ͱ͸ʁ

    View Slide

  33. ©2019 Wantedly, Inc.
    H31$ͱ3&45GVM)551"1*ͷม׵Λ
    ߦ͏3FWFSTF1SPYZ(FOFSBUPS
    w H31$TFSWFSͷલஈʹཱͪɺ+40/"1*TFSWFSͱͯ͠ৼΔ෣͏
    ಋೖͷϋʔυϧ͕௿͍
    HSQDHBUFXBZͱ͸ʁ

    View Slide

  34. ©2019 Wantedly, Inc.
    HSBQJΛར༻ͯ͠ɺ1SPUPDPM#VGGFST
    ͷϝϦοτΛڗड
    w QSPUPpMFΛॻ͘ͱɺH31$HSQDHBUFXBZͷίʔυΛࣗಈੜ੒
    4DIFNBΛݫີʹຬͨ͢"1*TFSWFSΛ؆୯ʹ࡞੒Մೳ
    w QSPUPDQMVHJOͰTXBHHFSKTPOΛੜ੒
    4XBHHFS6*ͳͲɺ4XBHHFSΤίγεςϜΛ׆͔ͤΔ
    w ৄࡉ͸ҎԼͷϦϯΫΛࢀর
    (PΛར༻ͨ͠ϚΠΫϩαʔϏε։ൃ
    IUUQTTQFBLFSEFDLDPNJ[VNJOHSBQJCVMEJOHKTPOBQJ
    TFSWFSXJUIHSQDHBUFXBZGPSNJDSPTFSWJDFT

    View Slide

  35. ©2019 Wantedly, Inc.
    Ͱ͸ɺ3VCZΛར༻ͨ͠
    ϚΠΫϩαʔϏε։ൃ͸ʁ

    View Slide

  36. ©2019 Wantedly, Inc.
    3VCZPO3BJMT1SPUPDPM#VGGFSTͷ
    4FSJBMJ[FS%FTFSJBMJ[FSΛར༻
    w 3BJMTͰ"1*Λ։ൃ
    w ͨͩ͠ɺSFRVFTUSFTQPOTFͷQBZMPBEʹ1SPUPDPM#V⒎FSTͷ
    CJOBSZGPSNBUΛར༻
    3VCZΛར༻ͨ͠ϚΠΫϩαʔϏε։ൃ

    View Slide

  37. ©2019 Wantedly, Inc.
    > PATCH /api/books/2 HTTP/1.1
    > Accept: application/protobuf
    > Content-Type: application/protobuf
    >
    > \x08\x02
    < HTTP/1.1 200 OK
    < Content-Type: application/protobuf
    <
    < \x08\x02\x12\x0BHello, Book
    [1] book = Book.new(id: 2, title: "Hello, Book")
    =>
    [2] book.to_proto
    => "\b\x02\x12\vHello, Book”
    3VCZ
    )551SFRVFTUSFTQPOTF

    View Slide

  38. ©2019 Wantedly, Inc.
    Mime::Type.register "application/protobuf", :protobuf
    ActionController::Renderers.add :protobuf do |obj, _|
    send_data obj.to_proto, type: Mime[:protobuf]
    end
    3VCZPO3BJMTJOJUJBMJ[FS
    def show
    req = GetBookRequest.decode(request.body.read)

    book = Book.new(id: xxx, title: yyy)
    render protobuf: book
    end
    3VCZPO3BJMTDPOUSPMMFS

    View Slide

  39. ©2019 Wantedly, Inc.
    3BJMTΛར༻͠ͳ͕Βɹ
    1SPUPDPM#VGGFSTͷϝϦοτΛڗड

    View Slide

  40. ©2019 Wantedly, Inc.
    Ұ෦Ͱ͸5ZQF4DSJQU͔Β΋
    1SPUPDPM#VGGFSTΛར༻

    View Slide

  41. ©2019 Wantedly, Inc.
    #BDLFOE'PS'SPOUFOE #''
    ͱͳΔ
    5ZQF4DSJQUαʔόʔ͕ଘࡏ
    w #SPXTFSͱ͸(SBQI2-Ͱ௨৴͠ɺ#BDLFOE4FSWFSͱͷ௨৴ʹ͸
    1SPUPDPM#V⒎FSTΛར༻
    5ZQF4DSJQU͔Βͷ1SPUPDPM#VGGFSTར༻
    #SPXTFS .PCJMF"QQ
    5ZQF4DSJQU
    (SBQI2-
    1SPUPDPM#V⒎FST

    View Slide

  42. ©2019 Wantedly, Inc.
    (SBQI2-ͱ1SPUPDPM#VGGFSTΛ
    దࡐదॴͰ࢖͍෼͚͍ͯΔ

    View Slide

  43. ©2019 Wantedly, Inc.
    ࣮ࡍʹ1SPUPDPM#VGGFSTΛར༻ͯ͠
    ײͨ͡ϝϦοτ

    View Slide

  44. ©2019 Wantedly, Inc.
    ૝૾Ҏ্ʹྑ͍෦෼͕
    ଟ਺͋ͬͨʂ

    View Slide

  45. ©2019 Wantedly, Inc.
    ࣮૷ΑΓ΋ৼΔ෣͍ʹूதͰ͖Δ
    w QSPUPpMFͷ಺༰͸γϯϓϧͰಡΈ΍͘͢ཧղ͠΍͍͢
    w QSPUPpMFΛݟΔ͚ͩͰɺϚΠΫϩαʔϏεͷৼΔ෣͍͕෼͔Δ
    w υϝΠϯϞσϧΛQSPUPpMFͷதʹએݴతʹهड़Ͱ͖Δ
    ʮ࣮૷ʯΑΓ΋ʮৼΔ෣͍ʯʹूதͯٞ͠࿦ɾઃܭ͕Ͱ͖Δ
    1SPUPDPM#VGGFSTΛར༻ͯ͠ײͨ͡ϝϦοτ

    View Slide

  46. ©2019 Wantedly, Inc.

    View Slide

  47. ©2019 Wantedly, Inc.

    View Slide

  48. ©2019 Wantedly, Inc.
    (PPHMFͷ"1*%FTJHO(VJEFͷଘࡏ
    w (PPHMF$MPVE"1*TͳͲ(PPHMFͷެ։"1*͸QSPUPpMFͰهड़
    ͞Ε͓ͯΓɺͦΕ͕४ڌ͢Δ"1*%FTJHO(VJEF΋ެ։͞Ε͍ͯΔɹ
    w DGIUUQTHJUIVCDPNHPPHMFBQJTHPPHMFBQJT
    w DGIUUQTDMPVEHPPHMFDPNBQJTEFTJHO
    w (PPHMF"1*T͸༏Ε࣮ͨྫͱͳ͍ͬͯΔ
    w "1*%FTJHO(VJEF͸"1*ઃܭͷࢀߟʹͰ͖Δ
    w ඪ४తͳܕͳͲ΋(PPHMFʹΑͬͯଟ਺ఆٛ͞Ε͍ͯͯར༻Ͱ͖Δ
    1SPUPDPM#VGGFSTΛར༻ͯ͠ײͨ͡ϝϦοτ

    View Slide

  49. ©2019 Wantedly, Inc.
    ੩తಈతݴޠ྆ํ͔Βѻ͍΍͍͢
    w QSPUPpMF͸"1*ʹର͢Δ੩తܕ෇͚ͱͯ͠ػೳ͢Δ
    w (Pͷ༷ͳ੩తܕ෇͚ݴޠ͔Β΋ѻ͍΍͍͢ɻQBZMPBEΛ੩తܕ෇͚
    ͞ΕͨTUSVDU΁NBSTIBMVONBSTIBMͰ͖Δɻ
    w 3VCZͷ༷ͳಈతܕ෇͚ݴޠͰ΋ѻ͍΍͍͢ɻpFME໊ͷUZQPͳͲΛ
    ߟ͑ͳͯ͘ྑ͍ɻ
    1SPUPDPM#VGGFSTΛར༻ͯ͠ײͨ͡ϝϦοτ

    View Slide

  50. ©2019 Wantedly, Inc.
    5FTU%SJWFO%FWFMPQNFOU 5%%

    ͕΍Γ΍͍͢
    w QSPUPpMFͱͯ͠"1*ͷৼΔ෣͍Λઌʹఆٛ͢ΔͷͰɺͦΕΛຬͨ͢
    5FTUΛ࣮૷ΑΓ΋ઌʹॻ͘͜ͱ͕ग़དྷΔ
    w ࣗવͳܗͰ5%%Λ࣮ફग़དྷΔ
    1SPUPDPM#VGGFSTΛར༻ͯ͠ײͨ͡ϝϦοτ

    View Slide

  51. ©2019 Wantedly, Inc.
    1SPUPDPM#VGGFSTͷԸܙΛड͚ͯ
    ։ൃΛਐΊΔ͜ͱ͕Ͱ͖ͨ

    View Slide

  52. ©2019 Wantedly, Inc.
    1SPUPDPM#VGGFSTΛར༻͢ΔதͰ
    ݟ͖͑ͯͨ஫ҙ఺

    View Slide

  53. ©2019 Wantedly, Inc.
    1SPUPDPM#VGGFSTΛར༻͢ΔதͰݟ͖͑ͯͨ஫ҙ఺
    QSPUPpMFͷڞ༗ํ๏͸੔උ͕ඞཁ
    w 1SPUPDPM#V⒎FST͸$MJFOU 4FSWFS྆ํ͕ಉ͡QSPUPpMFΛࢀর͢Δ
    ඞཁ͕͋Δɻ
    3FQPTJUPSZ͕෼͔Ε͍ͯΔ৔߹ɺQSPUPpMFͷڞ༗͕ඞཁ
    w ڞ༗ํ๏͝ͱͷϝϦοτɾσϝϦοτΛߟ͑Δඞཁ͕͋Δ
    w ୯७ͳίϐʔʜ࣮ݱ͕؆୯͕ͩɺQSPUPpMFͷมߋ௥ै͕೉͍͠
    w QSPUPEFQ౳ͷπʔϧʜ$MJFOU͔ΒWFSTJPOࢦఆ͕Մೳ
    w QSPUPpMFू໿SFQPTJUPSZʜSFQPTJUPSZʹQSPUPpMFΛू໿ɻ
    ίʔυੜ੒ͯ͠MJCSBSZͱͯ͠഑৴ɻEFQFOEBCPUͰมߋΛ௨஌ɻ
    w 8BOUFEMZͰ͸ϓϩδΣΫτ͝ͱʹόϥόϥ͕ͩɺQSPUPpMFू໿
    SFQPTJUPSZͷར༻͕૿Ճத

    View Slide

  54. ©2019 Wantedly, Inc.
    1SPUPDPM#VGGFSTΛར༻͢ΔதͰݟ͖͑ͯͨ஫ҙ఺
    1SPUPDPM#VGGFSTίϯύΠϥ QSPUPD

    ͷWFSTJPOʹ஫ҙ͢Δ
    w QSPUPDWFSTJPOͷҧ͍ʹΑͬͯɺࣗಈੜ੒ͨ͠ίʔυ಺༰͕มΘΔ
    w ޓ׵ੑ͸΄ͱΜͲյΕͳ͍͸͕ͣͩɺಛʹ(PͰݟͨ໨ͷEJ⒎͕
    େ͖͘WFSTJPOΛ্͛ͮΒ͔ͬͨ
    w ։ൃऀͦΕͧΕ͕QSPUPDͰίʔυੜ੒͢Δ৔߹ɺQSPUPDWFSTJPO
    Λἧ͑Δඞཁ͋Γ
    VCFSQSPUPUPPMͳͲΛར༻ͯ͠WFSTJPOΛݻఆ͢Δͱྑ͍

    View Slide

  55. ©2019 Wantedly, Inc.

    View Slide

  56. ©2019 Wantedly, Inc.
    1SPUPDPM#VGGFSTΛར༻͢ΔதͰݟ͖͑ͯͨ஫ҙ఺
    ݴޠʹΑͬͯ͸4FSJBMJ[BUJPO-JCSBSZ
    ͷػೳ͕ශऑ
    w +BWB4DSJQUpFMEͷTFU͸TFUUFSNFUIPEΛར༻͢Δඞཁ͕͋Δ
    w FHTFU*E TFU/BNF FUD
    w 3VCZSFQFBUFEpFME͸"SSBZMJLF͕ͩඍົʹ࢖͍উख͕ҧ͏
    w ୯७ͳTFU͸ग़དྷͣɺSFQMBDF͕ඞཁ
    w "DUJWF3FDPSEͷXIFSFʹͦͷ··౉ͤͳ͍

    View Slide

  57. ©2019 Wantedly, Inc.
    [1] book = Book.new(id: 1)
    =>
    [2] book.authors
    => []
    [3] book.authors.class
    => Google::Protobuf::RepeatedField
    [4] book.authors = [Author.new(id: 2)]
    Google::Protobuf::TypeError: Expected repeated field
    array
    from (pry):4:in `method_missing’
    [5] book.authors.replace([Author.new(id: 2)])
    => []
    [6] book.authors
    => []

    View Slide

  58. ©2019 Wantedly, Inc.
    [1] req = ListBookRequest.new(ids: [1, 2, 3])
    =>
    [2] req.ids.class
    => Google::Protobuf::RepeatedField
    [4] Book.where(id: req.ids).to_sql
    => "SELECT \"books\".* FROM \"books\" WHERE
    \"books\".\"id\" = NULL"
    [3] Book.where(id: req.ids.to_a).to_sql
    => "SELECT \"books\".* FROM \"books\" WHERE
    \"books\".\"id\" IN (1, 2, 3)"

    View Slide

  59. ©2019 Wantedly, Inc.
    1SPUPDPM#VGGFSTΛར༻͢ΔதͰݟ͖͑ͯͨ஫ҙ఺
    1SPUPDPM#VGGFST8FMMLOPXO5ZQFT
    ͷѻ͍͸গ͠໘౗
    w 1SPUPDPM#V⒎FST্Ͱ࣌ؒΛදݱ͢ΔHPPHMFQSPUPCVG5JNFTUBNQ
    w ݴޠ͝ͱͷ5JNF࣮૷ͱ͸ผͳͷͰຖճXSBQVOXSBQ͢Δඞཁ͋Γ
    w 4USJOH7BMVF *OU7BMVFͳͲͷOVMMBCMFUZQFT
    w TUSJOH JOUͳͲΛOVMMBCMFʹ͢Δҝʹར༻
    w ͜Ε΋XSBQVOXSBQͷख͕͔͔ؒΔ

    View Slide

  60. ©2019 Wantedly, Inc.
    1SPUPDPM#VGGFSTΛར༻͢ΔதͰݟ͖͑ͯͨ஫ҙ఺
    CJOBSZGPSNBUͷՄࢹԽํ๏Λߟ͑Δ
    ඞཁ͋Γ
    w MPHʹ࢒͢ࡍͳͲɺCJOBSZGPSNBUͷ··Ͱ͸ղऍͮ͠Β͍
    ྫ͑͹MPHΛར༻͢ΔλΠϛϯάͰ%FTFSJBMJ[F͢Δ
    w SFRVFTUSFTQPOTFͷ಺༰֬ೝʹ͸ɺՄࢹԽ͕ඞཁ
    +40/ͱ1SPUPDPM#V⒎FST྆ํΛฦ͢αʔόʔͱͯ͠։ൃ

    View Slide

  61. ©2019 Wantedly, Inc.
    1SPUPDPM#VGGFSTΛར༻͢ΔதͰݟ͖͑ͯͨ஫ҙ఺
    H31$HSQDHBUFXBZߏ੒ͷ࣌
    มߋʹΑͬͯ͸ޙํޓ׵ੑ͕յΕΔ
    w QSPUPpMFͷFOVN஋Λ૿΍ͨ͠ࣄʹΑͬͯɺSFRVFTUQBSBNFUFS
    Ͱ͋Δ+40/ͷ%FTFSJBMJ[FͰFSSPS͕ى͖ͨέʔε͕͋ͬͨ
    w H31$HSQDHBUFXBZߏ੒ͷ࣌͸ɺ҆શͳมߋ͔ෆ҆ͳ࣌͸ڍಈΛ
    ֬ೝͨ͠΄͏͕ྑ͍

    View Slide

  62. ©2019 Wantedly, Inc.
    ͍͔ͭ͘ͷ఺ʹ͸஫ҙ͠ͳ͕Β
    1SPUPDPM#VGGFSTΛར༻͠Α͏

    View Slide

  63. ©2019 Wantedly, Inc.
    ·ͱΊ

    View Slide

  64. ©2019 Wantedly, Inc.
    ·ͱΊ
    1SPUPDPM#VGGFSTΛ"1*ͷ4DIFNB
    ؅ཧʹར༻͢Δͱଟ͘ͷར఺͕͋Δ
    w QSPUPpMFͱͯ͠"1*ͷৼΔ෣͍Λએݴతʹهड़
    w ࣗಈੜ੒ͨ͠ίʔυʹΑͬͯ4DIFNBͱ࣮૷ͷҰகΛอূ
    w ੩తಈతܕ෇͚ݴޠ྆ํ͔Βѻ͍΍͍͢
    w TXBHHFSKTPOͷੜ੒ͳͲɺQSPUPDQMVHJOͷΤίγεςϜΛ׆༻Մೳ
    ϝϦοτΛڗड͠ੜ࢈ੑߴ͘։ൃ͠Α͏ʂ

    View Slide

  65. ©2019 Wantedly, Inc.
    "QQEFOEJYH31$ʹ͍ͭͯ
    H31$΋ݱࡏݕূத
    w LTDMVTUFS಺ͷϚΠΫϩαʔϏεʹରͯ͠FOWPZ͕TJEFDBSQSPYZ
    ͱͯ͠EFQMPZ͞ΕΔ༷ʹͳͬͨ
    )551MPBECBMBODJOH͕Մೳʹͳͬͨ
    w HSQDHBUFXBZΛ௨ͣ͞ʹ(PͷH31$αʔόʔͱ௨৴ͨ͠Γɺ৽͍͠
    3VCZαʔόʔΛH31$αʔόʔͱͯ͠։ൃ͢ΔࢼΈΛ͍ͯ͠Δ
    1SPUPDPM#V⒎FSTͷԸܙΛड͚ͭͭɺUSBOTQPSU΋ޮ཰Խ

    View Slide

  66. ©2019 Wantedly, Inc.
    1IPUP$SFEJU
    w "MFYXPOHIUUQTVOTQMBTIDPNQIPUPTM5[WBMDQT

    View Slide