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
フルスタックエンジニアとしてゼロからサービスを作る時に考えていること
Search
tanaka-yui
September 13, 2020
Programming
3
1.1k
フルスタックエンジニアとしてゼロからサービスを作る時に考えていること
・開発の各ポイントでどういう思想で設計・構築したか
・フルスタックエンジニアの視点でみたときの発想
などの話
tanaka-yui
September 13, 2020
Tweet
Share
More Decks by tanaka-yui
See All by tanaka-yui
パラレルワーカーという働き方
tanakayui
1
1k
Nuxt.jsのベストプラクティスを考えてみる.pdf
tanakayui
6
6.3k
Other Decks in Programming
See All in Programming
見えないメモリを観測する: PHP 8.4 `pg_result_memory_size()` とSQL結果のメモリ管理
kentaroutakeda
0
410
快速入門可觀測性
blueswen
0
380
17年周年のWebアプリケーションにTanStack Queryを導入する / Implementing TanStack Query in a 17th Anniversary Web Application
saitolume
0
250
testcontainers のススメ
sgash708
1
120
暇に任せてProxmoxコンソール 作ってみました
karugamo
2
720
Jakarta EE meets AI
ivargrimstad
0
260
テスト自動化失敗から再挑戦しチームにオーナーシップを委譲した話/STAC2024 macho
ma_cho29
1
1.3k
テストコード書いてみませんか?
onopon
2
140
PHPで作るWebSocketサーバー ~リアクティブなアプリケーションを知るために~ / WebSocket Server in PHP - To know reactive applications
seike460
PRO
2
520
テストコードのガイドライン 〜作成から運用まで〜
riku929hr
5
740
Zoneless Testing
rainerhahnekamp
0
120
rails statsで大解剖 🔍 “B/43流” のRailsの育て方を歴史とともに振り返ります
shoheimitani
2
940
Featured
See All Featured
Stop Working from a Prison Cell
hatefulcrawdad
267
20k
GraphQLとの向き合い方2022年版
quramy
44
13k
Music & Morning Musume
bryan
46
6.2k
How To Stay Up To Date on Web Technology
chriscoyier
789
250k
A Philosophy of Restraint
colly
203
16k
Become a Pro
speakerdeck
PRO
26
5k
The Pragmatic Product Professional
lauravandoore
32
6.3k
Designing for Performance
lara
604
68k
KATA
mclloyd
29
14k
Navigating Team Friction
lara
183
15k
VelocityConf: Rendering Performance Case Studies
addyosmani
326
24k
Git: the NoSQL Database
bkeepers
PRO
427
64k
Transcript
フルスタックエンジニアとしてゼロ からサービスを作る時に 考えていること 田中 友彩
田中 友彩(たなか ゆい) •所属 AI事業本部 CyberPOP •職種 フルスタックエンジニア 商談からはじめ、インフラ、サーバーサイド、 Webフロント、Android、iOSまで一気通貫です •最近よく使う技術 Nuxt.js, Typescript,
Golang, Kotlin, AWS, GCP, Terraform, Datadog ML系など @yuit1552
はじめに 最近一人で構築したサービスを例に、 •開発の各ポイントでどういう思想で設計・構築したか •フルスタックエンジニアの視点でみたときの発想 などのお話をしようと思います。
1.ソーシャルアプリをゼロから構築したときの話 2.ニュース配信サイトをゼロから構築したときの話
ソーシャルアプリを ゼロから構築したときの話
要件の内容を整理 要件定義 基本設計 詳細設計 PG ソーシャルアプリとして考えると •会員の登録、プロフィール閲覧などができる •文章、つぶやき、画像などの投稿ができる •他の会員の内容、投稿などを検索できる •他の人と交流できるような仕掛けがある
(いいね、フォロー、返信、DMなど)
要件の内容を整理 もう少し細かいこと考えると、例えば •ハッシュタグ、レコメンドなど検索する仕掛けをどうするか •いいねなどのリアクションに対するリアルタイム性をどうするか •DMにはグループDMなど、付加機能をどこまで持たせるか •既存システムがある場合アカウントを共通化するか などなど 要件定義 基本設計 詳細設計
PG
要件定義で特に意識していること •企画者の要望をどうやったら叶えられるか案を提案する •実現可否をはっきり伝える •やりたいことに対しての落とし所を見つける 要件定義 基本設計 詳細設計 PG
要件定義で特に意識していること •企画者の要望をどうやったら叶えられるか案を提案する •実現可否をはっきり伝える •やりたいことに対しての落とし所を見つける 要件の認識のズレやモレを できる限り少なくすること 要件定義 基本設計 詳細設計 PG
落とし所のポイント リリースしたい時期はいつか? 予算は? 大体この観点で落とし所話します。 要件定義 基本設計 詳細設計 PG
リリース時期について •一刻も早く出したい、という場合 要件定義 基本設計 詳細設計 PG
リリース時期について •一刻も早く出したい、という場合 →理由 例えば、競合他社がいて、他社より 早めに出して先攻有利性を取りたい 要件定義 基本設計 詳細設計 PG
リリース時期について •なるべく早くしたいが、◦◦の機能はどうしても欲しい 要件定義 基本設計 詳細設計 PG
リリース時期について •なるべく早くしたいが、◦◦の機能はどうしても欲しい →理由 例えば、後発サービスなので、ある程度遅くてもい いが、画期的な◦◦な機能が欲しいから、機能を優 先させたい 要件定義 基本設計 詳細設計 PG
この案件の落とし所 ソーシャルとしては後発サービスだが、 ・狙っているターゲット層が他サービスと異なる ・メインで考えている◦◦の機能は他にない などから、結果的に競合にならないと判断でき、 ある程度機能を優先することに。 要件定義 基本設計 詳細設計 PG
もちろん最初から全部入れるのは辛いので優先度をきめ、 必須にしたものは この案件の落とし所 要件定義 基本設計 詳細設計 PG
もちろん最初から全部入れるのは辛いので優先度をきめ、 必須にしたものは この案件の落とし所 既存システムとのアカウント共通化 要件定義 基本設計 詳細設計 PG
新しいサービスを作った時一番最初の時点で、 その後の運営側のサービス展開を考えてプラットフォーム構 想を想定して作るケースって業界的に結構少ないと思いませ んか? 既存システムとのアカウント共通化 要件定義 基本設計 詳細設計 PG
システムごとにユーザー管理機能を作ってることが多いの で、共通プラットフォーム化する場合の アカウントを統合する時、大変だった人が少なからずいると思 います^^; 既存システムとのアカウント共通化 要件定義 基本設計 詳細設計 PG
•運営してるサービスはRailsで出来た画面とビジネスロジックが結構絡 み合ったモノリスなサービス •認証機能もRails用の認証ライブラリ「Sorcery」に完全に依存して全部 くっついていた •だいぶ大きなモノリスになってたので認証APIをRailsに用意しても高負 荷に耐えられそうにないし、メインサービスに影響がでる 既存システムの状態 要件定義 基本設計 詳細設計
PG
完全に新規で作ってしまうのと既存ユーザーにアカウントの移行作業を してもらう必要がありますよね(時々そういうサービスあるかと思います) そうすると、そこでサービスを離脱してしまうユーザーがいると思うので、 既存サービスのアカウントと互換させつつ新認証基盤を作ったほうがい いと思い、 企画者に提案したところ、OKをもらえたので 新認証基盤の検討 要件定義 基本設計 詳細設計
PG
これ以上絡み合う前に新認証基盤を マイクロサービスで作っちゃおう!
互換性を保つ場合の一番のポイントとして考えたのは 認証基盤を作る上で 要件定義 基本設計 詳細設計 PG
互換性を保つ場合の一番のポイントとして考えたのは 認証基盤を作る上で パスワードの暗号化(ハッシュ化)アルゴリズムが同 じであること 要件定義 基本設計 詳細設計 PG
パスワードを保存する方法の王道パターンとしては、非可逆系のハッ シュ化(MD5,SH256, BCryptなどなど)を使うことと、それと組み合わせる、 ストレッチ、ペッパー、ソルトなどの手法かと思います。 認証基盤を作る上で 要件定義 基本設計 詳細設計 PG
パスワードさえどうにかなれば、あとは辻褄を合われば良いと 思ったので、既存システムと互換性を保てるかどうかを判断するため、 この要件定義の時点で、実現性の検証の工数を数日もらいました。 認証基盤を作る上で 要件定義 基本設計 詳細設計 PG
「Sorcery」のソースコードを調べて、 そのシステムでどう使ってるかを分析した結果、状態がわかり 利用しているアルゴリズムも大丈夫そうだったので 検証にて 要件定義 基本設計 詳細設計 PG
「Sorcery」のソースコードを調べて、 そのシステムでどう使ってるかを分析した結果、状態がわかり 利用しているアルゴリズムも大丈夫そうだったので 検証にて Golangでその処理を再現しました 要件定義 基本設計 詳細設計 PG
既存の「Sorcery」で作ったアカウントが Golangの検証APIでログインできることまで確認できたので、そのまま突 き進むこととなりました。 検証の結果 要件定義 基本設計 詳細設計 PG
次に基本設計
要件定義で作る機能の方向性をあらかた決めたので、 基本設計で決めたことは、ざっくりいうと •画面の下書き(ワイヤーフレーム)を作ってもらう •デザイナーさんに、デザインコンセプトとか作ってもらう •必要なデータを考える 基本設計の方向性 要件定義 基本設計 詳細設計 PG
基本設計の方向性 まず、画面のワイヤーとデザインについて話しましたが、 企画者とデザイナーさんと話す時に最初に伝えたことは 要件定義 基本設計 詳細設計 PG
•スマホアプリとWebで同じデザインでも再現難易度が違うので、どちら でもブレにくいマテリアルデザインを基本としてデザインを作って欲しい 基本設計の方向性 要件定義 基本設計 詳細設計 PG
•スマホアプリとWebで同じデザインでも再現難易度が違うので、どちら でもブレにくいマテリアルデザインを基本としてデザインを作って欲しい •全画面作ると時間かかると思うので、テーマカラーや数ページ基本と なるコンポーネントを含む画面をデザインしてもらい、他の画面はある 程度私にお任せして欲しい。 基本設計の方向性 要件定義 基本設計 詳細設計 PG
基本設計の方向性 デザインと画面仕様がカッチリきまってしまうと、、、 例えば、一覧系画面はどうしてもページングがいい と言われると、 要件定義 基本設計 詳細設計 PG
基本設計の方向性 検索結果をサマリーしにくいNoSQLとか 使いづらくなったりとか(ロジックで頑張れば、、、) デザインと画面仕様がカッチリきまってしまうと、、、 例えば、一覧系画面はどうしてもページングがいい と言われると、 要件定義 基本設計 詳細設計 PG
基本設計の方向性 逆にデータ設計をガチガチに固めてしまうと、、、 例えば、RDBだとGroup byで検索結果の countが取れるからsummaryはしやすいので、 ページングは作りやすい 要件定義 基本設計 詳細設計 PG
基本設計の方向性 DynamoDBのようなNoSQLだと全体のカウントととりづらいの で、ページングしづらい。(Scan使うとフルスキャンになるし)な ので「もっと見る」的なUIに制限してもらうことがある。 要件定義 基本設計 詳細設計 PG
そういったところふまえ、 画面の落とし所を決めました
データ設計について ソーシャルアプリなので、 •プロフィールなどユーザー関連のデータ •投稿に関するデータ •フォローやいいねなど、ユーザーの出会いのきっかけを作る系のデー タ •ハッシュタグなど検索しやすくするためのデータ 等々 要件定義 基本設計 詳細設計
PG
データ設計について 必要なデータはいろいろあると思いますし、データの リレーションや依存性など考えることはいろいろ ありますが、ここで気にしたポイントとしては、 要件定義 基本設計 詳細設計 PG
データ設計について 必要なデータはいろいろあると思いますし、データの リレーションや依存性など考えることはいろいろ ありますが、ここで気にしたポイントとしては、 扱うデータの性質を考える 要件定義 基本設計 詳細設計 PG
データ設計について 簡単にいうと、そのデータは 要件定義 基本設計 詳細設計 PG
データ設計について 簡単にいうと、そのデータは •読み込みが多いか 要件定義 基本設計 詳細設計 PG
データ設計について 簡単にいうと、そのデータは •読み込みが多いか •書き込みが多いか 要件定義 基本設計 詳細設計 PG
データ設計について サーバーサイド、インフラ視点でそこを気にする ポイントの大体は 要件定義 基本設計 詳細設計 PG
データ設計について サーバーサイド、インフラ視点でそこを気にする ポイントの大体は 大量のアクセス、データをどう早くさばくか? 要件定義 基本設計 詳細設計 PG
データ設計について 読み込みが多いデータをさばく手段として、例えば 要件定義 基本設計 詳細設計 PG
データ設計について 読み込みが多いデータをさばく手段として、例えば •RDBを使っている場合、Master、Slave構成にする 要件定義 基本設計 詳細設計 PG
データ設計について 読み込みが多いデータをさばく手段として、例えば •RDBを使っている場合、Master、Slave構成にする •CDNを使ってAPIやページごとキャッシュする 要件定義 基本設計 詳細設計 PG
データ設計について 読み込みが多いデータをさばく手段として、例えば •RDBを使っている場合、Master、Slave構成にする •CDNを使ってAPIやページごとキャッシュする •RedisやMemcachedなどインメモリでキャッシュする 要件定義 基本設計 詳細設計 PG
データ設計について 読み込みが多いデータをさばく手段として、例えば •RDBを使っている場合、Master、Slave構成にする •CDNを使ってAPIやページごとキャッシュする •RedisやMemcachedなどインメモリでキャッシュする などなど、キャッシュを頼ることが多いかと思います 要件定義 基本設計 詳細設計 PG
データ設計について 書き込みが多いデータをさばく手段として、例えば 要件定義 基本設計 詳細設計 PG
データ設計について 書き込みが多いデータをさばく手段として、例えば •書き込み基本性能の高いNoSQL系に保存する 要件定義 基本設計 詳細設計 PG
データ設計について 書き込みが多いデータをさばく手段として、例えば •書き込み基本性能の高いNoSQL系に保存する •書き込む値が複数ある場合並列化するなどロジックで頑張 る 要件定義 基本設計 詳細設計 PG
データ設計について 書き込みが多いデータをさばく手段として、例えば •書き込み基本性能の高いNoSQL系に保存する •書き込む値が複数ある場合並列化するなどロジックで頑張 る •即時性を求めない場合は、Queueなどに入れて逐次処理 要件定義 基本設計 詳細設計 PG
データ設計について 書き込みが多いデータをさばく手段として、例えば •書き込み基本性能の高いNoSQL系に保存する •書き込む値が複数ある場合並列化するなどロジックで頑張 る •即時性を求めない場合は、Queueなどに入れて逐次処理 •インメモリに一時的に書き込みあとで永続化 などなど 要件定義 基本設計 詳細設計
PG
データ設計について 基本設計の時点でそこまで考えるのか? というのもありますが、なぜかというと、例えば 要件定義 基本設計 詳細設計 PG
データ設計について 基本設計の時点でそこまで考えるのか? というのもありますが、なぜかというと、例えば 「DynamoDBは料金も安いし、オートスケールしてくれるしパ フォーマンスも良いから使おう」 要件定義 基本設計 詳細設計 PG
データ設計について 基本設計の時点でそこまで考えるのか? というのもありますが、なぜかというと、例えば 「DynamoDBは料金も安いし、オートスケールしてくれるしパ フォーマンスも良いから使おう」 と思って採用したとします 要件定義 基本設計 詳細設計 PG
データ設計について DynamoDBは仕組み上、検索パフォーマンスを出すために Queryを使う場合、複合条件が2つまでかつ、それを5パター ンしか作れないという制限があったりします。 要件定義 基本設計 詳細設計 PG
データ設計について ECサイトなど絞り込み条件が多いサイトだと、複合条件が、い くら以上で、カテゴリがこれで、メーカーはこれで、色は、、、み たいな複雑な条件がありますが、DynamoDBでは検索機能を 充実させることが結構つらかったりします。 要件定義 基本設計 詳細設計 PG
データ設計について 検索条件などを充実させたい場合は、RDBが有効だったりす るので、そうするとRDBとNoSQLだとデータの関連性の考え方 が違うので、データ設計に影響してきます。 (NoSQLは結構、非正規化しないと扱えなかったり) 要件定義 基本設計 詳細設計 PG
データ設計について なので、この時点で、 •扱うデータの性質を見極め採用するものを決める •対策が必要になった時の回避策が使えるか考えておく 要件定義 基本設計 詳細設計 PG
データ設計について このソーシャルアプリで扱うデータは基本ユーザー自身が中 心なので、比較的単純なデータが多く、NoSQLでもRDBでもど ちらでも問題なかったので、料金が安くと基本パフォーマンス が高いDynamoDBを採用しました。 要件定義 基本設計 詳細設計 PG
データ設計について 他、性能が良く複雑なクエリを扱えるものだとクラウドでいえ ば、 •Amazon Aurora •Amazon DocumentDB •Cloud Spanner とかあると思いますが、
要件定義 基本設計 詳細設計 PG
データ設計について 料金が結構するので予算のあるサービスであればいいです が、スタートアップ系だと予算が限りなく少ないので、初回は 選択肢にならないことが多いかと思います 要件定義 基本設計 詳細設計 PG
基本設計しめ このサービスも予算が少ないのでDynamoDBを採用しました が、読み込みが多いデータにはキャッシュを駆使したり、ロ ジックでカバーしたりと料金を抑えつつ、工夫して構築する方 向性にしました。 要件定義 基本設計 詳細設計 PG
次に詳細設計・PG
採用したもの インフラ 全てAWS。Terraformでコード化 • ECS Fargate • DynamoDB • RDS
(MySQL) • AppSync • CloudFront • Elasticache(Redis) • Lambda • Pinpoint • Amplify • Cognito • Code Pipeline • Route53 など Androidアプリ Android Architecture Components を基本としたMVVM • ViewModel • LiveData • Room • coroutine-flow • retrofit2 • okhttp3 • groupie • threetenabp • glide • koin など サーバーサイド Golangでマイクロサービス • go-chi • grpc • gorm • cobra • zap • robfig/cron など Webフロント Nuxt.jsでBFF入れつつvuetify • Nuxt.js • TypeScript • tsconfig-paths • Vuetify • grpc_tools_node_protoc_ts • prettier • express など 要件定義 基本設計 詳細設計 PG
インフラの概要 ECS Fargate ・・・ コンテナオーケストレーション DynamoDB ・・・ NoSQL のDB RDS(MySQL)・・・RDB
CloudFront ・・・CDN ElastiCache ・・・インメモリキャッシュ Lambda ・・・みんなよく使うと思うサーバーレス Amplify ・・・スマホアプリなどを作るのに最適なAWSのいくつかのサービスをまとめ+それを使いやすくしたツールのセット AppSync ・・・GraphQLの マネージド(Amplifyの一貫にもなってる) Pinpoint ・・・Push通知(Amplifyの一貫にもなってる) Cognito ・・・認証基盤(Amplifyの一貫にもなってる) Route53 ・・・DNSサーバーとかドメイン管理。 要件定義 基本設計 詳細設計 PG
インフラの概要 ECS Fargate を採用した理由 • インスタンスそのものを管理しなくていい → OSの脆弱性パッチ当てとかしなくていい • AWSの他サービスと親和性高い→EC2とか使ってても乗り換えが比較的容易
• ECS Fargateのversion up の頻度はかなりゆっくりなのでversionの追従が楽 要件定義 基本設計 詳細設計 PG
インフラの概要 ECS Fargate を採用した理由 • インスタンスそのものを管理しなくていい → OSの脆弱性パッチ当てとかしなくていい • AWSの他サービスと親和性高い→EC2とか使ってても乗り換えが比較的容易
• ECS Fargateのversion up の頻度はかなりゆっくりなのでversionの追従が楽 一人でやったのでとりあえずお手軽なのが嬉しい( ^ω^ ) 要件定義 基本設計 詳細設計 PG
インフラの概要 他考えたサービス 大人気「kubernetes」、のマネージドEKS 別案件でGoogleのGKEを使っていたが、確かにPodのスケールがECSより早くスパイクに強かったり(設定次 第ではありますが)して非常に優秀だと思いますが、 要件定義 基本設計 詳細設計 PG
インフラの概要 他考えたサービス 大人気「kubernetes」、のマネージドEKS 別案件でGoogleのGKEを使っていたが、確かにPodのスケールがECSより早くスパイクに強かったり(設定次 第ではありますが)して非常に優秀だと思いますが、 • 頻繁にあるkubernetes本体のバージョンアップにノードを追従していくのが面倒 (特に一人でやってるとかなり面倒) 要件定義 基本設計
詳細設計 PG
インフラの概要 他考えたサービス 大人気「kubernetes」、のマネージドEKS 別案件でGoogleのGKEを使っていたが、確かにPodのスケールがECSより早くスパイクに強かったり(設定次 第ではありますが)して非常に優秀だと思いますが、 • 頻繁にあるkubernetes本体のバージョンアップにノードを追従していくのが面倒 (特に一人でやってるとかなり面倒) • デプロイの仕組みを独自につくる必要が結構ある
(CI/CDはECSでも使うとしても、マニフェストファイル変更した時の扱いとかとか、、、) 要件定義 基本設計 詳細設計 PG
インフラの概要 他考えたサービス 大人気「kubernetes」、のマネージドEKS EKSもFargateが登場してからノードの管理が不要になりましたが、それでも頻繁に上がるversionへの追従 が大変なのと初回はやはり仕組み考えるのに時間かかるので、いくら高機能でも 要件定義 基本設計 詳細設計 PG
インフラの概要 他考えたサービス 大人気「kubernetes」、のマネージドEKS EKSもFargateが登場してからノードの管理が不要になりましたが、それでも頻繁に上がるversionへの追従 が大変なのと初回はやはり仕組み考えるのに時間かかるので、いくら高機能でも プロダクトの規模からすればオーバースペックだった (一人でkubeメンテつらい他もあるし、、、) 要件定義 基本設計 詳細設計
PG
インフラの概要 ということで、ECS Fargateを採用しました。 また、そのあとのデプロイなども楽にするため、こんな感じのお手軽パイプライン組みました。 GitHub Action上で ・docker build ・ECR へ
docker push 要件定義 基本設計 詳細設計 PG
インフラの概要 ということで、ECS Fargateを採用しました。 また、そのあとのデプロイなども楽にするため、こんな感じのお手軽パイプライン組みました。 GitHub Action上で ・docker build ・ECR へ
docker push Cloud Watch Eventで ECRを監視し、pushされたら CodePipeLine実行 要件定義 基本設計 詳細設計 PG
インフラの概要 ということで、ECS Fargateを採用しました。 また、そのあとのデプロイなども楽にするため、こんな感じのお手軽パイプライン組みました。 GitHub Action上で ・docker build ・ECR へ
docker push Cloud Watch Eventで ECRを監視し、pushされたら CodePipeLine実行 buildステージは飛ばすように し、ECRからdockerイメージ を取得しdeploy 要件定義 基本設計 詳細設計 PG
インフラの概要 ECSがデプロイするまでの一連の全設定とパイプラインは、どのマイクロサービスでも大体変わらないため Terraformでこんな感じのmoduleを作ってマイクロサービス増えてもいいようにお手軽化。 要件定義 基本設計 詳細設計 PG
インフラの概要 ECSがデプロイするまでの一連の全設定とパイプラインは、どのマイクロサービスでも大体変わらないため Terraformでこんな感じのmoduleを作ってマイクロサービス増えてもいいようにお手軽化。 オプションとして、「private = true」 にしたらALB作らずServiceDiscoveryを利用した Internal Onlyなマイクロサービスに 要件定義
基本設計 詳細設計 PG
インフラの概要 ECSがデプロイするまでの一連の全設定とパイプラインは、どのマイクロサービスでも大体変わらないため Terraformでこんな感じのmoduleを作ってマイクロサービス増えてもいいようにお手軽化。 証明書を指定したら ALBを含んだpublicなマイクロサービスに 要件定義 基本設計 詳細設計 PG
インフラの概要 マイクロサービスごとに異なるロールの設定やTask定義はこんな感じでmoduleを指定する時に 渡すようにして柔軟性を持たせた マイクロサービスごとにことなるロール 要件定義 基本設計 詳細設計 PG
インフラの概要 マイクロサービスごとに異なるロールの設定やTask定義はこんな感じでmoduleを指定する時に 渡すようにして柔軟性を持たせた サイドカーとか違う場合の タスク定義のテンプレをいくつか用意 要件定義 基本設計 詳細設計 PG
インフラの概要 マイクロサービスごとに異なるロールの設定やTask定義はこんな感じでmoduleを指定する時に 渡すようにして柔軟性を持たせた それぞれ、moduleの呼び出し時に指定 要件定義 基本設計 詳細設計 PG
インフラの概要 もう一つインフラのはなしでは、Amplify、AppSync、Pinpoint、Cognitoあたりの話を。 AmplifyはCloudFormationやTerraformなどと考え方が似ていてサービスを構築管理するための サービス・ツール郡(フロントをつくるライブラリもありますけど)という感じです。 Terraformでインフラ構築してる場合で、AppSync、Pinpoint、Cognitoなど構築する時に、 Amplifyを使うか?Terraformで全部統一したいか? と実は選択肢があります。 要件定義 基本設計 詳細設計
PG
インフラの概要 私はとりあえず「Terraformで全部統一してみたい」と思い、最初は頑張って 「AppSync、Pinpoint、Cognito」あたりをTerraform書きました。 インフラ自体はできたのですが、、、 要件定義 基本設計 詳細設計 PG
インフラの概要 私はとりあえず「Terraformで全部統一してみたい」と思い、最初は頑張って 「AppSync、Pinpoint、Cognito」あたりをTerraform書きました。 インフラ自体はできたのですが、、、 Androidの実装するときに結局Amplifyコマンドや プラグインが必要になりました 要件定義 基本設計 詳細設計 PG
インフラの概要 AppSyncのスキーマを元に Androidのファイルを自動生成す るのでコマンドが必要でした Androidプラグインも必要 要件定義 基本設計 詳細設計 PG
インフラの概要 Pinpoint、Cognitoもインフラ自体はいけますが、Androidの呼 び出し時にAmplifyのSDKを呼び出すとかあったり、それぞれ 素のSDKでもいけますけど、AwsConfigの定義が自力だと管理 面倒だったので、この2つに関してはTerraformをやめて Amplifyで構築することにしました。 要件定義 基本設計 詳細設計 PG
インフラの概要 またAppSyncを採用した理由ですが、DMとかのリアルタイムの画面の変 化に対応するためWebSocketを使いたかったのですが、ゼロからの実 装は非常に面倒なので、AppSyncの@aws_subscribeでお手軽 WebSocketを使いました。 GraphQL自体の機能はほぼ使いませんでした( ̄▽ ̄) 要件定義 基本設計 詳細設計 PG
インフラの概要 GraphQLのメリットは、呼び出し側がQueryを書いて欲しいデータを欲しいものだけ可変にとれる。 というところがあると思います。API側は全部のデータが取れるように組む必要はあります。 通常はアプリとサーバーサイドと担当わかれてるので、JSONのAPIを使ってる場合とかだと、 項目なかったら増やして、、、とかそういうやりとりが発生するかと思います。 それのやりとりを軽減することができる手段の一つとしてGraphQLがあるかと思いますが、 (AppSync単体でみた場合は、オートスケールが楽だったりとかありますが) 要件定義 基本設計 詳細設計
PG
インフラの概要 フルスタックのメリットとしては、 項目足りなかったら自分でAPIいじればいいのでGraphQLつかわずともまったく問題は なく、またAppSyncではHttpProxyとかLambdaとかも使えますが、わざわざAppSync経由 させる必要はなく、直接アプリからAPIを呼びだた方が早くメンテしやすかったので純粋 なGraphQLとしての機能は、ほとんど使いませんでした(^^;) 要件定義 基本設計 詳細設計 PG
サーバーサイドの概要 APIは全てGolangで作りました。基本的な設計思想はGolangのコンセプトでもある、標 準ライブラリだけでAPIサーバーとか作れるというところが好きで、痒いところだけ、部 分的にライブラリを使うという感じにしました。なので巨大なフレームワークのコンセプト 系のライブラリは使いませんでした。 (そのフレームワークの書き方が基準になるため、やめようと思った時に大変になるか ら) 要件定義 基本設計 詳細設計
PG
サーバーサイドの概要 大きいフレームワーク的なライブラリで言うと、 JavaとかやってきてるとDIコンテナ(Springとか)とか良く使ってましたが、 GolangにもGoogle製の「Wire」とかがあったりします。 ためしてみましたが、どうしてもWireの書き方に依存するので、コンセプトから離れてい くなぁ、、、と思い採用はせず、Golangで良くやる、 最初の方でインスタンスを生成して渡していくことにしました。 要件定義 基本設計 詳細設計
PG
Androidアプリの概要 Android Architecture Component(AAC)を基本として作りMVVMで作りました。 SwiftだとRxSwiftや、AndroidにもRxJavaとかはあります。SwiftとかもSwiftUIが出てきたり、AndroidもAACが標 準になってきてるので、Rxは使いたくなくAACでいきました。 ただし、Rxであった便利な関数とかはAACになかったりするので、coroutine-flowを使って、 Rxであった便利関数に相当する機能使い補いました。 要件定義 基本設計
詳細設計 PG
Androidアプリの概要 このアプリを作った時に採用したDIコンテナライブラリの「Koin」 この子がすごくに気に入りました( ^ω^ ) 広く使われている「Dagger」とかもありますが、初回のお作法が面倒だったり、アノテーションがみずらかった りと、なんか昔ながらのDIコンテナだなぁ。。。と思ってたところとてもシンプルでかつ、AndroidのDI使わない 場合の書き方に近く、見やすいKoinに出会いました。 要件定義 基本設計
詳細設計 PG
Androidアプリの概要 インスタンス生成時 コンストラクタで受け取り たいインスタンスの型を指 定し 要件定義 基本設計 詳細設計 PG
Androidアプリの概要 定義したコンストラクタの分だ 実際のインスタンスを設定す る インスタンス生成時 要件定義 基本設計 詳細設計 PG
Androidアプリの概要 Koinの初期化 MainのApplication()で初期化 要件定義 基本設計 詳細設計 PG
Androidアプリの概要 利用する時も、ActitityやFragmentで こんな感じでDIされてるオブジェクト を取ってくる viewModel意外もInjectで呼び出し 呼び出し時 要件定義 基本設計 詳細設計 PG
やっぱりお手軽なのはいいですね!
と、ここでいろいろ触ってる立場で思い 立ったことが、
Golangのインスタンス生成するときに、 Koinの書き方参考にしたらみやすくで きるんじゃ!?
ということで、Golangのリファクタ
サーバーの話にちょっと戻って インスタンス生成時 引数で受け取りたい インスタンスの型を 指定し 要件定義 基本設計 詳細設計 PG
サーバーの話にちょっと戻って インスタンス生成時 こんな感じで定義した引数の 分だけ実際のインスタンスを 設定する 要件定義 基本設計 詳細設計 PG
サーバーの話にちょっと戻って インスタンス生成するための initializer.goというファイルを作っ て分割し 初期化の全体。 起動ロジックとかRoutingとかはこのファイルに含 めず、Usecase、 Repository、clinet、serviceな どのインスタンス生成だけを処理まとめる 要件定義
基本設計 詳細設計 PG
サーバーの話にちょっと戻って 初期化時 mainでinitializerを呼び出し 実際に初期化 要件定義 基本設計 詳細設計 PG
サーバーの話にちょっと戻って 呼び出し時 初期化したインスタンスを Routerに渡して使う structに保持している インスタンスを利用する 要件定義 基本設計 詳細設計 PG
見やすくなった!
こんな感じで、言語変わっても 設計思想は参考にできるとこはたくさ んあるので、いろいろな視点から コード書いてます
Webフロントの概要 Webフロントは、Nuxt.js(Vue)を採用しました。 理由としては、管理画面向けだったのでInputの要素が多く、 v-modelによる双方向バインディングが書きやすかったからです。 また、Nuxt.jsのServerMiddleWareで、Node.jSのBFF-API作って 画面用にちょっと加工するためのAPIとか用意しました (私のQiita記事とかでも書いてます) 要件定義 基本設計 詳細設計
PG
Webフロントの概要 ReactやNextも使ったことありますがReactでFormik等のライブラリを使わ ない場合 要件定義 基本設計 詳細設計 PG
Webフロントの概要 ReactやNextも使ったことありますがReactでFormik等のライブラリを使わ ない場合 onChange等でInputの変化を検知し ↓ 要件定義 基本設計 詳細設計 PG
Webフロントの概要 ReactやNextも使ったことありますがReactでFormik等のライブラリを使わ ない場合 onChange等でInputの変化を検知し ↓ componentのstateに値を入れる ↓ 要件定義 基本設計 詳細設計
PG
Webフロントの概要 ReactやNextも使ったことありますがReactでFormik等のライブラリを使わ ない場合 onChange等でInputの変化を検知し ↓ componentのstateに値を入れる ↓ propsでcallbackする 要件定義 基本設計
詳細設計 PG
Webフロントの概要 ReactやNextも使ったことありますがReactでFormik等のライブラリを使わ ない場合 onChange等でInputの変化を検知し ↓ componentのstateに値を入れる ↓ propsでcallbackする Callbackが深くなる。。。 要件定義
基本設計 詳細設計 PG
Webフロントの概要 ReactやNextも使ったことありますがReactでFormik等のライブラリを使わ ない場合 onChange等でInputの変化を検知し ↓ componentのstateに値を入れる ↓ propsでcallbackする かといってライブラリ使うと、ラ イブラリに依存してしまうから、
やめたくなった時にやめるの大 変になる 要件定義 基本設計 詳細設計 PG
Webフロントの概要 ReactやNextも使ったことありますがReactでFormik等のライブラリを使わ ない場合 onChange等でInputの変化を検知し ↓ componentのstateに値を入れる ↓ propsでcallbackする かといってライブラリ使うと、ラ イブラリに依存してしまうから、
やめたくなった時にやめるの大 変になる GolangでWire使わなかった時と 同じ気持ちです 要件定義 基本設計 詳細設計 PG
Webフロントの概要 ReactもHooksが登場してきたあたりから、 かなり見やすくなったので、閲覧系がメインでFormが少ない サービスであれば、Reactでもいいかと思っています。 要件定義 基本設計 詳細設計 PG
ニュースサイトを ゼロから構築したときの話
概要 Wordpressで運用していたニュースサイトでしたが、Wordpressが重たく なってきたので刷新するという依頼を受けました。 また、記事を書くライターさんも何人もいるので運用も考えて アーキテクチャを決める必要がありました。
Wordpressで落ち入りがちなこと •プラグインをたくさん入れて重たくなる •単体で扱うことが多いためスパイクに耐えられないことが多い •冗長構成にする場合Rsyncでファイル同期になる •デザインを独自にしようとするとかなりPHPのテンプレートを いじる必要が出てくる などなど
Wordpressの便利なところ •やはり、ニュースサイトとか作る上での機能は充実している •5.0以降は「Gutenberg」というブロック式エディタを採用しているので、 記事の品質を統一しやすい などなど
アーキテクチャの方向性 •運用を考えた場合、使い勝手をWordpressに近づけたいけど、 エディタとかから選定して管理画面つくるの面倒 •サイトのパフォーマンスあげたい •高負荷に強いサイトにしたい •画面も自由に開発したい
アーキテクチャの方向性 •サイトのパフォーマンスあげたい •高負荷に強いサイトにしたい →ECS Fargate使って水平スケールしたり、CDN使って負荷 に強くしたい •画面も自由に開発したい →Nuxt.js(Vue)とかNext.js(React)
アーキテクチャの方向性 •運用を考えた場合、使い勝手をWordpressに近づけたいけど、 エディタとかから選定して管理画面つくるの面倒 →Wordpress管理画面だけ使えないかな。。。
アーキテクチャの方向性 •運用を考えた場合、使い勝手をWordpressに近づけたいけど、 エディタとかから選定して管理画面つくるの面倒 →Wordpress管理画面だけ使えないかな。。。 お、REST-APIあるから、JSONとって フロントだけ作ればいけそう https://developer.wordpress.org/rest-api/
アーキテクチャの方向性 ということで •REST-APIと管理画面だけWordpressを使用 •フロント側はNuxt.jsでゼロから構築 •インフラはECS Fargateと、CloudFrontとかでキャッシュ入れよう という方向性にしました
考えた全体アーキテクチャ ※ALBとかVPCとか、細かいのは割愛
考えた全体アーキテクチャ WordPressの公式DockerfileをベースにS3 プラグインを含んだ状態のDockerfileを作 成。複数コンテナを配置して 水平スケール可能に ※ALBとかVPCとか、細かいのは割愛
考えた全体アーキテクチャ Wordpressの画像用S3。 閲覧者はCloudFront を経由してアクセス ※ALBとかVPCとか、細かいのは割愛
考えた全体アーキテクチャ WordpressのREST-APIは CloudFront経由してBFFからアクセス ※ALBとかVPCとか、細かいのは割愛
考えた全体アーキテクチャ Nuxt.js内部にBFF作ったので、そこへのア クセスもCloudFront経由 (nuxtのbaseURLと、browserBaseURLを両 方ともCloudFront①のドメインを指定) ※ALBとかVPCとか、細かいのは割愛
考えた全体アーキテクチャ 公開するURLは、CloudFrontのドメイン ※ALBとかVPCとか、細かいのは割愛
•カテゴリページとハッシュタグページが要件として必要で タグ名やカテゴリ名から記事を検索する必要があったが 、WorkPress の記事APIのタグとカテゴリの条件がID指定だった → BFFで名称からIDを逆引きできる様に アプリキャッシュ(メモリ上のMapに数分ごとにロード) ちょっと工夫したこと
•カテゴリページとハッシュタグページが要件として必要で タグ名やカテゴリ名から記事を検索する必要があったが 、WorkPress の記事APIのタグとカテゴリの条件がID指定だった → BFFで名称からIDを逆引きできる様に アプリキャッシュ(メモリ上のMapに数分ごとにロード) •ドメインを持つ3箇所に CloudFrontを入れ、 WordPressへのアクセスを極力抑え、パフォーマンスを維持した ちょっと工夫したこと
いろいろな視点を組み合わせることで 安定した 高パフォーマンスなニュースサイトが作 れました( ^ω^ )
最後に
私は「フルスタックエンジニア」として働いてますが、 現代は技術の幅がかなり広く、一つ一つ深く知るにはそれなりの時間と 努力が必要で、私ももちろん人の何倍も技術に時間を使ってます。 大変ではありますが、広く深く知っているからできることだったり、楽しさ があったりのするので、それがとてもやりがいになっています。 最後に
最後に また、今回お話したことは、弊社の案件とは全く関わりがない 私個人が、副業で依頼され一人で構築したサービスです。 今回の事例は名前は伏せておりますが副業先にも了承を いただいています。
いろいろな開発を行ってくことで広く深いスキルを身に付けることがで き、会社のプロダクトでも、その技術を生かしています。 もちろん、どのプロダクトもサービスの根幹に関わるノウハウは口外でき ませんが、根底の技術スキルはほとんど一緒です。 最後に
「技術の循環」をすることで、より良いプロダクトになるし、 またこうやって発表の機会をいただき公開することで、 業界自体がもっと広い視点で発展して行って欲しいと思い、 今回の様なテーマで語らせていただきました。 これを見ていただいた方のご参考になれば幸いです。 最後に
ありがとうございました