@ Hatena Engineer Seminar #12
ͯͳϒϩά λάͷٕज़બHatena Engineer Seminar #12id:aereal
View Slide
• id:aereal• GitHub: @aereal• ϒϩά౷߹νʔϜ ςοΫϦʔυ• https://this.aereal.org/
https://this.aereal.org/
ϒϩάαʔϏεͷ HTTPSԽΛࢧ͑ͨ AWSͰ࡞ΔϐλΰϥεΠονhttps://speakerdeck.com/aereal/the-construction-of-large-scale-tls-certificates-management-system-with-aws
speakerdeck.com/papix/hatena-engineer-seminar-number-10?slide=52
͢͜ͱ• ͯͳϒϩά λάͷ։ൃʹ͍ͭͯ• ͯͳϒϩά λάͷߏ• ֤ʑͷٕज़બʹ͍ͭͯ
͞ͳ͍͜ͱ• σʔλҠߦ• ͜Ε͚ͩͰ͍Ζ͍ΖͤΔͷͰػձ͕͋Ε• ϓϩδΣΫτཧ• Πϯϑϥߏཧ• Service Mesh• ֎෦APIݺͼग़͕͠ଟ͍ͷͰݕ౼ͨ͠• ϦϦʔεલͷݕূஈ֊ͳͷͰࣽ٧·ͬͨΒ͓͠͠·͢
։ൃʹ͍ͭͯ• αʔϏεͷಛ• ։ൃମ੍• ͜Ε·Ͱͷ։ൃͷৼΓฦΓ
ͯͳϒϩά λάͷಛ• Ϣʔβ͕ίϯςϯπΛฤू͢Δ• ༧ଌ͕͍͠ΞΫηεͷมಈ• ݕࡧΤϯδϯʹΠϯσοΫεͯ͠Β͍͍ͨ• దͳΩϟογϡઓུ• ߴ͍εέʔϥϏϦςΟ• αʔόαΠυͰstaticʹHTMLΛฦ͢ඞཁ͕͋Δ
։ൃମ੍• ΤϯδχΞɾσβΠφʔɾσΟϨΫλʔʹΑΔ খنͳνʔϜ• ΈΜͳԿ͔͠ΒSM, POͳͲͷϩʔϧΛෳ͍࣋ͬͯΔ• σβΠφʔίʔσΟϯά͢Δ
࿀ʹࣄʹେ͠• (ΤϯδχΞʹݶΒͣ) Δ͜ͱ͕ଟ͍!• ਓ͕ؒΔ͜ͱΛݮΒ͍ͨ͠• ࣗಈԽɺίʔυੜɺ͍ͷʹר͔ΕΔ, etc.• ਓ͕গͳ͚ΕίϛϡχέʔγϣϯίετԼ͕Δ• →νϟϨϯδϯάͳ͜ͱΛ͢Δྑ͍ػձ• →·ͣաڈΛৼΓฦΖ͏
ͯͳϒϩάͷ։ൃΛৼΓฦͬͯ ࣍ʹ׆͔ͤΔ͜ͱͳ͍͔
ͯͳϒϩάͰͷࠔΓ͝ͱ• ϓϨθϯςʔγϣϯͷࢄ• ΫϥΠΞϯταΠυͱαʔόαΠυͷAPIϓϩτίϧ
ϓϨθϯςʔγϣϯͷࢄ• αʔόαΠυͷςϯϓϨʔτ• ΫϥΠΞϯταΠυ• DOMΛ৮Δ• React
ϓϨθϯςʔγϣϯͷࢄ• Des.ʮ͜͜ͷςΩετΛήετͷ͚࣌ͩม͍͑ͨͰ͢ʯ• Eng.ʮαʔόαΠυͰ͍ͬͯΔͷͰม͓͖͑ͯ·͢Ͷʯ• Des.ʮ͜ͷmarginม͍͑ͨͷͰΫϥεΛ͚͍ͨͰ͢ʯ• Eng.ʮ͜͜jQueryͰ͍ͬͯΔͷͰ͓͖ͬͯ·͢Ͷʯ• Des.ʮ͜͜ͷςΩετͲ͏ͬͯग़͍ͯ͠ΔΜͰ͔͢?ʯ• Eng.ʮReactͰ͍ͬͯͯɺJSͷίʔυ͕͜͜ʹ͋Γ·͢ʯ
ϓϨθϯςʔγϣϯͷ౷Ұ• ΫϥΠΞϯταΠυαʔόαΠυReactʹ• ϨΠϠू• SSR (= Server-side Rendering) ͍ͨ͠ (ޙड़) ͷͰ߹
API• αʔόαΠυͱΫϥΠΞϯταΠυΛAPIͰܨ͙ΞʔΩςΫνϟྲྀߦ͍ͬͯΔ• ͍ΖΜͳπʔϧ͕ग़ճ͍ͬͯΔ• gRPC, GraphQL, Swagger, etc.• ͍ͷʹר͔ΕΑ͏ → GraphQL (ޙड़)
Server-side Rendering• ݕࡧΤϯδϯΫϩʔϥͳͲʹΠϯσοΫεͯ͠΄͍͠• ݴ༿ڵຯΛ࣋ͬͨਓΛͯͳϒϩάɾͯͳϒοΫϚʔΫΛհͯ͠ܨ͍͛ͨͱ͍͏ϛογϣϯ• ύϑΥʔϚϯεͷد༩• scriptingΛڬ·ͳ͍ͷ͕ͳΜ͔ͩΜ͍ͩ• ΠϯλϥΫςΟϒͳཁૉ͕গͳ͍ͱ͍͏ࣄ͋Δ
Q. ·ͩSSR͍Δ?• Q. Googlebot͕༻͢ΔChromium͕࠷৽ʹͳ͚ͬͨͲ?• The new evergreen Googlebot• A. Googlebot͚ͩߟ͑ΔͳΒඞਢͰͳ͘ͳͬͨ• A. ͔͠͠ଞʹΫϩʔϥ͍Δ• Twitter, Facebook, Bing, etc.
͜͜·Ͱͷ·ͱΊ
ͯͳϒϩά λάͷಛ• Ϣʔβ͕ίϯςϯπΛฤू͢Δ• ༧ଌ͕͍͠ΞΫηεͷมಈ• ݕࡧΤϯδϯʹΠϯσοΫεͯ͠Β͍͍ͨ• దͳΩϟογϡઓུ• ߴ͍εέʔϥϏϦςΟ• αʔόαΠυͰstaticʹHTMLΛฦ͢ඞཁ͕͋Δ࠶ܝ
·ͱΊ• ϓϨθϯςʔγϣϯReactʹू• αʔόͱΫϥΠΞϯτAPIͰ݁߹͢Δ• ͦͷͨΊͷΤίγεςϜʹ;ΜͩΜʹ͔ͬΔ• SSR͢Δ
ͯͳϒϩά λάͷߏ
frontGraphQL APIϒϥβDBॳճGETSSRͷͨΊʹ σʔλΛfetchCSRҎ߱ fetchͯͳϒϩάͯͳϒοΫϚʔΫ
ߏ• frontGraphQL API͔ΒσʔλΛऔ͖ͬͯͯSSR͢Δ• ϒϥβfrontΞΫηε͠HTMLΛฦͯ͠Β͏• Πϯϑϥͯ͢AWS• ALB, ECS, RDS (Aurora)
GraphQL• ΫϥΠΞϯτɾαʔόڞʹΤίγεςϜ͕ॆ࣮͍ͯ͠Δ• TypeScript, Goͷίʔυੜ• (։ൃணख࣌grpc-webunstableͩͬͨ)• ͯͳϒϩά λάͰαʔόαΠυΛGo w/gqlgenͰ࣮• ΫϥΠΞϯτϥΠϒϥϦApolloΛ࠾༻
gqlgen• gqlgenSchema͔ΒresolverͷܗΛੜͯ͘͠ΕΔ• ಉ͡Α͏ͳίʔυΛίϐϖ͢Δࠈ͕ͳ͍• interface{} ͕΄ͱΜͲग़ͯ͜ͳ͍type-safe͞• refs. MTC2018 ΧϯϑΝϨϯεLPͷཪ ʙGraphQLฤʙ
Apollo• apollographql.com• ϥΠϒϥϦͱSaaS͔ΒͳΔ• ͯͳϒϩά λάͰapollo-client, react-apollo, apollo-toolingΛར༻
apollo-tooling• apollo client:codegenͰεΩʔϚͱquery/fragmentΛύʔεɺTypeScriptͷܕఆٛΛੜ͢Δ• ͪ͜Βany͕΄ͱΜͲग़ͯ͜ͳ͍type-safe͞ͳͷͰ҆৺ײ͕͋Δ• APIʹ͓͚Δtype-safeͷ҆৺ײΫϥΠΞϯτɾαʔό྆ํ͕ݎ࿚Ͱͳ͍ͱ࣮ݱ͞Εͳ͍ͷͰଚ͍
apollo-client• apollo-clientFetch APIΛGraphQL͚ʹྑ͍ײ͡ʹแΜͰ͘ΕΔ• linkͱ͍͏ϛυϧΣΞΛΈ߹ΘͤͯɺೝূϔομͷՃΤϥʔϋϯυϦϯάΛϓϥΨϒϧʹ࡞ΕΔwww.apollographql.com/docs/link/overview/
react-apollo• query/mutationΛൃߦͨ݁͠ՌΛ͢Higher-orderComponent• TypeScriptͩͱܕมΛͯ͠anyΛճආͰ͖Δ• queryͱvariablesͷܕΛࢦఆͰ͖Δ
const ALL_PEOPLE_QUERY = gql`query All_People_Query {allPeople {people {idname}}}`;interface Data {allPeople: {people: Array<{ id: string; name: string }>;};};interface Variables {first: number;};const AllPeopleComponent = query={ALL_PEOPLE_QUERY}>{({ loading, error, data }) => { ... }}www.apollographql.com/docs/react/recipes/static-typing/
GraphQLͷԸܙΤϯδχΞσβΠφʔϞοΫresolverΛ࣮ίʔσΟϯά։࢝resolverຊ࣮
GraphQLͷԸܙ• GraphQLͱApolloͷ͓͔͛Ͱѹతʹলྗ• ͜Ε·Ͱͱҧ͏͜ͱ: நʹґଘͰ͖Δ• ґଘੑٯసͷݪଇ dependency inversion principle• ܕݕ͕ࠪແ͍߹: ۩ (ͷܕ) ͰΓͱΓ͢Δ = յΕ͍͢• ۩ͷܕ is ಈ͍͍ͯΔίʔυͷฦΓ
SSR• ReactͰSSR͢ΔͳΒNext.js͕༗ྗͰͳ͍͔• ͦͦNext.jsͱԿͳͷ͔• ΫϥΠΞϯτͱαʔόؒͰͳΔ͘ίʔυΛڞ௨ԽͰ͖ΔΑ͏ͳworkaroundू• ศརWebpackઃఆू• ศརExpressϛυϧΣΞू
͠λΠϜϚγϯ͕͋Ε• Google App Engine/SEFirebaseΛબΜ͔ͩ͠Εͳ͍• ϑϧϚωʔδυαʔϏεͷॆ࣮GCPͷํ͕ߴ͍ͱࢥ͏
·ͱΊ
·ͱΊ• GraphQLͷ͓͔͛ͰগਓͰૉૣ͘։ൃͰ͖͍ͯΔ• ϨόϨοδ͕ޮ͘• ϦϦʔεΛ͓ͨͷ͠Έʹ!