AKB48グループ映像倉庫のWeb版をリリースしましたので構成や技術スタックについて簡単に紹介したいと思います。
構成図
- API Gateway: フロントのAPIとバックエンドのAPIを中継する
- Video API: フロントサービス毎に動画の検索/配信URLの生成を提供する
- Platform API: レコチョク共通の会員/決済機能などを提供する
技術スタック
- インフラ(AWS)
- RDS(MySQL)
- Elastic Beanstalk
- Application Load Balancer
- EC2
- S3
- API
- Flask(Python)
- フロント
- Nuxt.js (SPAモード)
- その他
- CDN
- Datadog
- Google Analytics
- Sentry
アーキテクト全般
全部サーバーレスも検討したのですが外部システムとの連携のため固定IPが必要であったこととリリース日が決まっていて、フロントエンドでも技術的なチャレンジがあり、両方で問題が起きたとき詰む可能性があったためAPIは無難にEC2を採用しました。
また、開発環境構築時に利用してみたElastic BeanstalkのCLIが使いやすくなっていたためそのまま商用環境にも採用しました。
設定を保存できるためGitHubでElastic Beanstalkのインスタンスタイプや環境変数なども管理できるのは便利です。
(RDSはBeanstalkで扱うのが間違って消しそうでなんとなく怖いので別のスタックにしています)
フロントエンドについては、完全に静的ファイル(HTML/JS/CSSのみ)にすることで(HTMLの描画部分は)サーバーレスになっています。
そのため、フロントエンドのソースをCDNから配信しAPIからデータをHTTPで送受信する構成になっています。
Nuxt.js
今回のサービスの特徴としてフロントエンドにNuxt.jsを採用しています。
2016年頃からWIZYのプロジェクトにてVue.jsを使い続けてVue.jsに関する知識が溜まってきたことと、
2017年末頃から社内のサイドプロジェクトにてNuxt.js x RestAPIの組み合わせを試していて、ある程度技術的な制約や課題の見通しが立った為、今回のサービスで採用してみました。
SSRモードも検討したのですがSEO観点を除いたメリットが特になく、パフォーマンスの予測が難しいことやセキュリティ的に考慮することが増えてしまう為、現時点での採用はリスクが高いという判断でSPAモードを選択しています。
API認証
APIサーバーの認証はJWT認証を使用しています。
vue-storeトークンを保管しaxiosのリクエスト実行時にAuthorizationヘッダーをセットします。
export default function ({$axios, store}) { $axios.onRequest(config => { config.headers.common['Authorization'] = `Bearer ${store.state.authToken}` }) } |
Swagger-Codegenで生成したPythonクライアントと比べると使いやすくて良かったです。
ブラウザ対応
不安だった古いブラウザへの対応ですが結果的にChrome/Safari/Firefox/IE11にも対応することができました。
Polyfillやautoprefixerを使用しつつダメなところは記述方法を変えたりすることで最終的には大きな問題なく利用できる状態になりました。
ブラウザによっては外部JavaScriptファイルの読み込みタイミングが微妙に違ったり動画関連の機能差異があったりと色々試行錯誤していったん使える状態にはなっていますが、今後の推奨環境も考慮しつつ見直ししたいと思います。
インフラについて
フロントエンドを全てS3に配備できるようになったことでデプロイが s3 cp コマンドのみで完結したり、単純にサーバーがないので運用の手間やコスト削減にもなったり、パフォーマンスの観点でもサーバーがないためリクエストの処理をCDNに任せられるので楽でした。
SEOについて
nuxt-pwaを使用することで簡単にPWA化することができました。
また、SPAモードにして気になっていた検索エンジンからの見え方ですがJavaScriptが動作した結果のdescriptionで正しく登録されるなど現時点で問題は無いように見えます。
視聴環境について
今のところ視聴環境は
SP:PC:Tab = 6:3:1 くらい の比率です。
動画サービスなのでSPの比率はPCとタブレットもそこそこあるようですがSP環境の方が最も多いですね。
(SPだけしか持っていない人はいてもPC/タブレットしか持っていない人というのはあまりいないと思いますので、UUベースでの比率はまた異なるかもしれません)
やはりiPhoneユーザーが割合的には一番多いのですが、iOS SafariはMediaSourceExtensionsを実装していないため他のブラウザと比較して動画再生機能が劣ることがサービスを実装してみてわかりました。
まとめ
結果的にNuxt.jsを選択して良かったです。
シンプルなアプリケーションならデフォルトで十分ですしプラグインをインストールしたり自分で書いたりする事でカスタマイズも可能で、Webpackをゴリゴリ書いてゴニョゴニョする事に疲れた人にはちょうど良いと感じました。
2.0が来そうで来ないので落ち着いたらバージョンアップに備えようと思います。
この記事を書いた人
最近書いた記事
- 2021.12.10React NativeでWallet風UIを実装する
- 2018.11.19Elasticsearchで簡単な検索とscoreを調整する方法
- 2018.10.05ECSをEC2からFargateに切り替える際の注意点
- 2018.09.12AKB48グループ映像倉庫のWeb版をリリースしました