Slide 1

Slide 1 text

Nuxt.js + Google App Engine でのアプリケーション開発 の勘所 フリュー株式会社 新規事業開発部 システムアーキテクト 佐藤慧太

Slide 2

Slide 2 text

自己紹介 ◦ 佐藤 慧太 @SatohJohn ◦ フリュー株式会社 新規事業開発部 システムアーキテクト ◦ Webエンジニア ◦ フロントからバックエンドからインフラからシステム設計まで そして、組織の構成のことを考えながら過ごしてます ◦ 最近はGCPに合うJVM言語、フレームワークの動向を頑張って追っています

Slide 3

Slide 3 text

自己紹介 ◦ Vue.jsとの付き合い ◦ 2系がリリースされたころから利用している ◦ 社内で取り入れ始めた ◦ 関西のVueコミュニティ(v-kansai)のお手伝いしてた ◦ Nuxt.jsを使い始めたのが1年前ぐらい

Slide 4

Slide 4 text

会社紹介 ◦ フリュー株式会社 ◦ プリントシール機や フィギュアなどプライズ製品の製造・販売 若年女性向けサービスやゲーム・アニメ制作など 幅広く事業を展開している ◦ 新規事業開発部は、新しい柱を立ち上げるが ミッション ◦ シューマツワーカーさんに手伝っていただいております

Slide 5

Slide 5 text

ミミニミニミミの紹介 ◦ 若年女性向けの音声サービス ◦ iPhone + Google App Engine(Node.js)での開発 ◦ Firebase Functionsで作成していたが、 通信速度上GAEのほうが良かったため載せ替え ◦ webページ、運用のツールはNuxt.jsで作成

Slide 6

Slide 6 text

今回話すこと Nuxt.js + GAEでSPA vs SSR どっち使う? ここでの「SSR」はNuxt.jsの元「Universal」modeのことです

Slide 7

Slide 7 text

SPA vs SSRの基本

Slide 8

Slide 8 text

SSRを使うメリット ◦ サーバ上でLoginの判定ができる(nuxtServerInit) ◦ 個人の特有情報や管理画面を守るために、一度Loginページに飛ばす ◦ そもそも一度Loginページを挟まないと行けないのか? ◦ Loginしてなければ、データが取得できないから別にいいのでは? ◦ clientでの初期化でも良いのなら以下pluginでも代用可能 ◦ https://github.com/potato4d/nuxt-client-init-module

Slide 9

Slide 9 text

SSRを使うメリット ◦ 「最終的な完成した画面」のレンダリング時間は早くなる ◦ FrontサーバとBackendサーバ間と、端末とBackendサーバ間の物理距離の問題はある ◦ でも、SPAってそもそも一部データだけ、サーバからとってきて表示する。 それ以外は静的なので、そこを早く見せるという効果もあるハズ。

Slide 10

Slide 10 text

SSRを使うメリット ◦ サーバでレンダリングすることで、SEOに引っかかりやすくする ◦ SEOを上げることで検索流入が増えるからやっておいたほうがいい ◦ でも正直、そのメリットがあんまりない ◦ Googleのクローラとかも進化しててきちんとJavaScriptの結果を見ている ◦ OGPはprerender.ioなどのサービスを使うことで解決できる

Slide 11

Slide 11 text

SSRを使うデメリット ◦ SSR時にデータのシリアライズ/デシリアライズが走るので、classのメソッドが死ぬ ◦ 全部typeで書くようにするという決まりを作る or SSR用のマッピングを書くようになる ◦ ただでさえBackendサーバから返ってくるJSON色付けしているのに、SSRのものも書くの辛い

Slide 12

Slide 12 text

SSRを使うデメリット ◦ cookieでのLogin Session管理がややこしくなる ◦ SSR中のメソッド(AsyncData/Fetch)ではcookieをよみこんで、通信してくれない ◦ process.clientならcookieがつくので、何もせずそのままリクエストできる ◦ Cookieじゃないtoken例えばidTokenなどの場合期限が1時間なのと、 localStorageとかに置くことが多いから結局serverからのリクエストには載せられない

Slide 13

Slide 13 text

ここまでの結論 SPAで良いのでは? これは伏線です

Slide 14

Slide 14 text

GAE+IAP認証での SPA vs SSRについて

Slide 15

Slide 15 text

システム構成図 ◦ iPhoneアプリ + web(Nuxt.js)の構成 ◦ APIに対してIAP認証がある

Slide 16

Slide 16 text

IAP認証について ◦ GAEサービスへアクセスする際に 特定のアカウントだけアクセスできる ◦ GAEへのアクセスがあると、アプリケーションが起動してしまう ◦ 未ログインでも使える機能であった場合でも、 誰でもアクセスできるようにはしたくない ◦ アクセスが増えるとDBへの負荷が上がったり

Slide 17

Slide 17 text

IAP認証に必要なもの ◦ アクセス許可のあるサービスアカウントでの認証情報 ◦ HeaderにTokenをつけてリクエストする ◦ google-auth-library を使うと、とても楽

Slide 18

Slide 18 text

SPAでIAP認証を対応する場合 ◦ clientでapikeyを入れて、使うことができるdomainを制限してやる ◦ APIにしかアクセスできない、service accountを作成して、そのキーをclientに露出する ◦ アプリケーションは起動するが、バックエンドサーバでCORSで対応する

Slide 19

Slide 19 text

SPAでIAP認証を対応する場合 行儀よくない

Slide 20

Slide 20 text

Nuxt.jsをフロントサーバにする ◦ Nuxt.jsのexpress serverにまかせて、アクセスする ◦ ServerMiddlewareを使ってcustom urlを使う ◦ https://ja.nuxtjs.org/docs/2.x/configuration-glossary/configuration-servermiddleware/#custom-api-endpoint ◦ Server内でGAEデフォルトの認証を使ってアクセスする ◦ IAPでアクセス許可を入れておくのを忘れない

Slide 21

Slide 21 text

export default { ssr: true, serverMiddleware: [ { path: '/api', handler: '~/api/index.ts'} ] } nuxt.config.ts

Slide 22

Slide 22 text

import { Response, Request } from 'express' import * as bodyParser from 'body-parser' import { GoogleAuth } from 'google-auth-library' const { BASE_URL, TARGET_AUDIENCE } = process.env const gAuth = new GoogleAuth() const app = require('express')() app.use(bodyParser.json()) app.all('/', async (req: Request, res: Response) => { const client = await gAuth.getIdTokenClient(TARGET_AUDIENCE) client.request({ baseURL: BASE_URL || 'https://example.an.r.appspot.com/', url: `test/url` }) .then((responseData) => { res.json(responseData.data) }) .catch((err) => { res.status(err.response?.status ?? 400) res.json({}) }) }) module.exports = app ~/api/index.ts

Slide 23

Slide 23 text

axios-client.ts import axios, { AxiosRequestConfig } from 'axios' const config: AxiosRequestConfig = {} if (process.server) { config.baseURL = 'http://127.0.0.1:8080' } export const axiosClient= axios.create(config)

Slide 24

Slide 24 text

そしての結論 フロントサーバとして SSR必要かも

Slide 25

Slide 25 text

まとめ ◦ 単純にNuxt.jsを使うなら、SPAが良いんじゃないかな? ◦ GAE + IAPを使った認証を挟む場合は、SSRで対応すると良いかも ◦ Nuxt.jsをフロントサーバとして利用する ◦ フロントサーバとして、1サービス追加するか ◦ そして、SSRの機能を使う部分は一部にする ◦ 使えるけど使わないという気持ち

Slide 26

Slide 26 text

おわり