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
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
2.1k
フロントエンドテストの育て方
quramy
12
3.9k
App Router 悲喜交々
quramy
8
750
上手に付き合うコンポーネントテスト
quramy
6
2.4k
Patched fetch did not work
quramy
6
800
GraphQL あるいは React における自律的なデータ取得について
quramy
18
5.9k
Next.js App Router
quramy
15
3.9k
Fragment Composition of GraphQL
quramy
17
4.9k
reg-viz VRT tools
quramy
4
1.7k
Other Decks in Programming
See All in Programming
freeeにおけるEvalsの実践例の紹介
freee
PRO
0
120
そこに3びきプロダクトがいるじゃろう——生成AI時代における“価値が届かない理由”の構造
kosuket
0
520
Terraform標準の組織で AWS CDKをどう使うか
mu7889yoon
1
530
S3 を使うアプリケーションをローカル完結で動かすことに全力を注いでみた / Running S3 Apps Offline
contour_gara
0
530
リアルな遅延を測る仕様
kota_yata
1
120
KotlinConf Extended South Korea 2026 Keynote
l2hyunwoo
0
110
Foundation Models frameworkで画像分析
ryodeveloper
1
620
AI時代に設計が 最大の生産性レバーになる 意図駆動開発とデータを消さない設計|Don't Delete Your Data or Your Intent — Design as the Deepest Lever in the AI Era
tomohisa
1
1k
使いながら育てる Claude Code — 開発フローの1コマンド化 × 繰り返し指摘の自動仕組み化
shiki_kakaku
0
1.9k
komatsuna「分散システムにおけるバグ分析手法」
komatsunaqa
0
270
ソフトウェア設計に溶けるインフラ ― AWS CDK のインフラ認識論
konokenj
3
810
引き算の組織 ― アウトカムとAIに全振りするために辞めたこと ― / Organization by Subtraction
hirokiyamamoto14
PRO
0
250
Featured
See All Featured
Rebuilding a faster, lazier Slack
samanthasiow
85
9.6k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.3k
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
1
250
Building a A Zero-Code AI SEO Workflow
portentint
PRO
0
670
The World Runs on Bad Software
bkeepers
PRO
72
12k
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
390
The Power of CSS Pseudo Elements
geoffreycrofte
82
6.5k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
56k
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
420
Technical Leadership for Architectural Decision Making
baasie
3
500
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
410
Utilizing Notion as your number one productivity tool
mfonobong
4
550
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