$30 off During Our Annual Pro Sale. View Details »

Laravelで運用しているサービスを Nuxt.jsにリプレイスする

kubotak
December 11, 2020

Laravelで運用しているサービスを Nuxt.jsにリプレイスする

PHP Conference 2020 Track4

kubotak

December 11, 2020
Tweet

More Decks by kubotak

Other Decks in Programming

Transcript

  1. Copyright © M&A Cloud All rights reserved.
    Laravelで運用しているサービスを
    Nuxt.jsにリプレイスする
    PHP Conference 2020/Track 4
    Kenjiro Kubota

    View Slide

  2. Copyright © M&A Cloud All rights reserved.
    Profile
    2
    久保田 賢二朗
    kubotak-is
    kubotak_public
    kenjiro.kubota
    株式会社M&Aクラウド
    JavaScript Go
    PHP
    https://kubotak.page

    View Slide

  3. Copyright © M&A Cloud All rights reserved.
    PR

    View Slide

  4. Copyright © M&A Cloud All rights reserved.
    買い手

    ・案件報酬はM&A成功報酬のみ
    ・最低手数料なし
    ・売り手ソーシングのチャネルが増える
    ・M&Aニーズを発信するだけで売り手を集客
    ・仲介業者を介さずにダイレクトにやり取り可能
    ・潜在層にもリーチが可能
    手数料無料
    ※プラットフォーム案件の場合 

    ※

    売り手
    1.掲載する
    ・買い手のM&Aニーズを自ら調べることが可能
    ・仲介業者を介さずにダイレクトにやり取り可能
    ・買い手のM&A担当者に直接コンタクトをとれる
    ・仲介業者を使わないので手数料が無料
    2.オファーする
    M&A・出資ニーズを掲載
    買い手のメリット 売り手のメリット
    ・仲介業者を使わないので手数料が無料

    求人広告サイトのようなM&Aダイレクトマッチング
    〇〇領域の会社を
    募集します
    この会社と一緒に
    やっていきたい!
    4
    PR

    View Slide

  5. Copyright © M&A Cloud All rights reserved.
    注意事項
    注意事項
    ● すべてをリプレイスした、という話ではないです。
    ○ 現在進行系です。
    ● また、一部は意図して移行しません。これは後ほど説明します。
    ● どちらのフレームワークが優れているかという話ではありませ
    ん。

    View Slide

  6. Copyright © M&A Cloud All rights reserved.
    移行経緯

    View Slide

  7. Copyright © M&A Cloud All rights reserved.
    既存のアプリケーション
    既存のアプリケーション
    ● 2018年から開発が開始したLaravelによるモノリシックアプリ
    ケーション
    ● フロントエンドはBlade + Vue.js + PureJS(VanillaJS) / jQuery
    ○ Laravel標準のバリデーションやセッションフラッシュなど
    によるバリデーションエラー表示

    View Slide

  8. Copyright © M&A Cloud All rights reserved.
    アプリケーションやビジネスの拡大に伴う要求の変化
    アプリケーションやビジネスの拡大に伴う
    要求の変化
    ● UIをインタラクティブに変化させたい
    ○ 画面側に状態を持つ必要がある

    View Slide

  9. Copyright © M&A Cloud All rights reserved.
    既存アプリケーションでのVue.js
    既存アプリケーションでのVue.js
    ● Vuex(ステート管理ライブラリ)は使っていない
    ○ 親子コンポーネント間でprops/emitでバケツリレー
    ● 一部Vue.js v2.6から追加されたVueObservable APIを利用して共
    有ストアを作って状態管理などを行った
    ● 画面の初期データをBladeとVue.jsでの共有が辛い
    ○ スクリプトタグにJsonを出力するなどしてハイドレーション
    したりdata属性に出力

    View Slide

  10. Copyright © M&A Cloud All rights reserved.
    Child.vue

    View Slide

  11. Copyright © M&A Cloud All rights reserved.
    Parent.vue

    View Slide

  12. Copyright © M&A Cloud All rights reserved.

    View Slide

  13. Copyright © M&A Cloud All rights reserved.
    複雑なUIの状態と戦う
    複雑なUIの状態と戦う
    ● UIの管理が複雑化してきた
    ● 共通化できてないコンポーネント
    ○ 都度生み出される類似のボタンなど
    ● 既存仕様のまま戦うか、やり方を変えるか、

    View Slide

  14. Copyright © M&A Cloud All rights reserved.
    UIを切り離す
    UIを切り離す
    ● Laravelで開発する場合、基本的にはBlade + JavaScript
    ● コンポーネントを共通化したいが、BladeとJavaScriptでの二重
    管理になる可能性がある
    ○ LaravelからUIを完全に分離する

    View Slide

  15. Copyright © M&A Cloud All rights reserved.
    フロントエンドをNuxt.jsに置き換える

    View Slide

  16. Copyright © M&A Cloud All rights reserved.
    Nuxt.jsの選定
    Nuxt.jsの選定
    ● メンバー全員がVue.jsの経験あり
    ○ コンポーネントのライフサイクルにある程度の知見があった
    ● 個人的に何度か利用したことがあったので開発の初速が見込めた
    ● Next.js(React)でも良かったがVue.jsベースなので他メンバーの
    学習コストも下げられて説得しやすかった
    ○ TypeScriptやCompositionAPIを導入したので学習コストは
    若干あった

    View Slide

  17. Copyright © M&A Cloud All rights reserved.
    Nuxt.jsとは
    Nuxt.jsとは
    Nuxt.jsはVue.jsを利用してユニバーサルアプリケーションを作成でき
    るオープンソースフレームワークです。
    サーバーサイドレンダリング・静的ファイル生成・シングルページア
    プリケーションをサポートしています。
    Vue.jsのプラグインであるVuexやVue Router、Vue Metaなどを内包
    し、フルスタックなアプリケーション作成をサポート

    View Slide

  18. Copyright © M&A Cloud All rights reserved.
    ユニバーサルモード
    ユニバーサルモード
    Nuxt.jsにはユニバーサルモードと呼ばれるアプリケーション状態があ
    ります。
    これはHTTPリクエスト時の初期状態をSSRで表示し、以降のページ遷
    移をSPA(CSR)として振る舞うハイブリッドで動作するアプリケーショ
    ンです。
    SPAの課題であるSEOに対しても有効な手段です。

    View Slide

  19. Copyright © M&A Cloud All rights reserved.
    フロントエンドとバックエンド
    フロントエンドとバックエンド
    ● フロントエンドにNuxt.jsを採用
    ● バックエンドをそのままLaravlを使う
    ○ HTTP APIとして動作
    ○ すでに存在するドメインオブジェクトは流用活用

    View Slide

  20. Copyright © M&A Cloud All rights reserved.
    Open API(Swagger)
    Open API(Swagger)
    ● HTTP APIの定義はOpen APIを利用
    L5-Swagger(swagger-php)を利用してController(弊社ではADRを採
    用しているのでActionとResponder)にアノテーションを記述するこ
    とで定義書を管理
    link: https://github.com/DarkaOnLine/L5-Swagger

    View Slide

  21. Copyright © M&A Cloud All rights reserved.

    View Slide

  22. Copyright © M&A Cloud All rights reserved.
    ADR(Action-Domain-Responder)
    ADR(Action-Domain-Responder)
    Paul M. Jones氏が提唱するMVC(Model-View-Controller)の改良型
    アーキテクチャ
    (ざっくり)
    Model => Domain
    View => Responder
    Controller => Action
    link: https://en.wikipedia.org/wiki/Action–domain–responder

    View Slide

  23. Copyright © M&A Cloud All rights reserved.
    ADRとOpen API
    ADRとOpen API
    ADRの最大の特徴は1つのエンドポイントに1つのAction(Class)にな
    ることが挙げられる。
    この特徴を利用することで、Open APIのアノテーションをActionと
    そのActionが返却するResponderに集約されることで見通しよく記述
    できる。

    View Slide

  24. Copyright © M&A Cloud All rights reserved.
    Action

    View Slide

  25. Copyright © M&A Cloud All rights reserved.
    Responder

    View Slide

  26. Copyright © M&A Cloud All rights reserved.
    Responder

    View Slide

  27. Copyright © M&A Cloud All rights reserved.
    Open APIのアノテーションが辛い
    Open APIのアノテーションが辛い
    ● 最初の導入こそ大変だが、利用する定義はどのエンドポイントも似
    てくるので徐々に記述効率は良くなっている。
    ● GitHub上でレビューする際にアノテーションで型のレビューなどが
    しやすい。
    ● openapi-validatorを利用してAPI実装と定義が一致しているかをテ
    ストすることもでき、実装と定義書の乖離を防ぐことに役立った。
    link: https://tech.macloud.jp/entry/2020/05/22/151820

    View Slide

  28. Copyright © M&A Cloud All rights reserved.
    Nuxt.jsの実行環境

    View Slide

  29. Copyright © M&A Cloud All rights reserved.
    AWS Lambda
    AWS Lambda
    AWS Lambdaはサーバーのプロビジョニングや管理の必要なしに、
    コードが実行できる環境です。
    Nuxt.jsのアプリケーションはこのAWS Lambda上で動作させます。
    デプロイにはServerless Frameworkを利用して、静的ファイルやクラ
    イアントで実行されるJavaScriptファイルはS3に配置します。

    View Slide

  30. Copyright © M&A Cloud All rights reserved.
    Serverless Framework
    Serverless Framework
    サーバーレスアプリケーションの構成管理やデプロイを行うツール
    プラグインが豊富でいろんなユースケースをカバーできる
    ● serverless-plugin-warmup
    ○ コールドスタート対策
    ● serverless-prune-plugin
    ○ 古いバージョンを削除
    ● serverless-cloudfront-invalidate
    ○ デプロイ後にCloudfrontのキャッシュを削除

    View Slide

  31. Copyright © M&A Cloud All rights reserved.

    View Slide

  32. Copyright © M&A Cloud All rights reserved.
    ● すべてのページを一括でNuxt.jsに移行するのは工数的に困難
    ● 既存のLaraveはElasticBeanstalk上で稼働させている
    ● CloudfrontのBehaviorsを利用してパス毎にリクエストの流す先
    を分岐させる
    ○ 段階的にNuxt.jsにリプレースされたページに移行していく
    段階的なリリース
    段階的なリリース

    View Slide

  33. Copyright © M&A Cloud All rights reserved.

    View Slide

  34. Copyright © M&A Cloud All rights reserved.
    小ネタ:Lambda上のNuxt.jsからLaravelへのHTTPリクエストが通らない
    小ネタ:Lambda上のNuxt.jsから
    LaravelへのHTTPリクエストが通らない
    ● Nuxt.jsからLaravelのHTTPのエンドポイントへのリクエストは
    axiosを利用
    ○ LambdaにデプロイしたNuxt.js上でこのリクエストが失敗
    (ステータスコード403)
    ○ どういうこと?

    View Slide

  35. Copyright © M&A Cloud All rights reserved.
    想定のリクエスト

    View Slide

  36. Copyright © M&A Cloud All rights reserved.
    実際のリクエスト

    View Slide

  37. Copyright © M&A Cloud All rights reserved.
    だとしても何がイケないのか

    View Slide

  38. Copyright © M&A Cloud All rights reserved.
    Cloudfrontは多段構成できない
    Cloudfrontは多段構成できない
    ● Cloudfrontは多段構成出来ない仕組みになっている
    ● Cloudfrontを経由したリクエストはヘッダーにviaというパラ
    メータが付与される
    ○ Lambda上で動かしているNuxt.jsで利用しているaxiosでは
    リクエストヘッダーを引き継いぐ
    ■ viaが引き継がれるので多段構成とみなされる
    Qiita: https://qiita.com/kubotak/items/fc1a877f99a569fc54bb

    View Slide

  39. Copyright © M&A Cloud All rights reserved.
    ログインセッション

    View Slide

  40. Copyright © M&A Cloud All rights reserved.
    ログインセッション
    ログインセッション
    ● LaravelとNuxt.jsが混在した状態でのログインセッションの共有
    ○ Laravelで発行されるCookieをそのまま利用
    ● クライアントで実行されるJSではaxiosによるリクエストに
    Cookieが付与される形でLaravel側でユーザーセッションが判断
    できる
    ● サーバーサイドのNuxt.jsでも同様にHTTPリクエストから取得し
    たCookieをaxiosでリクエストに付与

    View Slide

  41. Copyright © M&A Cloud All rights reserved.


    ユーザーを判別
    SSR
    CSR
    with axios

    View Slide

  42. Copyright © M&A Cloud All rights reserved.
    Cookieを付与するタイミング
    Cookieを付与するタイミング
    すべてのページをNuxt.jsで構築してしまうとサーバーがブラウザに
    Cookieを付与することができません。
    ログインページや会員登録ページのPOST先などはLaravelで作られ
    たエンドポイントにリクエストさせて、ブラウザにログインセッショ
    ンのCookieを付与する設計になった

    View Slide

  43. Copyright © M&A Cloud All rights reserved.
    POST

    Cookie付与

    View Slide

  44. Copyright © M&A Cloud All rights reserved.
    リクエストバリデーション
    リクエストバリデーション
    Cookieを付与しなくてはいけないログインページや会員登録ページで
    はクライアントのみでバリデーションが完結しません。
    [email protected]
    ************
    送信
    placeholder
    送信
    invalid!

    View Slide

  45. Copyright © M&A Cloud All rights reserved.
    リクエストバリデーション
    リクエストバリデーション
    POST先でリクエストバリデーションを行った結果を元のページにエ
    ラーとして通知するためにエラー用のCookieを付与してクライアン
    ト側で表示させる
    [email protected]
    ************
    送信
    placeholder
    送信
    invalid!

    入力に誤りがあります

    View Slide

  46. Copyright © M&A Cloud All rights reserved.
    移行してどうだったか

    View Slide

  47. Copyright © M&A Cloud All rights reserved.
    動的に遷移するページを作れた
    動的に遷移するページを作れた

    View Slide

  48. Copyright © M&A Cloud All rights reserved.
    移行後
    移行後
    ● TypeScriptによる型の恩恵
    ● 旧環境ではVue.jsのコンポーネントとPureJSが混在していてUIが
    どちらの処理かわかりにくかった点などはすべてNuxt.jsに集約さ
    れた
    ● scoped CSSにより安全にCSSを書くことができるようになった
    ● アトミックデザインのようなコンポーネント設計を取り入れたので
    パーツの再利用性が上がり、サイトのテイストが統一された
    ● etc

    View Slide

  49. Copyright © M&A Cloud All rights reserved.
    メンバーの声
    メンバーの声
    いいかんじ(≧∇≦)b 考えることが増えたので複雑になった
    気がしますが、apiを適切に切ってれ
    ばこれ以上無闇に複雑化しないかもと
    いう期待はある。

    View Slide

  50. Copyright © M&A Cloud All rights reserved.
    まとめ
    まとめ
    ● APIドキュメントが整備されているとフロントエンドとの連携がス
    ムーズ
    ● Lambdaを利用することでサーバーメンテナンスのコストをなくす
    ● CloudfrontのBehaviorsを利用して段階的に移行
    ● LaravelのCookieはそのまま利用
    ● LaravelとNuxt.jsでステートを共有するためにCookieを使う

    View Slide

  51. Copyright © M&A Cloud All rights reserved.
    WE ARE HIRING!
    M&Aクラウドでは
    一緒に働く仲間を募集しています
    PR
    https://www.wantedly.com/companies/macloud

    View Slide

  52. Copyright © M&A Cloud All rights reserved.
    Thank you for watching :)

    View Slide