MindSphereを案件で使用するにあたり、勘所や得た知見などを残しておきます。
随時更新予定。
Vue/Nuxt/SPA使用時のルーティングについて
NuxtはVueのフレームワークです。
MindSphere上でNuxtをSSRで使うこともできるでしょうが、今回は静的サイトジェネレータ(最新版v.2.4ではyarn generate
)で出力してからCF pushでデプロイしていました。
ただ静的ファイルとして出力する際に問題があるのがURL周りです。一般にSPAではHistory APIを使った「クリーンな」URL(http://localhost/users のようなもの)と、Hash(フラグメント識別子)を使ったURL(http://localhost/#users )の二通りがあります。多くの場合は「クリーンな」URLが好まれますが、サーバー側の設定をする必要があるため、サーバーの設定ファイルをいじれない場合は使用できません。
MindSphereが利用する静的サイト用のビルドパックもデフォルトではこの設定がされておらず、少なくとも自分ではいい方法が見つかりませんでした。
もしもHashモードでもいいのであれば、Nuxtの場合はnuxt.config.jsを以下のように書き換えます。
export default {
router: {
mode: 'hash'
}
}
これで動きはします。
ただ、細かい点ではHashとHistoryでは性能差はありますが見栄え的な理由からHistoryのほうが望ましいので、できればHisoryで実行できるよう試行錯誤しました。
当初はCFのbuild_packのオプションなどをいじっていましたが、どうもうまく行かず。
最終的にはNodejsのビルドパックであるnodejs_buildpack
と、express.js(とconnect-history-api-fallback
)を利用して、静的ファイルをexpress.js経由で出力する方法に切り替えました。
仮にNuxtの静的出力ディレクトリをnuxt-dist/dist
とすると、以下のような構成にします。
nuxt-app
├ assets
├ components
├ pages
├ (その他Nuxtディレクトリ)
└ nuxt-dist
├ .dist
├ server.js
└ package.json
インストールするパッケージは2つだけです。ローカルで使用する場合は以下のコマンドでインストールします。
yarn add express connect-history-api-fallback
最後に、expressjsで実行されるserver.jsは以下のようになります。
const path = require('path')
const express = require('express')
const history = require('connect-history-api-fallback')
const app = express()
const root = path.join(__dirname, '/dist') // Nuxt出力ディレクトリ
app.use(history())
app.use(express.static(root))
app.listen(process.env.PORT || 3000)
以上でOKです。
あとはmanifest.ymlを例えば以下のように指定をします。
applications:
- name: app-name
memory: 100M
instances: 1
path: ./nuxt-dist # server.js、package.json、distが入ってるDir
host: app-host
buildpack: nodejs_buildpack
正直Nuxtのディレクトリ関係を把握しないと混乱するかもしれません。Nuxt開発時とexpressによって実行されるファイルの区別がつくようによく考えて構成しないと混乱を生むと思います。
MindSpheres取り込み制限
MindSphereにはデータ取り込みレート(Data ingest rate)という制限があります。これは場合によっては作成するMindSphereアプリの制限になりえるので最初に計算しておくといいと思います。
この制限はプランによって異なりますが、たとえばSプランの場合はデータ取り込みレートは3KB/sです。
3KB/sというのは、たとえばアセットは(Sプラン最大の)20個として、30個の変数(variables=アスペクトで設定できるもの)があるとして、その変数がそれぞれ50バイトのデータ(オーバーヘッド込)とすると、10秒に一回データを送信できる、という意味です
データサイズ/秒 = (203050)/10
もしも10秒に一度データを送信する場合、理論上最大で一度に30KB送信できます。
これを超えるとさすがに問題になると思うので予め設計しておく必要があります。
アプリケーションクレデンシャル
Developer cockpitで、アプリごとに発行され、そのアプリに割り当てられているロールをToken Management Service経由で使用することができるクレデンシャルです。一つのアプリに一つのアプリケーション・クレデンシャルが発行されます。
基本的にアプリケーション・クレデンシャルは他人に知られないよう隠す努力が必要です。
このアプリケーション・クレデンシャルを例えばサブテナントに渡してしまうのもよくないパターンです。仮にこのクレデンシャルの使用者がサブテナントのユーザーであっても、アプリケーションのロール(権限)で使用されることになります。つまり通常はそのサブテナントは自分が割り当てられたサブテナントアセットにしかアクセスできませんが、、アプリケーションのロールでアセットマネージャーAPIの使用が割り当てられている際は、他のサブテナントにもアクセスできてしまうことになります。
そのため、基本的にはアプリケーション・クレデンシャルは他人に知られないように運用しなければいけません。
またアプリケーション・クレデンシャルは365日ごとの交換が必要になりますので、交換の際にダウン・タイムが発生しますのでこのあたりも運用時の考慮に必要です。
また自分はDeveloperプランなので使用したことはありませんが、Operatorプランの場合は自動的にアプリケーション・クレデンシャルを更新できるようです。