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

gRPCで始める ハイパフォーマンス タイプセーフウェブ開発

gRPCで始める ハイパフォーマンス タイプセーフウェブ開発

gunmaweb #49

Tsubasa SEKIGUCHI

June 03, 2023
Tweet

More Decks by Tsubasa SEKIGUCHI

Other Decks in Programming

Transcript

  1. gRPCͰ࢝ΊΔ ϋΠύϑΥʔϚϯε λΠϓηʔϑ΢Σϒ։ൃ Introduction of high-performance and type-safe development with

    gRPC. Gunma.web #49 ςʔϚϑϦʔ 2023.06.03 @ Takasaki Met., Empire of Gunma Tsubasa SEKIGUCHI
  2. ࠓ͞Βฉ͚ͳ͍RPCʹ͍ͭͯ  3FNPUF1SPDFEVSF$BMMͷུ  αʔϏεؒͷ৘ใͷ΍ΓऔΓʹݹ͔͘Β 
 ࢖ΘΕ͍ͯΔ  ೄจ࣌୅ΑΓ͸ޙͰ͢ 

    ͍ΘΏΔΫϥΠΞϯταʔόʔܕͷ௨৴  αʔόʔ্ʹ࣮૷͞Ε͍ͯΔॲཧΛΫϥΠΞϯτ͔Β ύϥϝʔλ෇͖Ͱୟ͍ͯύϥϝʔλʹର͢Δॲཧ݁Ռ Λฦ͢
  3. ࠓ͞Βฉ͚ͳ͍RPCʹ͍ͭͯ  ͲͷΑ͏ʹϦΫΤετΛૹ৴͢Δ͔ɺ 
 ͲͷΑ͏ͳϑΥʔϚοτͰ௨৴͢Δ͔ʜ 
 ࣌୅ʹԠͯ͡มԽ͍ͯ͠Δ  ࠷ۙ͸)5514͕ओྲྀͷΑ͏Ͱ͢ɻ 


    9.-Λѻ͏9.-31$΍ 
 +40/Λ࢖͏+40/31$ͳͲ͕طଘʹ͋Γ·͢  ੲͷϓϩτίϧͰ$03#"ͱ͔%$0.ͱ͔ 
 ϐϯͱ͖·ͤΜ͔ʁ  ๻͸ϐϯͱ͜ͳ͍Ͱ͢  ӈͷֆըΈ͍ͨʹ࿛ԎΛ࢖͍ͬͯͨࠒ͸ͳ͔ͬͨΑ͏Ͱ͢
  4. ࠓ·ͰͷRPCͷΠέͯͳ͍఺  9.-31$΍+40/31$͸Α͘࢖ΘΕ͍ͯΔ 
 ϑΥʔϚοτͳͷͰಋೖ͠΍͍͢  ͨͩ͠ͲͪΒ΋ςΩετϕʔεͰ͋Γɺ 
 )551͸جຊతʹςΩετϕʔεͰσʔλΛ 


    ΍ΓऔΓ͢Δ͠ɺόΠφϦ΋ѻ͍ͮΒ͘ɺ 
 ௕࣌ؒࢄൃతʹσʔλΛ΍ΓऔΓͮ͠Β͍ 
 ௨৴࣌ͷΦʔόʔϔου΋ଘࡏ͢Δ  ࿛Ԏ͔Ϟʔϧε৴߸ΑΓ͸ϚγͰ͚͢Ͳ
  5. H31$͘Μͷ͕͜͜εΰΠ  H13$ͷجຊతͳίϯηϓτ  ಛఆͷݴޠ΍ϓϥοτϑΥʔϜʹґଘ͠ͳ͍  ϖΠϩʔυΛ໰Θͳ͍  ૬ޓӡ༻ੑ͕͋ΓҰൠతͳΠϯλʔωοτͰ΋ 


    ར༻Մೳ  ൚༻ੑ͕͋Γͳ͕Βઐ༻ͷ΋ͷͱൺ΂ͯ 
 ύϑΥʔϚϯε໘ͰҰൠʹྼΔ͜ͱ͸ͳ͍  ετϦʔϛϯάͰͷ৘ใ఻ୡʹରԠ͍ͯ͠Δ
  6. H31$͘Μͷ͕͜͜Α͘ͳ͍  )551ͰH31$ͱ௨৴͢Δ৔߹ɺ)551Λ 
 ಋೖ͢Δඞཁ͕͋Δ  ͱ͸͍͑ɺ)551ͷΈͰαʔϏεΛߦ͏ͷ͸ 
 ݱ࣌఺Ͱ͸ݫ͍͠ͷͰɺී௨͸&OWPZ͋ͨΓͷ 


    ϓϩΩγΛט·ͤΔ  ༨ஊͰ͕͢3VTUͷUPOJDͱ͍͏αʔόʔϥΠϒϥϦ͸ ඪ४ػೳͰ)551Λ࿩ͯ͘͠ΕΔͷͰ 
 &OWPZ͕ෆཁͰ͢  ͪͳΈʹӈͷֆը͸ΞυϦΞʔϯɾϒϥ΢Τϧͷ 
 ʮ͍ۤༀ #JUUFS5POJD ʯͰ͢
  7. H31$͘Μͷ͕͜͜Α͘ͳ͍  1SPUPDPM#V ff FSTͷఆٛϑΝΠϧΛ࢖͑͹ 
 ϑϩϯτΤϯυͷ"1*௨৴ίʔυΛੜ੒Ͱ͖Δ͕ɺ 
 ٯʹݴ͏ͱఆٛϑΝΠϧ͕ڞ༗͞Ε͍ͯͳ͍ͱ௨৴ ࣗମͰ͖ͳ͍

     ڞ༗͞Ε͍ͯͯ΋ఆٛϑΝΠϧ͕ݹ͔ͬͨΒ 
 ಉظ͞Ε͍ͯͳ͔ͬͨΒ ΫϥΠΞϯτ͔Β 
 ୟ͚ͳ͍͔΋  ࠷ۙ+3ͷӺͦ͹͔Βי೑͕ೖͬͯΔڶഴ͕ͳ͘ͳͬͯ൵͍͠Ͱ͢
  8. H31$͸Ͳ͏࢖͏ͷʁ  ϓϩτίϧఆٛϑΝΠϧΛ࡞੒ QSPUP   ϓϩτίϧఆٛϑΝΠϧ͔Β࣮ࡍʹ࢖͏ݴޠͷ 
 ιʔείʔυΛੜ੒ͯ͠΋Β͏ 

    ͕Μ͹Δ syntax = "proto3"; package app.trainlcd.grpc; service StationAPI { rpc GetStationById (GetStationByIdRequest) returns (SingleStationResponse) {} rpc GetStationByGroupId (GetStationByGroupIdRequest) returns (MultipleStationResponse) {} rpc GetStationByCoordinates (GetStationByCoordinatesRequest) returns (MultipleStationResponse) {} rpc GetStationsByLineId (GetStationByLineIdRequest) returns (MultipleStationResponse) {} } message GetStationByIdRequest { uint32 id = 1; }
  9.  ϓϩτίϧఆٛϑΝΠϧΛ࡞੒ QSPUP  ϓϩτίϧఆٛϑΝΠϧΛ࡞੒ QSPUP   ϓϩτίϧఆٛϑΝΠϧ͔Β࣮ࡍʹ࢖͏ݴޠͷ 


    ιʔείʔυΛੜ੒ͯ͠΋Β͏  ͕Μ͹Δ syntax = "proto3"; package app.trainlcd.grpc; service StationAPI { rpc GetStationById (GetStationByIdRequest) returns (SingleStationResponse) {} rpc GetStationByGroupId (GetStationByGroupIdRequest) returns (MultipleStationResponse) {} rpc GetStationByCoordinates (GetStationByCoordinatesRequest) returns (MultipleStationResponse) {} rpc GetStationsByLineId (GetStationByLineIdRequest) returns (MultipleStationResponse) {} } message GetStationByIdRequest { uint32 id = 1; }
  10.  ϓϩτίϧఆٛϑΝΠϧΛ࡞੒ QSPUP // example.proto // Protocol Buffers 3ͷه๏Ͱهड़͢Δ͜ͱΛએݴ syntax

    = “proto3"; package ύοέʔδ໊; service αʔϏε໊ { rpc ϓϩγʔδϟ໊ (Ҿ਺ͱͯ͠ड͚औΔϝοηʔδܕ) returns (ฦΓ஋ͱͳΔϝοηʔδܕ) {} } message ϝοηʔδܕͷ໊લ { ܕ ϑΟʔϧυ໊ = ඥ෇͚ΔϑΟʔϧυ൪߸(1,2,3…); } ߏ଄ͱͯ͠͸͜Μͳײ͡
  11.  ϓϩτίϧఆٛϑΝΠϧΛ࡞੒ QSPUP // empireCivilServant.proto // ͨͱ͑͹…ࢢ໾ॴͰ࢖͏ϓϩτίϧΛఆٛ͢Δ syntax = “proto3”;

    package org.gunmaweb.grpc; service EmpireCivilServant { rpc GetCitizen (CitizenRequest) returns (CitizenResponse) {} } message CitizenRequest { uint32 id = 1; } message CitizenResponse { uint32 id = 1; string name = 2; bool is_happiness = 3; // gRPCؔ܎ͳ͍Ͱ͕͢ࢢຽͷ޾෱͸ٛ຿Ͱ͢ } ࢢ໾ॴͷࢢຽ؅ཧγεςϜ͔Կ͔Ͱ࡞Γͦ͏ͳϓϩτίϧఆٛ
  12.  ϓϩτίϧఆٛϑΝΠϧΛ࡞੒ QSPUP // enum.proto enum City { TAKASAKI =

    0; // enumͷ஋͸0͔Β࢝·Βͳ͍ͱμϝ MAEBASHI = 1; OTA = 2; ISESAKI = 3; TATEBAYASHI = 4; … } // Ϩεϙϯε໊͸લͷεϥΠυͱಉ͡Ͱ͢ message CitizenResponse { uint32 id = 1; string name = 2; bool is_happiness = 3; // gRPCؔ܎ͳ͍Ͱ͕͢ࢢຽͷ޾෱͸ٛ຿Ͱ͢ City city_of_residence = 4; } &OVN΋͋Γ·͢
  13. H31$͸Ͳ͏࢖͏ͷʁ  ϓϩτίϧఆٛϑΝΠϧΛ࡞੒ QSPUP   ϓϩτίϧఆٛϑΝΠϧ͔Β࣮ࡍʹ࢖͏ݴޠͷ 
 ιʔείʔυΛੜ੒ͯ͠΋Β͏ 

    ͕Μ͹Δ syntax = "proto3"; package app.trainlcd.grpc; service StationAPI { rpc GetStationById (GetStationByIdRequest) returns (SingleStationResponse) {} rpc GetStationByGroupId (GetStationByGroupIdRequest) returns (MultipleStationResponse) {} rpc GetStationByCoordinates (GetStationByCoordinatesRequest) returns (MultipleStationResponse) {} rpc GetStationsByLineId (GetStationByLineIdRequest) returns (MultipleStationResponse) {} } message GetStationByIdRequest { uint32 id = 1; }
  14.  ϓϩτίϧఆٛϑΝΠϧ͔Β࣮ࡍʹ࢖͏ݴޠͷ 
 ιʔείʔυΛੜ੒ͯ͠΋Β͏ ͪͳΈʹલͷεϥΠυͷίϚϯυΛ࣮ߦ͢Δͱ 
 ͜Μͳײ͡ͷίʔυ ઌ಄ͷൈਮ ͕ग़ྗ͞Ε·͢ //

    empire_pb.js // source: empire.proto /** * @fileoverview * @enhanceable * @suppress {missingRequire} reports error on implicit type usages. * @suppress {messageConventions} JS Compiler reports an error if a variable or * field starts with 'MSG_' and isn't a translatable message. * @public */ // GENERATED CODE -- DO NOT EDIT! /* eslint-disable */ // @ts-nocheck var jspb = require('google-protobuf'); var goog = jspb; var global = (typeof globalThis !== 'undefined' && globalThis) || (typeof window !== 'undefined' && window) || (typeof global !== 'undefined' && global) || (typeof self !== 'undefined' && self) || (function () { return this; }).call(null) || Function('return this’)();
  15. # ts-protoc-genΛಥͬࠐΜͩύε PROTOC_GEN_TS_PATH=“./node_modules/.bin/protoc-gen-ts” # ͖ͬ͞࡞ͬͨ.protoϑΝΠϧ PROTOC_SRC_PATH=“./empire.proto” # ੜ੒͞Εͨίʔυ͕͜͜ʹ౤͛ࠐ·ΕΔ OUT_DIR=“./generated” protoc

    \ --plugin="protoc-gen-ts=${PROTOC_GEN_TS_PATH}" \ --js_out="import_style=commonjs,binary:${OUT_DIR}" \ --ts_out="${OUT_DIR}" \ ${PROTOC_SRC_PATH}  ϓϩτίϧఆٛϑΝΠϧ͔Β࣮ࡍʹ࢖͏ݴޠͷ 
 ιʔείʔυΛੜ੒ͯ͠΋Β͏ ίϚϯυ͕௕͍ͷͰɺ γΣϧεΫϦϓτ౳Λ࡞͙ͬͯ͢࢖͑ΔΑ͏ʹ͠·͠ΐ͏
  16.  ϓϩτίϧఆٛϑΝΠϧ͔Β࣮ࡍʹ࢖͏ݴޠͷ 
 ιʔείʔυΛੜ੒ͯ͠΋Β͏ ͜ΕͰ5ZQF4DSJQUͷఆٛϑΝΠϧ ͪ͜Β΋ઌ಄ͷൈਮ ͕ు͖ग़͞Ε·ͨ͠ɻ Α͔ͬͨͰ͢Ͷ // package:

    org.gunmaweb.grpc // file: proto/empire.proto import * as jspb from "google-protobuf"; export class CitizenRequest extends jspb.Message { getId(): number; setId(value: number): void; serializeBinary(): Uint8Array; toObject(includeInstance?: boolean): CitizenRequest.AsObject; static toObject(includeInstance: boolean, msg: CitizenRequest): CitizenRequest.AsObject; static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>}; static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>}; static serializeBinaryToWriter(message: CitizenRequest, writer: jspb.BinaryWriter): void; static deserializeBinary(bytes: Uint8Array): CitizenRequest; static deserializeBinaryFromReader(message: CitizenRequest, reader: jspb.BinaryReader): CitizenRequest; }
  17.  ͕Μ͹Δ  ϓϩτίϧఆٛϑΝΠϧΛ࡞੒ QSPUP   ϓϩτίϧఆٛϑΝΠϧ͔Β࣮ࡍʹ࢖͏ݴޠͷ 
 ιʔείʔυΛੜ੒ͯ͠΋Β͏

     ͕Μ͹Δ w ؤுΔ͔௒ؤுΔ͔ͷ୒Ͱߟ͑ͯԼ͍͞ w ͨͿΜ෼͸࣮֬ʹա͍͗ͯΔͷͰऴΘΓ·͢