Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
BFF and Developer Experience
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Yosuke Kurami
May 18, 2019
Programming
4.1k
15
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
BFF and Developer Experience
Inside Frontend 2019
Yosuke Kurami
May 18, 2019
More Decks by Yosuke Kurami
See All by Yosuke Kurami
TypeScript LSP の今までとこれから
quramy
1
2k
フロントエンドテストの育て方
quramy
12
3.8k
App Router 悲喜交々
quramy
8
730
上手に付き合うコンポーネントテスト
quramy
6
2.4k
Patched fetch did not work
quramy
6
780
GraphQL あるいは React における自律的なデータ取得について
quramy
18
5.8k
Next.js App Router
quramy
15
3.9k
Fragment Composition of GraphQL
quramy
17
4.8k
reg-viz VRT tools
quramy
4
1.7k
Other Decks in Programming
See All in Programming
ユニットテストの先へ:テスト技法で要求・仕様を整理するJava開発実践 / Beyond_Unit_Testing_Practical_Java_Development_Techniques_for_Organizing_Requirements_and_Specifications
shimashima35
0
410
Make SRE Operations Easier with Azure SRE Agent
kkamegawa
0
6.9k
さぁV100、メモリをお食べ・・・
nilpe
0
150
並列実装の現場、2ヶ月間実務でAIを使い倒したAIもPCも私も限界が近い
ming_ayami
0
130
Webフレームワークの ベンチマークについて
yusukebe
0
170
Performance Engineering for Everyone
elenatanasoiu
0
180
ふつうのFeature Flag実践入門
irof
8
4.1k
そのテスト、説明できますか?~LWテスト戦略FW~のご紹介
nakahara
0
150
C# and C++ Interoperability - cho-dotnetnew
harukasao
0
280
脅威をエンジニアリングの糧にして――現場編 / Turning Threats into Engineering Fuel — Field Edition
nrslib
0
290
依存関係から依存物へ―Dependencyという言葉の歴史をひも解く
j_lee
0
120
LLM本来の能力を解き放つサンドボックス技術とAI民主化への適用
yukukotani
3
4.3k
Featured
See All Featured
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
200
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
2.9k
Git: the NoSQL Database
bkeepers
PRO
432
67k
svc-hook: hooking system calls on ARM64 by binary rewriting
retrage
2
300
Why You Should Never Use an ORM
jnunemaker
PRO
61
9.9k
Typedesign – Prime Four
hannesfritz
42
3.1k
The Illustrated Children's Guide to Kubernetes
chrisshort
51
52k
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
170
Practical Orchestrator
shlominoach
191
11k
Joys of Absence: A Defence of Solitary Play
codingconduct
1
400
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.5k
Rebuilding a faster, lazier Slack
samanthasiow
85
9.5k
Transcript
#'' %FWFMPQFS&YQFSJFODF :PTVLF,VSBNJ *OTJEF'SPOUFOE
"CPVUNF w ݟ༸ีʢ!2VSBNZʣ w ͓͠͝ͱ w ϑϩϯτΤϯυΤϯδχΞBU'0-*0 w ٕज़ސBU'J/$ w
։ൃิॿπʔϧΛ࡞Δͷׂ͕ͱ͖
None
None
#''
#BDLFOET'PS'SPOUFOET
ϑϩϯτΤϯυͷͨΊͷ αʔόʔ
By Sam Newman The BFF is tightly coupled to a
specific user experience, and will typically be maintained by the same team as the user interface. https://samnewman.io/patterns/architectural/bff/
ͳͥ#''ʁ
ϚΠΫϩαʔϏεͷ౷߹ͷͨΊ
6TFSFYQFSJFODF ύϑΥʔϚϯε 6*ʹඞཁॆͳ"1* ౷Ұ͞Εͨ6* .JDSPTFSWJDFT υϝΠϯʹྗͨ͠։ൃ γϯϓϧͰ࠶ར༻ੑͷߴ͍"1* αʔϏε͝ͱͷٕज़ಛҟੑ
6TFSFYQFSJFODF ύϑΥʔϚϯε 6*ʹඞཁॆͳ"1* ౷Ұ͞Εͨ6* .JDSPTFSWJDFT υϝΠϯʹྗͨ͠։ൃ γϯϓϧͰ࠶ར༻ੑͷߴ͍"1* αʔϏε͝ͱͷٕज़ಛҟੑ #''
'0-*0ʹ͓͚Δ#''
None
ࠓओʹίΠπͷ͓
8FC#''ͷ͓͠͝ͱ "1*"HHSFHBUJPO /PEFKTLPB 4FSWFS4JEF3FOEFSJOH 3FBDU 3FEVY
None
#''ಋೖͰྑ͍͜ͱ͍ͬͺ͍ όοΫΤϯυυϝΠϯ͝ͱͷαʔϏεͷ։ൃʹྗ ϑϩϯτΤϯυ6*ͷཁٻΛͦͷ··"1*Խ 443ʹΑΔߴͳॳظඳը
ྑ͍͜ͱ͍ͬͺ͍
ɾɾɾ
Ռͨͯ͠ຊ͔ʁ
ϑϩϯτͷࣄ૿͑ͯΔ w 41"ͷΈͷ߹ w 3FBDU 3FEVY෦Λ࡞ΕऴΘΓ w 41" #''ͷ߹ w
ࣗͨͪͰ"1*αʔόʔ࡞Δඞཁ͋Γ
ʮ#''Λ࠾༻͢Δʯ ʮϨΠϠʔ͕૿͑Δʯ ʮ։ൃʹ͕͔͔࣌ؒΔʯ
͜ͷ··͡Όμϝͩ
Α͏͘ࠓͷςʔϚ #''ΛαΫαΫ։ൃ͢ΔͨΊʹ
όοΫΤϯυͷ։ൃΛͨͳ͍ #''ͷ։ൃɾվम࣌Ͱɺ࣮αʔϏε͕ಈ࡞͠ͳͯ͘ Α͍ ϑϩϯτΤϯυόοΫΤϯυؒͰʮͲͷΑ͏ͳ"1* Ͱ͋Δ͖͔ʯͷ߹ҙ͕औΕ͍ͯΕฒߦ։ൃՄೳ
*%-ESJWFOEFWFMPQNFOU w *%- *OUFSGBDF%FpOJUJPO-BOHVBHF w "1*༷Λهड़͢ΔͨΊͷݴޠ w FH4XBHHFS H31$
(SBQI2- 84%- 40"1 FUDʜ w *%-͔Β֤छݴޠͷίʔυΛੜͰ͖Δͱخ͍͠
5ISJGU w '0-*0Ͱ5ISJGUͱ͍͏31$ϑϨʔϜϫʔΫΛ࠾༻ w IUUQTUISJGUBQBDIFPSH w ܕγεςϜΛඋ͑ͨ*%- w *%-͔Β+BWB4DSJQUΫϥΠΞϯτίʔυʢެࣜπʔϧʣ
5ISJGU*%- +BWB4DSJQU $MJFOU 8FC.PCJMF#'' /PEFKT 'JOBHMF 4FSWFS 4FSWJDF 4DBMB ࣗಈੜ
ϩδοΫΛ࣮
None
ࣗಈੜ͚ͩͰ ฒߦ։ൃʹ·ͩෆे
αʔϏεͷԾσʔλ͕ඞཁ ։ൃதαʔϏεͷ"1*ϞοΫσʔλʹࠩ͠ସ͍͑ͨ ։ൃࡁΈαʔϏεͷ"1*ςετڥΛར༻͍ͨ͠ ʢFHجຊతͳϢʔβʔใʣ ϞοΫͷར༻ੋඇ#''ͷίʔυ͔ΒෆՄʹ͍ͨ͠
͜͏͍͏ͱ͖ͦ͜ ʮؔ৺ࣄͷʯ
$SPTTDVUUJOHDPODFSO #''ͷओॲཧɿ ʮಛఆͷϚΠΫϩαʔϏεʹॲཧΛґཔ͢Δʯ ԣஅతؔ৺ࣄɿ ʮϚΠΫϩαʔϏεͷΓΛϞοΫ͢Δʯ
None
Πϯλʔηϓλ ࡞ΕͰ͚ͦ͏
ࢀߟɿ"01 w "TQFDU0SJFOUFE1SPHSBNNJOH w ԣஅతؔ৺ࣄΛॲཧຊମ͔Β͢Δ͜ͱ w ԣஅతؔ৺ࣄͷྫ w ϩΪϯά ྫ֎ϋϯυϦϯά
τϨʔγϯά FUDʜ
$PEFFYBNQMF
5ISJGUJOUFSGBDF *%- include "user_typedef.thrift" include "some_service_struct.thrift" include "common_exceptions.thrift" service SomeService
{ some_service_struct.UserAssetInfo getUserAsset( 1: required user_typedef.UserId userId ) throws ( 1: common_exceptions.ServerError serverError ) }
5ISJGUDMJFOU HFOFSBUFE ˞࣮ࡍ5ISJGUπʔϧ͕&4Ͱग़ྗ͢ΔͨΊɺ͔ͳΓಡΈʹ͍͘ class SomeServiceClient { constructor() { this.connection =
createConnection(); } getUserAsset(userId) { return new Promise(res => { this.connection.once("res_getUserAsset", res); this.connection.send("getUserAsset", [userId]); }); } }
$MJFOUΛར༻͢ΔՕॴʢ#''ʣ class SomeBFFLogic { constructor(someServiceClient, anotherServiceClient) { this.someServiceClient = someServiceClient;
this.anotherServiceClient = anotherServiceClient; } async getUserAssetWithDetail(userId) { const summary = await this.someServiceClient.getUserAsset(userId); const detail = await this.anotherServiceClient.getAssetDetail(summary); return { ...summary, ...detail }; } }
Πϯλʔηϓτʂ const mockResponseHandler = { get: (target, methodName) => {
const delegate = target[methodName]; if (typeof delegate !== "function") return delegate; return (...args) => getMockData(methodName).catch(delegate.bind(target, ...args)); }, }; const someServiceClient = process.env.NODE_ENV === "production" ? new SomeServiceClient() : new Proxy(new SomeServiceClient(), mockResponseHandler);
%JSFDU1SPYZͷར w ҆৺ײ w #''ओॲཧʢ5ISJGU$MJFOUͷݺͼग़͠ʣͷมߋෆཁ w ࣗಈੜ͞Εͨ5ISJGU$MJFOUͷίʔυͦͷ·· w IBOEMFSHFUτϥοϓͷҾ͔Β"1*໊শΛऔಘͰ͖ΔͨΊɺIBOEMFS ͷ෦ॲཧ͕۩ମతͳ"1*໊শΛؾʹ͢Δඞཁ͕ͳ͍
*OUFSDFQUPSDIBJO w OFX1SPYZ ͷΓΛ࠶OFX1SPYZʹ༩͑ΕɺෳͷΠϯ λʔηϓλʢIBOEMFSʣΛ࿈Ͱ͖Δ w '0-*0ͷ#''ͰϞοΫҎ֎ʹෳͷΠϯλʔηϓλΛ߹ w ࣮"1*ݺͼग़݁͠ՌͷϞοΫσʔλԽɺϦτϥΠɺ
2VFSZܥͷॲཧ ݶఆͰʣDBDIFɺFUDʜ
%ZOBNJDWT4UBUJD w %ZOBNJD1SPYZҎ֎ͰΠϯλʔηϓλΛ࣮ݱ͢Δ͜ͱՄೳ w ྫɿ#BCFMQMVHJO5ZQF4DSJQUDVTUPNUSBOTGPSNFSʹΑΓɺࣗಈ ੜ͞ΕͨίʔυΛ੩తղੳͯ͠ɺΞεϖΫτΛ৫ΓࠐΉΑ͏ʹ͢ Δʢ"45USBOTGPSNBUJPOʣ w ͜ͷ߹ɺϏϧυ࣌ʹ৫ΓࠐΈੋඇ͕֬ఆ͢Δ w
σϓϩΠޙʹڥมͰ৫ΓࠐΈͷ༗ޮແޮΛ੍ޚͰ͖ΔΑ͏ʹɺಈ తͳํࣜΛબͨ͠
༨ஊ w ࣮ͷͱ͜ΖϞοΫͷͨΊʹΠϯλʔηϓλͷΈΛ༻ҙͨ͠Θ͚Ͱ ͳ͍ w ॳʹ໘͍ͯͨ͠ʮϦΫΤετ͕ྃ͠ͳ͍αʔϏε"1*ίʔ ϧ͕كʹൃੜ͢Δʯͩͬͨ w ʮ൚༻తͳλΠϜΞτػߏΛͯ͢ͷϚΠΫϩαʔϏεݺͼग़͠ʹ ৫ΓࠐΉʯΈ͕ඞཁʹ
w ʮλΠϜΞτϋϯυϦϯά͞ΕΔΑ͏ʹQSPNJTFΛϥοϓ͢Δʯ ԣஅతؔ৺ࣄͰ͋Γɺ͜ΕΛղܾ͢ΔͨΊͷͱͯ͠։ൃ
͜͜·Ͱͷ͓͞Β͍ *%-͕ܾ·Ε#''ͷ։ൃʹணखͰ͖Δ w5ISJGU*%-/PEFKTΫϥΠΞϯτͷੜ w։ൃ࣌༻ͷϞοΫσʔλࠩ͠ସ͑
ં֯ͳͷͰ͏গ͠ศརʹ
8FC#''ͷ͓͠͝ͱʢ࠶ʣ "1*"HHSFHBUJPO /PEFKTLPB 4FSWFS4JEF3FOEFSJOH 3FBDU 3FEVY
#''Ͱ%FW͚ͷ6*࡞ΕΔ ϑϩϯτ։ൃ߹Ͱ "1*࡞ΕΔ 3FBDU 443 Ͱ 6*ఏڙͰ͖Δ
ͬͯΈΑ͏
None
%FNPOTUSBUJPO
˞ը૾ɾσʔλٕज़આ໌Λతͱͨ͠αϯϓϧͰ͢ w ྫɿͷจ֬ೝը໘ w ϞοΫΛར༻͍ͯ͠ͳ͍ঢ়ଶ w εςʔδϯάͷόοΫΤϯυαʔ Ϗε͕ར༻͞ΕΔ w ΩϟϓνϟจՄೳঢ়ଶͷਤ
࣌ؒଳʹΑͬͯՄ൱͕ҟͳΔ
˞ը૾ɾσʔλٕज़આ໌Λతͱͨ͠αϯϓϧͰ͢ w ։ൃऀϩʔΧϧςετڥͰɺ σόοά༻ͷϑολʔ͕ଘࡏͯ͠ ͍Δ
˞ը૾ɾσʔλٕज़આ໌Λతͱͨ͠αϯϓϧͰ͢ w σόοά༻ϑολʔͷϦϯΫ͔Β ɺϞοΫͷڍಈΛίϯτϩʔϧ ͢ΔͨΊͷ։ൃઐ༻ը໘ભҠ w ༗ޮʹ͍ͨ͠ϞοΫΛબ͢Δ w ͦͷϒϥβͰͷΈɺબͨ͠Ϟο Ϋ͕ద༻͞ΕΔΑ͏ʹͳΔ
˞ը૾ɾσʔλٕज़આ໌Λతͱͨ͠αϯϓϧͰ͢ w ΞϓϦέʔγϣϯͷը໘ʹͲΓ Ϧϩʔυ͢Δͱʜ w ϞοΫ͕༗ޮԽ͞ΕɺจෆՄೳ ঢ়ଶͱಉ༷ͷσʔλΛ#''͕ड͚ औͬͨঢ়ଶʹͳ͍ͬͯΔ
˞ը૾ɾσʔλٕज़આ໌Λతͱͨ͠αϯϓϧͰ͢ w ద༻͞ΕͨϞοΫσʔλ:".- ܗࣜͰදࣔ͞Εɺը໘͔Β֬ೝ ͕Ͱ͖Δ w ΞυϗοΫʹϞοΫͷσʔλΛฤ ू͢Δ͜ͱՄೳ
˞ը૾ɾσʔλٕज़આ໌Λతͱͨ͠αϯϓϧͰ͢ w ϞοΫͷσʔλΛ্ॻ͖ͨ͠ޙʹ ࠶ը໘ΛಡΈࠐΉͱʜ w ্ॻ͖ฤूͨ͠༰͕ө͞ΕΔ
6*GPSEFWͷԸܙ ඇϑϩϯτΤϯδχΞʢFH2"୲ʣɺ࠶ݱқ ͷߴ͍ը໘ঢ়ଶΛ༰қʹ֬ೝͰ͖ΔΑ͏ʹͳͬͨ
ͦͷଞ%9্ͷ
4DB⒎PMEJOH w 3FBDUDPNQPOFOU4UPSZCPPLܗͷੜεΫϦϓτ w 3FEVYؔ࿈ʢBDUJPO SFEVDFS NJEEMFXBSFʣܗͷੜεΫϦϓτ
None
7JTVBMSFHSFTTJPOUFTUJOH w 4$.QVTI࣌ʹ$*Ͱ4UPSZCPPLͷΩϟϓνϟΛऔಘ w લճΩϟϓνϟը૾܊ͱࠓճΩϟϓνϟը૾܊Λൺֱ w ൺֱ݁ՌͷϨϙʔτΛ.FSHF3FRVFTUͷίϝϯτ
None
ಠࣗͷ&4-JOUϧʔϧ w ίʔυϨϏϡʔͰΑ͋͘Γ͕ͪͳࢦఠΛগͣͭ͠ϧʔϧԽ w ʮYYYͷ$PNQPOFOUੜͰΘͣʹZZZͱ͍͏ϥούʔΛ͓͏ʯ w ʮ͜ͷσΟϨΫτϦʓʓͷॲཧ͕ϝΠϯ͔ͩΒɺ[[[ΛJNQPSU͢ ΔΑ͏ͳॲཧॻ͔ͳ͍Ͱʯ w ଞͷϑϩϯτΤϯδχΞͰ&4-JOUϧʔϧΛ։ൃͰ͖ΔΑ͏ʹϋϯζ
ΦϯΛ࣮ࢪ
ଓ͖8FCͰ w 4UPSZCPPLपΓͷɿ IUUQTTQFBLFSEFDLDPNRVSBNZMJEFEVPJTJJTUPSZCPPL w 7JTVBMSFHSFTTJPOUFTUͷɿ IUUQTNFEJVNDPN!2VSBNZGPMJPͷը૾ճؼςετͷཪଆ DCD w &4-JOUͷϋϯζΦϯɿ
IUUQTHJUIVCDPN2VSBNZFTMJOUQMVHJOUVUPSJBMCMPCNBTUFS HVJEF3&"%.&KBNE
ࠓޙͷల
#''443ͷGFBUVSFUFTU w ࠓ͍࣋ͬͯΔΈ w ҙͷϚΠΫϩαʔϏεͷϞοΫࠩ͠ସ͑ JOUFSDFQUPS w 3FBDU$PNQPOFOUΛඳը݁Ռͷ7JTVBMUFTUJOH w
྆ํ͑ʮϚΠΫϩαʔϏεͷϦΫΤετऔಘʙ443$43Ͱͷ ϒϥβඳըʯΛҰؾ௨؏ͰςετͰ͖Δͣ
·ͱΊ
ࠓͨ͜͠ͱ w '0-*0ʹ͓͚Δ8FC#''ͷ֓ཁ w ͪΐͬͱָͯ͠#''Λ։ൃ͢ΔͨΊͷۤ࿑ w *%-ϕʔεͰͷ։ൃ w ΠϯλʔηϓλʹΑΔΫϥΠΞϯτͷࠩ͠ସ͑ w
FUD
͍͑ͨ͜ͱ ࡢࠓͷϑϩϯτΤϯυ༷ʑͳٕज़ཁૉͷͨΊʹɺ ։ൃ͕ෳࡶʹͳΓ͕ͪ ʮෆศʯͱײͨ͡Βগͣͭ͠ΤϯδχΞϦϯάͰղܾ ͢ΕΑ͍ ։ൃελοΫΛඥղ͚͖ͬͱԿ͔ݟ͔ͭΔͣʂ
Α͍ϑϩϯτΤϯυ։ൃΛ
5IBOLZPV