フロントエンドの React Redux Rx などの設計パターンを元に GUI 設計について考えてみました
ࠓɺզʑɺ GUI ͷઃܭʹ͍ͭͯԿΛߟ͑Δ͖͔mizchi
View Slide
લఏw 41"(6*ઃܭͱେࠩͳ͍w ؔܕ'31ͱ͍͏ݴ༿ΛͰ͖Δ͚ͩΘͳ͍w ࢿྉ͖Ε͍ʹ࡞ΔͷΛ్தͰ͖ͨ
Event Stream Snapshot= State
4UBUF7JFX
4FSWFS4UBUF)5.-Oldschool Web App63-
4FSWFS$MJFOUHTMLAJAXAJAX1 AJAX2
4FSWFS4UBUF$MJFOU$POUSPMMFSClient Side MVC)5.-3FXSJUF
4FSWFS&WFOU&WFOU4USFBN'MVY7JFX4OBQTIPU6*&WFOU
4FSWFS&WFOU&WFOU4USFBN+ PWA7JFX4OBQTIPU6*&WFOU 8PSLFS&WFOU
Event Streamw ݱࡏͷΫϥΠΞϯτઃܭͷཧରw ଟछଟ༷ͳ&WFOU4USFBNΛΓग़͢ͱ4UBUF͕֬ఆw &WFOU4USFBN͔Β4OBQTIPUΛΓग़͢खஈ৭ʑ
Reducer• (prev: State, action: Action) => Statew ͨͩͷؔw ࠓͷঢ়ଶͱ"DUJPOΛҰͭͱͬͯ࣍ͷঢ়ଶΛ֬ఆ͢Δw "DUJPOΛେྔʹྲྀ͠ଓ͚Εঢ়ଶมԽ͢Δ
Redux•predictable state manager (ࣗশ)•combineReducers Ͱ ෳͷ reducer ΛଋͶͯ৽͍͠ reducerΛ࡞Δ•Action ͕དྷΔʹશͯͷ reducer ʹྲྀ͢•reducer ࣗʹڵຯ͕͋Δऀ͚ͩั·͑ͯߋ৽ॲཧΛ͢Δ
"DUJPO"DUJPO"DUJPO"DUJPOEventStream Reducer4UBUF "DUJPO4UBUF4UBUF "DUJPO4UBUF4UBUF "DUJPO4UBUF4UBUFSnapshot4UBUF4UBUF
"DUJPO"DUJPO"DUJPO"DUJPO3FEVDFS4UBUF "DUJPO4UBUF4UBUF "DUJPO4UBUF4UBUF "DUJPO4UBUF"DUJPO"DUJPO3FEVY.JEEMFXBSF4UBDLReduxmiddleware
Redux Middleware•͋Δ Event Stream Λผͷ EventStream ʹม͢Δ•Ұͭͷ Action ͕ෳͷ Action ʹม͞ΕͨΓɺMiddleware෦Ͱঢ়ଶΛ࣋ͬͨΓ͢Δ•େૉ௨Γ•͜͜Λཧղ͢Δͷʹ͕͔͔࣌ؒͬͨʢ໊લ͕ѱ͍ʣ
Rx ͱ Redux•EventStream(Observable) ΛΦϖϨʔλʔͰSnapshotʹมܗ͢Δ•EventStreamΛͦͷ··ѻ͏(Observable) ͔ɺ reducer ͱ͍͏ܗʹݶఆ͢Δ͔͕͓ͳҧ͍•Redux ͱ,ͭ·Γ Rx ͷݶఆܥ•reducer = observable.reduce((state, action) =>state)•Redux Middleware = Rx Operator
ରαʔόʔαΠυΞʔΩςΫνϟઓུ
ΫϥΠΞϯτઃܭ࣌ʹରαʔόʔαΠυͰߟ͑Δࣄw ௨৴ຊͰΫϥΠΞϯτͷΫϥΠΞϯτͷࡉ͔͍࠷దԽਧ͖ඈͿ NTdw ϦΫΤετগͳ͚Εগͳ͍΄Ͳྑ͍w )551ʹͳΕ·ͨมΘͬͯ͘Δ͕ʜ
αʔόʔΫϥΠΞϯτResponceRequestLegacy Style
αʔόʔΫϥΠΞϯτHTMLAJAXAJAX1 AJAX2
ΫϥΠΞϯτREST APIJUFNT VTFST%#
w 3&45"1*ͷநΫϥΠΞϯτͷϢʔεέʔεͷෳࡶԽw ϦΫΤετͷฒྻԽw ΫϥΠΞϯτϩδοΫͰϦϨʔγϣϯ͕໌ͯ͠/w %#ͷඇޮͳ͍߹Θͤw ઐ༻"1*͕ඞཁʁ
ΫϥΠΞϯτView API Pattern7JFX"1*%#6TFS*OGP
View API Patternw "1*&OEQPJOUͰϞσϧΛ߹͢Δw $POTVNFS%SJWFO$POUSBDUw ࣮ࡍʹ3&45ͱซ༻͞ΕΔ͜ͱ͕ଟ͍ͷͰw ϞόΠϧΞϓϦͰଟ͍
ΫϥΠΞϯτGraphQL(SBQI2-&OEQPJOU%#2VFSZ$PNQPTJUJPOGraphQL Query.PEFM3FTPMWFS'JMUFS2VFSZ
GraphQLw ΫϥΠΞϯτ͔ΒͷΫΤϦൃߦ ෳϦιʔεͷ߹w ΫΤϦΛղͯ͠ෳͷ3FTPMWFSͷϦΫΤετw ΫΤϦࣗʹΑͬͯඞཁͳύϥϝʔλΛࢦఆ͍ͯ͠ΔͷͰɺͦΕ͚ͩฦ٫ 'JMUFS2VFSZ
View API ͱ GraphQLw ߟ͑ͯΔ͜ͱಉ͡w ΫϥΠΞϯτͰൃੜ͢ΔϦΫΤετΛຊʹ·ͱΊ͍ͨw %#ͷϦΫΤεταʔόʔͰ߹͢Δw (SBQI2-σʔλΛߜΔػೳΛ࣋ͬͯΔ
#''ͷ#BDLFOE'PS'SPOUFOE
Real World : Multi Requests6TFS*OGP *UFNT)FBEFS $POUFOU4FSWFS
ૄͳίϯϙʔωϯτୡw ͓ޓ͍ૄͳಠཱੑͷߴ͍ίϯϙʔωϯτ͕ෳͷϦΫΤετΛൃߦw ϦΫΤετΛ·ͱΊΑ͏ʹɺΫϥΠΞϯτϩδοΫͱαʔόʔΛڧௐͤ͞Δ͜ͱ͕Ͱ͖ͳ͍
*BFF Architecture&OEQPJOU &OEQPJOU$PNQPOFOU $PNQPOFOU *TPNPSQIJD-BZFS$PNQPOFOU $PNQPOFOU3FOEFS*OJUJBM4UBUFSFR
#''ͷղܾ͢Δͷw ͦͦڠௐ͠ͳ͍͕ɺڠௐ͢ΔॴΛαʔόʔʹ͢Δw ॳճϦΫΤετ࣌ɺαʔόʔͰΫϥΠΞϯτϩδοΫΛൃߦ͠ɺඞཁͳϦΫΤετΛશ෦ऴ͔͑ͯΒॳظεςʔτΛฦ٫w ͦͷޙ$PNQPOFOUಠཱͯ͠Քಇ͢Δw ࣗવͱ443ʹͳΔ
#''ͷw ࣮࣭/PEFKTݶఆͷΞʔΩςΫνϟw ࣗવͱϚΠΫϩαʔϏεԽ͕ཁٻ͞ΕΔw ಉ͡σʔληϯλʔͰ͋Δ͜ͱཁٻ͞ΕΔw తʹରͯ͠खஈ͕աw ϑϨʔϜϫʔΫͱͯ͠ղܾͯ͠΄͍͠
BFF Framework• Next.js - React• Nuxt.js - Vue• angular-universal
7JFXͷઃܭͰߟ͑Δ͜ͱ
7JFXͷઃܭͰߟ͑Δ͜ͱw ઃܭޙʹ7JFXͷ࣮ͷ࣌ʹԿΛ͢Δ͔ߟ͑ͨΒෛ͚w نͰࣗಈతʹܾ·ΔΑ͏ʹ͢Δ͖
7JFXͷw 1SFTFOUBUJPOw &WFOUͷൃՐ UP&WFOU4USFBN
$PNQPOFOUw ଞͷ$PNQPOFOUϓϦϛςΟϒͳཁૉΛଋͶΔ୯Ґw ೖྗ͞ΕΔܕΛܾΊΔw ग़ྗ͠͏Δ&WFOUΛ$BMMCBDLͱඥ͚Δw Ҏ্
$PNQPOFOUͷׂࢦw ࠷ۙͬͯΑ͔ͬͨͷ"UPNJD%FTJHOͷ෦आ༻w ॴଐͰͳ͘ɺׂՄೳͳཻͷΈͰׂ͍ͯ͘͠w ΤϯδχΞ͔ΒݟΔͱཻϓϩάϥϚϒϧʹܾ·Δw σβΠφ͔ΒݟΔͱ"UPNJD%FTJHOͱ͍͏ࢦΛԉ༻Ͱ͖Δ
Atomic Designw "UPNTͦΕҎ্ׂͰ͖ͳ͍$PNQPOFOUw .PMFDVMFTෳͷ"UPNT͔ΒͳΔ$PNQPOFOUw 0SHBOJTNTෳͷ.PMFDVMFT"UPN͔ΒͳΔ$PNQPOFOU
$PNQPOFOUͷ4OBQTIPUׂw $PNQPOFOUͷϧʔτཁૉ͕ɺͲͷ4UBUF 4OBQTIPUΛ"TTJHO͞ΕΔ͔w ੲͳ͕Βͷݴ༿Ͱݴ͑$POUSPMMFSw 3FEVYͳΒDPOOFDU࠷ۙͩͱTFMFDUPS w ͜͜ͷཻ͚ͩߟ͑ͳ͠ʹॻ͚ͳ͍ͷͰɺͪΌΜͱߟ͑Δ
4FMFDUPSw SFBDUKTSFTFMFDUw ؆୯ʹݴ͑3FBDUͷNBQ4UBUF5P1SPQT ͷෳࡶͰ࠷దԽ͞Εͨͭw 4OBQTIPU͔Βϧʔτͷ$PNQPOFOUׂΓͯΔॲཧ
4OBQTIPU0SHBOJTN0SHBOJTN.PMFDVMF"UPN"UPN"UPN"UPN.PMFDVMF4FMFDUPS͕࣌ؒͳ͔ͬͨ
ϑϩϯτΤϯυΤϯδχΞͷߟ͑Δࣄ
࣍ͷੈͷٕज़w &WFOU4USFBNܕ͋Γ͖ͷઃܭw 'VODUJPOBM1SPHSBNNJOH8BZw *TPNPSQIJDPO8FC"TTFNCMZ
࣍ͷੈ͍ͭw *&͕ࢮΜͩΒdw ͕͢͞ʹʹʜw ϞόΠϧγΣΞͷ૿େͰ૬ରతʹࢮʹͦ͏ʢࢮͶͦ͏ʣ
ϑϩϯτΤϯυ͜ͷઌੜ͖ͷ͜Δͷ͔w ϞόΠϧͷོʹରԠͯ͠3FBDU/BUJWF͕ಀ͛ޱͰ͋Δ͕ʜw ϞόΠϧ͍͔ͭࢮ͵w +4ͨͿΜࢮͳͳ͍ ࢮͶͳ͍w ઃܭٕ๏ͨͿΜࢮͳͳ͍
ΤϯδχΞͱͯ͠ੜ͖Γ·͠ΐ͏
͓ΘΓ