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
ReactNative + microCMS の設計にすごく悩んだ話
Search
hiroya iizuka
March 04, 2021
Technology
1.2k
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
ReactNative + microCMS の設計にすごく悩んだ話
hiroya iizuka
March 04, 2021
More Decks by hiroya iizuka
See All by hiroya iizuka
学問と資産
hiroyaiizuka
0
480
clean architecture と経営
hiroyaiizuka
0
1.5k
既存のRESTful な RailsプロジェクトにGraphQL導入を検討した話
hiroyaiizuka
0
5.1k
3つのNext.jsプロジェクトを 新卒エンジニアと一緒に 開発した話
hiroyaiizuka
1
470
実戦に役立つFirebase_Analytics_使用集
hiroyaiizuka
0
180
Other Decks in Technology
See All in Technology
“詰む”前に仕組みを作れ 〜技術の波に溺れないためのキャッチアップ術〜
takasyou
7
3.8k
Agile and AI Redmine Japan 2026
hiranabe
4
480
スタートアップにAmazon EKSは早すぎる? マルチプロダクト戦略を加速する Platform Engineeringの実践 / Is Amazon EKS Too Soon for Startups? Practical Platform Engineering to Accelerate a Multi-Product Strategy
elmodev09
1
1.8k
徹底討論!ECS vs EKS!
daitak
3
1.7k
SteampipeとExcel Power QueryでAWS構成定義書の作成を自動化する
jhashimoto
0
180
10年間のブログ発信を振り返って見えたWebアプリケーションエンジニアとしての軌跡
stefafafan
0
180
コミュニティの有益性 ~JAWS Days 2026 での体験を通して~ / The Benefits of a Community ~Through My Experience at JAWS Days 2026~
seike460
PRO
0
270
感情と身体を置き去りにしない、エンジニアの生きのこり方 ──いまから、ここから「自分の状態」を扱うという選択
saorimurooka
0
340
GitHub Copilot 最新アップデート – 「一歩先」の実践活用術
moulongzhang
5
1.7k
IaC コードを資産へ:AWS CDK 社内ライブラリと横断展開 / aws-summit-japan-2026
gotok365
10
1.6k
AIをフル活用してオンコール機能のプロトタイプを2日で作った話 / Building an AI-Powered On-Call Prototype in Just Two Days
nari_ex
0
130
FPGAの開発コンペでZephyrを使ってみた
iotengineer22
0
200
Featured
See All Featured
Odyssey Design
rkendrick25
PRO
2
700
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
370
Agile that works and the tools we love
rasmusluckow
331
22k
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
2k
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
0
210
世界の人気アプリ100個を分析して見えたペイウォール設計の心得
akihiro_kokubo
PRO
72
40k
A Modern Web Designer's Workflow
chriscoyier
698
190k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
3.5k
svc-hook: hooking system calls on ARM64 by binary rewriting
retrage
2
310
Leading Effective Engineering Teams in the AI Era
addyosmani
9
2.1k
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
1
240
Data-driven link building: lessons from a $708K investment (BrightonSEO talk)
szymonslowik
1
1.1k
Transcript
ReactNative + microCMS の設計にすごく悩んだ話 株式会社BeatFit CTO 飯塚 浩也
医師 循環器内科、総合診療医と して、⼤学 - 地⽅の病院を 8 年間勤務。 IT は⼤の苦⼿。 パソコン教室のアビバに
通っていた。 エンジニア 株式会社BeatFit にエンジニ アとして⼊社。 [ ⽇課] Codewars, LeetCode Hack The Box Type Challenge
今⽇のお話 Headless CMS の技術選定に⾄るまでの経緯 悩んだ設計の話 CMS との差分を埋める React Native ライブラリ
みんなの広場
None
弊社運営チームは CMS から投稿したい でも、CMS 周りを コーディング したくない 期限まで あと3 ヶ⽉しかない
そうだ microCMS でいこう
運⽤⾯ ・⽇本語が魅⼒的だった ・中の⼈が、twitter で だった ・料⾦プランが、優しかった 友達
いいね、返信 コメント、通知など 複雑な機能がある React Native での 事例の少なさ よくある HeadlessCMS の
Usecase と違う・・・
実際に悩んだ設計
設計 1. 責務を分離 通常の Feed コンテンツは、CMS ヘ 複雑なwrite 要件のデータは、RDS へ
Get request 時に、frontend 側で mapping するロジックが必要になる 😣
WebHook を使い、CMS 上 からの投稿や削除が可能。 運営が、不適切な投稿を、CMS でチェックできる。 設計 2. 全データを microCMS
で管理
データの⼆重管理になり、データ不整合が⼼配。 定期的に同期をする処理が必要になる。 Post request が多く、コストが⾼くなる。 設計 2.
twitter でぶつぶつ悩んでたら → microCMS 創業者 ( 柴⽥さん、松⽥さん) からDM
神対応、ありがとうございました・・・!😭
最終設計: こうなりました!
最終設計: Usecase での分離 運営の投稿 User の投稿
Appendix Usecase で分離することで、設計が simple になった Post request が少ない設計になり、費⽤⾯で優れた 運営側の投稿のカスタマイズを、細かくできる設計になった 運営側の投稿頻度は少なく、当⾯は
Webhook 通信の失敗は 許容できる設計になった
microCMS との差分を埋める ライブラリーのご紹介 react-native-rich-editor react-native-render-html
Rich Editor in microCMS "textContent": "<p><br></p><h2 id=\"hf99e890528\"> あああいいい</h2> <p><a ref=\"https://beatfit.jp\"target=\"_blank\"
rel=\"noopenernoreferrer\"> アイウエオ</a><br><br> </p>", ↓
react-native-rich-editor
HTML を取得 const richText = useRef<RichEditor | null>() const html
= richText.current?.getContentHtml() <RichEditor ref={r => (richText.current = r)} placeholder={' ⼊⼒してください'} onChange={handleChange} initialFocus /> 1 2 3 4 5 6 7 8 9 10
HTML を取得 const richText = useRef<RichEditor | null>() const html
= richText.current?.getContentHtml() <RichEditor ref={r => (richText.current = r)} placeholder={' ⼊⼒してください'} onChange={handleChange} initialFocus /> 1 2 3 4 5 6 7 8 9 10 const html = richText.current?.getContentHtml() const richText = useRef<RichEditor | null>() 1 2 3 4 <RichEditor 5 ref={r => (richText.current = r)} 6 placeholder={' ⼊⼒してください'} 7 onChange={handleChange} 8 initialFocus 9 /> 10
react-native-render-html import React, { Component } from "react"; import {
ScrollView, useWindowDimensions } from "react-native"; import HTML from "react-native-render-html"; const htmlContent = ` <h1>This HTML snippet is now rendered with native components !</h1> <h2>Enjoy a webview-free and blazing fast application</h2> <img src="https://i.imgur.com/dHLmxfO.jpg?2" /> <em style="textAlign: center;">Look at how happy this native cat is</em> `; export default function Demo() { const contentWidth = useWindowDimensions().width; return ( <ScrollView style={{ flex: 1 }}> <HTML source={{ html: htmlContent }} contentWidth={contentWidth} /> </ScrollView> ); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
react-native-render-html import React, { Component } from "react"; import {
ScrollView, useWindowDimensions } from "react-native"; import HTML from "react-native-render-html"; const htmlContent = ` <h1>This HTML snippet is now rendered with native components !</h1> <h2>Enjoy a webview-free and blazing fast application</h2> <img src="https://i.imgur.com/dHLmxfO.jpg?2" /> <em style="textAlign: center;">Look at how happy this native cat is</em> `; export default function Demo() { const contentWidth = useWindowDimensions().width; return ( <ScrollView style={{ flex: 1 }}> <HTML source={{ html: htmlContent }} contentWidth={contentWidth} /> </ScrollView> ); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 const htmlContent = ` <h1>This HTML snippet is now rendered with native components !</h1> <h2>Enjoy a webview-free and blazing fast application</h2> <img src="https://i.imgur.com/dHLmxfO.jpg?2" /> <em style="textAlign: center;">Look at how happy this native cat is</em> `; import React, { Component } from "react"; 1 import { ScrollView, useWindowDimensions } from "react-native"; 2 import HTML from "react-native-render-html"; 3 4 5 6 7 8 9 10 11 export default function Demo() { 12 const contentWidth = useWindowDimensions().width; 13 return ( 14 <ScrollView style={{ flex: 1 }}> 15 <HTML source={{ html: htmlContent }} contentWidth={contentWidth} /> 16 </ScrollView> 17 ); 18 } 19
react-native-render-html import React, { Component } from "react"; import {
ScrollView, useWindowDimensions } from "react-native"; import HTML from "react-native-render-html"; const htmlContent = ` <h1>This HTML snippet is now rendered with native components !</h1> <h2>Enjoy a webview-free and blazing fast application</h2> <img src="https://i.imgur.com/dHLmxfO.jpg?2" /> <em style="textAlign: center;">Look at how happy this native cat is</em> `; export default function Demo() { const contentWidth = useWindowDimensions().width; return ( <ScrollView style={{ flex: 1 }}> <HTML source={{ html: htmlContent }} contentWidth={contentWidth} /> </ScrollView> ); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 const htmlContent = ` <h1>This HTML snippet is now rendered with native components !</h1> <h2>Enjoy a webview-free and blazing fast application</h2> <img src="https://i.imgur.com/dHLmxfO.jpg?2" /> <em style="textAlign: center;">Look at how happy this native cat is</em> `; import React, { Component } from "react"; 1 import { ScrollView, useWindowDimensions } from "react-native"; 2 import HTML from "react-native-render-html"; 3 4 5 6 7 8 9 10 11 export default function Demo() { 12 const contentWidth = useWindowDimensions().width; 13 return ( 14 <ScrollView style={{ flex: 1 }}> 15 <HTML source={{ html: htmlContent }} contentWidth={contentWidth} /> 16 </ScrollView> 17 ); 18 } 19 <HTML source={{ html: htmlContent }} contentWidth={contentWidth} /> import React, { Component } from "react"; 1 import { ScrollView, useWindowDimensions } from "react-native"; 2 import HTML from "react-native-render-html"; 3 4 const htmlContent = ` 5 <h1>This HTML snippet is now rendered with native components !</h1> 6 <h2>Enjoy a webview-free and blazing fast application</h2> 7 <img src="https://i.imgur.com/dHLmxfO.jpg?2" /> 8 <em style="textAlign: center;">Look at how happy this native cat is</em> 9 `; 10 11 export default function Demo() { 12 const contentWidth = useWindowDimensions().width; 13 return ( 14 <ScrollView style={{ flex: 1 }}> 15 16 </ScrollView> 17 ); 18 } 19
まとめ 設計に悩んだときは、UseCase で分離すると単⼀責任に なり、設計が simple になる microCMS は、複雑な機能が必要な時も、有効な選択肢 となる react-native-render-html
と react-native-rich-editor で 差分を埋められる