- 投稿日:2020-03-01T23:00:06+09:00
Nuxt.jsのpluginsにaxiosの共通部品を実装する
はじめに
Nuxt.jsにてクライアントサイドのvueからサーバのREST APIを呼び出す際に、vue内のスクリプトにロジックを書くと、他の場所で流用できない。そのため、外部のjsに共通ロジックとしてサーバのAPIを呼び出す処理を記述したかったが、あまり良い例が無かったので、検討&実装してみた(正しいかは不明)
Vuexストア内でaxiosを使ってサーバAPIを呼び出すみたなことをやってる人も居たけど、それはちょっと違うだろう(というか気持ち悪い)ということで、pluginsに共通ロジックを作成することにした。構成
修正する対象は以下の3ファイル(pages/index.vue , plugins/axios.js , plugins/api.js)
ROOT ├─.nuxt ├─assets ├─components ├─layouts ├─middleware ├─pages │ index.vue ├─plugins │ api.js │ axios.js ├─server ├─static ├─store └─testaxios.js
以下の記事を参考に、pluginsフォルダ配下にaxios.jsを作成する。
今回は記事のまま修正はしていない。このプラグインを作成することで、axiosでサーバアクセスする際、
リクエスト発生時、エラー発生時に処理をフックして任意の処理を実行することができる。
$axios.onResponseでレスポンス時にフックすることも可能。https://axios.nuxtjs.org/extend
axios.jsexport default function ({ $axios, redirect }) { $axios.onRequest((config) => { console.log('Making request to ' + config.url) }) $axios.onError((error) => { const code = parseInt(error.response && error.response.status) if (code === 400) { redirect('/400') } }) }api.js
このjsがapiを呼び出す共通部品。
api.jsexport default function ({ $axios }, inject) { const api = new API($axios) inject('api', api) } class API { constructor (axios) { this.axios = axios } async getHoge () { const res = await this.axios.$get('http://localhost:3000') console.log(res) } }次の処理を入れることで、後述するvue内で $api としてアクセスすることができるようになる。
inject('api', api)ここまで作成したら、 nuxt.config.js 内の plugins に次のように記載する。
nuxt.config.jsplugins: [ '~/plugins/axios', '~/plugins/api' ],idnex.vue
index.vueの<script>部分だけを抜粋。
asyncData() 内ではthisが使えないので、context.app.\$api.getHoge()
mounted() 内などのthisが使える箇所では、this.\$api.getHoge()
とすることで、api.jsに記載したaxiosの共通ロジックを呼び出すことができる。index.vue<script> import Logo from '~/components/Logo.vue' export default { components: { Logo }, asyncData (context) { context.app.$api.getHoge() return { } }, mounted () { this.$api.getHoge() } } </script>まとめ
この記述がNuxt.jsとして正しいかどうかは、少し微妙なところ。
そもそもAPIクラスを作成する必要が無く、inject('メソッド名', function)とすればよい。
しかし、今回作成したかったアプリケーションは、バックエンドが複数あり、
そのバックエンド毎に処理を実行する共通インスタンス(この例では\$api)を
作成したかったからこのようにしている。
\$backendA.getHoge(), \$backendB.getHoge() のような感じ。参考
- Axios Module
https://axios.nuxtjs.org/
なぜNuxt.jsの本家サイトにこの例が記載されていないのかが謎ってくらい「なるほどね」ってなった。- Nuxt.jsでaxiosの共通処理を作成し、API呼び出し処理をラップして使用する
https://qiita.com/itouuuuuuuuu/items/4132e3b7ddf2cbf02442
最初この記事を見つけたときは「おぉ!!」ってなった。次の2点を自分なりに改善してみたのが本記事。
- export let axios;
plugins/axios/index.js 内で export let axios; としている。
axiosをexportしたかったからこのようにしたんだと思うけども、
これだとESLintのimport/no-mutable-exports に引っかかってしまう。- import UserApi from '@/plugins/axios/modules/user'
作成した共通部品をvue内で使用する際にimportしなければならない。
これは地味にメンドイ。
- 投稿日:2020-03-01T17:23:26+09:00
node.jsをインストールの際、Chocolateyの提案を受けたのでインストールしてみた
概要
windowsでnode.jsをインストールしてみた。
ネットのインストール画像にはない、Chocolateyに関するインストール確認がでてきたたため、合わせてインストールしてみた。環境
windows 10
node-v12.16.1-x64インストール画面
以下が、Chocolateyに関するインストールの確認。
チェックをいれると、インストールされる。
Some npm modules need to be compiled from C/C++ when installing. If you want to be able to install such modules, some tools (Python 2 and Visual Studio Build Tools) need to be installed.
一部のnpmモジュールは、インストール時にC / C ++からコンパイルする必要があります。
そのようなモジュールをインストールできるようにするには、いくつかのツール(Python 2およびVisual Studioビルドツール)をインストールする必要があります。Automatically install the necessary tools. Note that this will also install Chocolatey. The script will pop-up in a new window after the installation completes.
必要なツールを自動的にインストールします。 これにより、Chocolateyもインストールされることに注意してください。
インストールが完了すると、スクリプトが新しいウィンドウにポップアップ表示されます。Alternatively, follow the instructions at https://github.com/nodejs/node-gyp#on-windows to install the dependencies yourself.
または、https://github.com/nodejs/node-gyp#on-windowsの指示に従って、依存関係を自分でインストールします。この後には、以下の画面でChocolateyのインストールが始まった。
- 投稿日:2020-03-01T15:55:03+09:00
nodejsのorマッパー sequelize のaccociaton
associationのまとめ
belongsTo
1つの関連をもつ。
- 例) Players.belongsTo(Teams) Playersに外部キー
teamIdが自動追加される。hasOne
1つの関連をもつ。
- 例) Players.hasOne(Profiles)
Profilesに外部キー
playerIdが自動追加される。include時、最初の1つのみ出力される。hasMany
複数の関連をもつ。
- 例) Players.hasMany(Profiles)
Profilesに外部キー
playerIdが自動追加される。include時、複数件出力される。belongsToMany
多対多の中間テーブルを持つ。
例1)Players.belongsToMany(Teams, { through: TeamPlayers })
中間テーブル'TeamPlayers'が作成され、そこに外部キーteamIdplayerIdが自動追加される例2)Teams.belongsToMany(Players, { through: TeamPlayers })
中間テーブル'TeamPlayers'が作成され、そこに外部キーplayerIdteamIdが自動追加されるbelongToとhasOneの違い
挙動はほぼ同じ。指定の順が変わっただけ。
belongsTo のサンプル
// model(テーブル)を定義 // 主キー`id`や`createdAt`、`updatedAt`は勝手に定義されるので記述不要 const Players = sequelize.define('players', { name: Sequelize.STRING, }); const Teams = sequelize.define('teams', { name: Sequelize.STRING, }); Players.belongsTo(Teams, { foreignKey: 'team_id' }) // playersに外部キー'team_id'が作成される。foreignKeyを省略した場合、キャメルケースでid名'teamId'が自動生成される // modelを元にDBテーブルの作成({force:true}オプションは、テーブルdrop&create) await Players.sync({ force: true }); await Teams.sync({ force: true }); // レコードのcreate const team1 = await Teams.create({ name: 'team1' }); const player1 = await Players.create({ name: 'player1', team_id: team1.id }); // レコード取得 const player = await Players.findById(player1.id, { include: Teams }) console.log(player.get({ plain: true }))出力結果
{ id: 1, name: 'player1', createdat: 2019-08-29t02:36:21.464z, updatedat: 2019-08-29t02:36:21.464z, team_id: 1, team: { id: 1, name: 'team1', createdat: 2019-08-29t02:36:21.448z, updatedat: 2019-08-29t02:36:21.448z } }以下でも、teams : players = 1 : n で取得できそうだが、できない
const team = await Teams.findById(team1.id, { include: Players})出力結果
failed: sequelizeeagerloadingerror: players is not associated to teams!
hasOne のサンプル
// model(テーブル)を定義 const Players = sequelize.define('players', { name: Sequelize.STRING, }); const Profiles= sequelize.define('profiles', { name: Sequelize.STRING, }); Players.hasOne(Profiles,{foreignKey:'player_id'}) // modelを元にDBテーブルの作成 await Players.sync({ force: true }); await Profiles.sync({ force: true }); // レコードのcreate const player1= await Players.create({ name: 'player1' }); const profile1= await Profiles.create({ name: 'profile1', player_id: player1.id }); const profile2= await Profiles.create({ name: 'profile2', player_id: player1.id }); // レコードの取得 const player = await Players.findById(player1.id, { include: Profiles}) console.log(player.get({ plain: true }))出力結果
{ id: 1, name: 'player1', createdAt: 2019-08-29T03:59:30.432Z, updatedAt: 2019-08-29T03:59:30.432Z, profile: { id: 1, name: 'profile1', createdAt: 2019-08-29T03:59:30.448Z, updatedAt: 2019-08-29T03:59:30.448Z, player_id: 1 } }hasMany のサンプル
// model(テーブル)を定義 const Players = sequelize.define('players', { name: Sequelize.STRING, }); const Profiles= sequelize.define('profiles', { name: Sequelize.STRING, }); Players.hasMany(Profiles,{foreignKey:'player_id'}) // modelを元にDBテーブルの作成 await Players.sync({ force: true }); await Profiles.sync({ force: true }); // レコードのcreate const player1= await Players.create({ name: 'player1' }); const profile1= await Profiles.create({ name: 'profile1', player_id: player1.id }); const profile2= await Profiles.create({ name: 'profile2', player_id: player1.id }); // レコードの取得 const player = await Players.findById(player1.id, { include: Profiles}) // hasOneだと最初の1件しか取得できないがhasManyだと全て取得できる console.log(player.get({ plain: true }))出力結果
{ id: 1, name: 'player1', createdAt: 2019-08-29T04:13:05.396Z, updatedAt: 2019-08-29T04:13:05.396Z, profiles: [ { id: 1, name: 'profile1', createdAt: 2019-08-29T04:13:05.412Z, updatedAt: 2019-08-29T04:13:05.412Z, player_id: 1 }, { id: 2, name: 'profile2', createdAt: 2019-08-29T04:13:05.428Z, updatedAt: 2019-08-29T04:13:05.428Z, player_id: 1 } ] }belongsToMany のサンプル
// model(テーブル)を定義 // 主キー'id'や'createdAt'、'updatedAt'は勝手に定義されるので記述不要 const Players = sequelize.define('players', { name: Sequelize.STRING, }); const Teams = sequelize.define('teams', { name: Sequelize.STRING, }); const TeamPlayers = sequelize.define('team_players', { name: Sequelize.STRING, }); // 中間テーブル'TeamPlayers'を作成し、そこに'team_id'を追加する Players.belongsToMany(Teams, { through: TeamPlayers, foreignKey: 'team_id' }) // 中間テーブル'TeamPlayers'を作成し、そこに'team_id'を追加する Teams.belongsToMany(Players, { through: TeamPlayers, foreignKey: 'player_id' }) await TeamPlayers.sync({ force: true }); await Players.sync({ force: true }); await Teams.sync({ force: true }); // レコードのcreate const team1 = await Teams.create({ name: 'team1' }); const team2 = await Teams.create({ name: 'team2' }); const player1 = await Players.create({ name: 'player1' }); player1.addTeam(team1,{ status: 'started' }) player1.addTeam(team2,{ status: 'started' }) const player2 = await Players.create({ name: 'player2' }); player2.addTeam(team1,{ status: 'started' }) player2.addTeam(team2,{ status: 'started' }) // レコード取得 const player = await Players.findById(player1.id, { include: Teams }) console.log(player.get({ plain: true })) const team= await Teams.findById(team1.id, { include: Players}) console.log(team.get({ plain: true }))出力結果
{ id: 1, name: 'player1', createdAt: 2019-08-29T05:56:11.200Z, updatedAt: 2019-08-29T05:56:11.200Z, teams: [ { id: 1, name: 'team1', createdAt: 2019-08-29T05:56:11.168Z, updatedAt: 2019-08-29T05:56:11.168Z, team_players: [Object] }, { id: 2, name: 'team2', createdAt: 2019-08-29T05:56:11.184Z, updatedAt: 2019-08-29T05:56:11.184Z, team_players: [Object] } ] } { id: 1, name: 'team1', createdAt: 2019-08-29T05:56:11.168Z, updatedAt: 2019-08-29T05:56:11.168Z, players: [ { id: 1, name: 'player1', createdAt: 2019-08-29T05:56:11.200Z, updatedAt: 2019-08-29T05:56:11.200Z, team_players: [Object] }, { id: 2, name: 'player2', createdAt: 2019-08-29T05:56:11.217Z, updatedAt: 2019-08-29T05:56:11.217Z, team_players: [Object] } ] }
- 投稿日:2020-03-01T14:40:25+09:00
node-canvasで絵文字を扱う
ユーザ生成コンテンツは、OGPを画像化して見せるのがデファクトスタンダードのようになってきました。
node.jsから、画像処理をcanvasのように扱える node-canvas を使う人も多いのではないでしょうか。その方法は色々紹介されています。例えばこちらの記事など。
node.jsではてなブログ風アイキャッチ画像を動的に生成するこのnode-canvasですが、デフォルトでは絵文字は描画ができません。
今回は、node-canvasで、絵文字を Twemoji の見た目で描画するモジュールの紹介です。
node-canvasで絵文字を扱う
node module を npm で公開しておきました。
$ npm install --save node-canvas-with-emojiconst { createCanvas } = require('canvas'); const { fillTextWithTwemoji } = require('node-canvas-with-twemoji'); async function main () { const canvas = createCanvas(500, 300); const context = canvas.getContext('2d'); context.font = '30px Arial'; await fillTextWithTwemoji(context, '絵文字も描画?', 140, 160); } main();提供しているのは
fillTextWithTwemoji(context, text, x, y, options?)という関数です。
contextを渡す以外は、本家の CanvasRenderingContext2D.fillText のように扱えるようにしています。ただし、
fillTextWithTwemojiは非同期(Promise)で扱われるため、Promise や async/await も利用する必要があります。
(関数内で絵文字画像をダウンロードしているため)また、現時点(2020.03.01)ではイタリック書体や、maxWidth引数などに対応していません。
こちらで開発しているので何かあれば。 GitHub
スターがつくだけでもやる気が出て実装するかもしれません。雑記
Twemojiではなく、Apple Color Emojiなど、絵文字フォントを使う方法もあるようです。
- Any emoji support?
- Colored Emojiただし、こちらは著作権周りで、実際に使う場合は注意が必要です。
- 「絵文字」の利用で気をつけた方が良いこと、安全な使い方について雑記2
同じようなこと考えてる人もいました。
- node-canvas でカラー絵文字対応について考えてたこと
- 投稿日:2020-03-01T14:28:23+09:00
Node.js Expressフレームワークを使用する準備
はじめに
本格的な開発をするにはフレームワークを活用します。
フレームワークを活用することで効率よく、開発することが出来るようになります。今回は「Express」というフレームワークを採用しました。
Express Generatorのインストール
Expressを使用するには、Express Generatorを使用するのが便利です。
まず、Express Generatorをインストールします。
コマンドプロンプトを立ち上げで、以下のコマンドでインストールします。npm install express-generator - g上記コマンドはグローバルインストールと呼ばれるインストール方法になります。
Express Generatorはプログラム中で使用するものではありませんので、グルーバルな領域にインストールします。
ですので、コマンドを打つ場所(カレントフォルダ)はどこでも良いです。
- 投稿日:2020-03-01T14:28:23+09:00
Node.js Expressフレームワークを使用する為の準備作業
はじめに
本格的な開発をするにはフレームワークを活用します。
フレームワークを活用することで効率よく、開発することが出来るようになります。今回は「Express」というフレームワークを採用しました。
環境
OS:Windows 10 Pro 64bit
node.js:v12.16.1
npm:v6.13.4Express Generatorのインストール
Expressを使用するには、Express Generatorを使用するのが便利です。
まず、Express Generatorをインストールします。
コマンドプロンプトを立ち上げで、以下のコマンドでインストールします。npm install express-generator - g上記コマンドはグローバルインストールと呼ばれるインストール方法になります。
Express Generatorはプログラム中で使用するものではありませんので、グルーバルな領域にインストールします。
ですので、コマンドを打つ場所(カレントフォルダ)はどこでも良いです。確認
以下のコマンドでインストールされたか確認出来ます。
npm view express-generator version
- 投稿日:2020-03-01T12:45:52+09:00
node.jsでswitchbotの温湿度計データ取得
switchbotの温湿度計を購入したので、node.jsでデータを取得し、s3にアップロードしてみた。
データの取得
データの取得にはnobleを使用した。
nodeのv9以降では動かないようなので、v8系をインストールすること。
nobleの使い方は割愛。microbotの開発元?のOpenWonderLabsがAPI仕様を公開しているので、それを参照しながらデータを読み取る。
https://github.com/OpenWonderLabs/python-host/wiki/Meter-BLE-open-API
ビットの操作はとっても苦手なので、苦労した。
例えば、4バイト目の後ろ7ビットには温度のデータが入っているようなので、このようにして取得。const temperature = data.readUInt8(4) & 0x7f;&(ビット演算子)で0x7f(1111111)をビットANDして、後ろ7桁を切り出すらしい。
前3桁が欲しかったら、こんな感じで0xE0(11100000)をビットANDして、
さらにシフト演算子>>>(0埋めバージョン)で後ろ5桁を溢れさせる。var a = data.readUInt8(4) & 0xE0 >>> 5web開発ばっかりやってた人間としては、このあたりはとっても苦手な領域。
データが取れたら
fsでファイルに書き出す。
後で扱いやすいようにmoment.jsを使って日時分秒をファイル名にした。↓ソース全体(scan.js)
'use strict'; const noble = require('noble'); const fs = require('fs'); const moment = require('moment'); // living swithbot const MAC = "xxxxxxx"; // switchbotのmacアドレス const tmpDir = "/var/tmp/envdata/"; // データを保存したいディレクトリ noble.on('stateChange', (state) => { if (noble.state === 'poweredOn'){ noble.startScanning(); } else { noble.on('stateChange', scanStart); } }); noble.on('scanStart', () => { console.log('start scanning'); }); noble.on('scanStop', () => { console.log('stop scanning'); process.exit(0); }); noble.on('discover', (peripheral) => { if (peripheral.uuid === MAC) { noble.stopScanning(); const data = peripheral.advertisement.serviceData[0].data; const deviceType = data.slice(0, 1).toString('ascii'); const battery = data.readUInt8(2) & 0x7f; const temperature = data.readUInt8(4) & 0x7f; const humidity = data.readUInt8(5) & 0x7f; const time = moment().format('YYYY-MM-DD_HH:mm:ss'); const jsonData = { "datetime": time, "battery": battery, "temperature": temperature, "humidity": humidity }; // write to file fs.writeFileSync(tmpDir + time + '.log', JSON.stringify(jsonData)); noble.stopScanning(); } });s3へのアップロード
s3へのアップロードはいたって簡単です。
下準備
aws-sdkのライブラリをnpm installする。
AWSのIAMでアップロード用のユーザ作ってAmazonS3FullAccessのポリシー(uploadだけだったら権限絞ったポリシーで良い気もする)付けて、そのcredential情報をjsonファイルに書き出しておく。{ "accessKeyId": "xxxxxxxxxxxxx", "secretAccessKey": "xxxxxxxxxx" }こんな具合。
S3への接続
こんな感じでs3オブジェクトをセットアップ。
AWS.config.loadFromPath('/home/pi/.aws/credential.json'); // 保存したcredentialファイルのパスを指定 AWS.config.update({region: 'ap-northeast-1'}); const s3 = new AWS.S3();あとはアップロードしたいファイルの情報を整えて
s3.putObject()でアップロード。↓ソース(upload.js)
const AWS = require('aws-sdk'); const fs = require('fs'); AWS.config.loadFromPath('/home/pi/.aws/credential.json'); AWS.config.update({region: 'ap-northeast-1'}); const s3 = new AWS.S3(); const tmpdir = '/var/tmp/envdata/'; fs.readdir(tmpdir, (err, files) => { if (err) throw err; files.forEach( (file) => { var params = { Bucket: 'switchbot-room', Key: file }; params.Body = fs.readFileSync(tmpdir + file); s3.putObject(params, (err, data) => { if (err) throw err; fs.unlinkSync(tmpdir + file, (err) => { if (err) throw err; }); }); }); });自動起動設定
cron設定するだけ。
*/5 * * * * /usr/local/bin/node /home/pi/swithbot/scan.js */5 * * * * /usr/local/bin/node /home/pi/swithbot/upload.js5分間隔でデータを取得して、アップロード。
今のところ問題なくデータが上がってます。
NextAction
次は、上がったデータを可視化したい。
QuickSight, Mackerel, ES + Kibana どれでやろうか検討中。chart.js使って自分で作ってもいいけど、
一番費用が掛からない方法がいいな。
- 投稿日:2020-03-01T09:56:00+09:00
LamdbaからS3内のファイルを操作したい
LamdbaからS3内を操作するメソッドで、よく使うものをメモ書き。
まずaws-sdkをrequireし、リージョンを指定します。
AWS SDKとは、AWSサービスをプログラムから操作できる開発キットです。const AWS = require('aws-sdk'); const s3 = new AWS.S3({'region':'リージョン'});ファイル作成・更新
ファイルを作成するには、putObjectメソッドを使用します。
S3に'test'というバケットがあり、その配下のsampleフォルダに'sample.json'というJSONファイルを作成します。exports.handler = async (event) => { const putData = await s3.putObject( { Bucket:'test', Key:'sample/sample1.json', Body: JSON.stringify({}) }).promise() }Bucket...バケット名
Kye...バッケト以下/ファイル名
Body...JSONファイル内に書きたい内容実行すると、空のJSONファイルがS3に作成されます。
内容を記載したい場合はBodyのところに適当に入れます。
Body: JSON.stringify({name:'ai',age:20})実行すると、sample.jsonの中に
{"name":"ai","age":20}が追加されているのが確認できます。ファイル取得
S3のファイルを取得するには、getObjectメソッドを使います。
exports.handler = async (event) => { const data = await s3.getObject( { Bucket:'test', Key:'test/sample1.json' }).promise() const obj = JSON.parse(data.Body) console.log(obj.name,obj.age) //ai 20 }先ほどと同様に、取得したいファイルの情報をBucket,Keyに指定します。
JSONをparseしてオブジェクトに変換することで、中身にアクセスすることができます。ファイル削除
exports.handler = async (event) => { const deletes = await s3.deleteObject( { Bucket:'test', Key:'test/sample1.json' }).promise() }こちらも同様に削除したいファイルの情報をBucket、Keyに指定します。
実行すると、削除できたことが確認できます。
ちなみに、存在しないファイル名を指定した場合でもエラーにはなりません。
なのでtry~catchで囲み、エラーを出してくれるようにしてあげる必要があります。exports.handler = async (event) => { try { const deletes = await s3.deleteObject( { Bucket:'test', Key:'sample/sample1XXX.json' }).promise().catch(err=>{ throw new Error(err) }) } catch (err){ console.log(err) } } //実行結果 Error: NoSuchKey: The specified key does not exist.存在しないファイル名を指定して実行すると、エラーになることが確認できました。
データの一覧を取得する
S3にどんなファイルがあるか分からない時、listObjectsV2メソッドで確認することがきます。
exports.handler = async (event) => { const params = { 'Bucket':'test', 'Prefix':'sample', } const lists = await s3.listObjectsV2(params).promise() lists.Contents.forEach((a) => console.log(a.Key)) }実行すると、sampleフォルダ配下に何があるか確認できました。
実行結果sample/ sample/sample1.json sample/sample2.json sample/sample3.json
- 投稿日:2020-03-01T02:53:14+09:00
azure app service で kintone アプリデータ公開
kintone のアプリデータをazure app service で公開してみます。
概要
プラグインを購入いただいたお客様のサポートやプラグインのバージョンアップなどで、kintone アプリを使ってどうにか出来ないかと調べています。
kintone アプリデータを外部に公開する外部サービスがありますが、簡単にできる反面、いろいろ制約があったりします。
azure app service で、kintone アプリデータを外部に公開する試作をしてみます。環境
いつも使っている PC 環境で開発・テストして、azure へデプロイ。
開発環境
- Windows 10
- Visual source code
- node.js, Express, pug
- kintone JS SDK
azure環境
- east asia (東京)
開発準備
vscode, node, npm あたりがそろっていれば OK。
Express ジェネレーター
アプリ名を指定すれば、基本的な一式をそろえてくれる優れもの。
アプリ名 kintone-view-test1 で作ってみます。
$ mkdir webapp $ cd webapp $ npx express-generator kintone-view-test1 --view pug --git $ cd kintone-view-test1 $ npm install ...アプリケーションの実行
npm start すると、http://localhost:3000 で参照できます。
CTL+C で、終了。$ npm startアプリケーションのデバッグ
vscode で、デバッグが出来るのがうれしい。
下記で、 wwww ファイルを起点とした設定が出来ます。
- vscode で、kintone-view-test1\bin\www を開きます。
- vscode の「デバッグと実行」をクリック
- 「lunch.json ファイルを作成します。」をクリック
- 「Node.js の実行とデバッグ(F5)」をクリック
- ブレークポイント
- index.js にブレークポイントを設定
ブラウザから、http://localhost:3000 で参照
ブレークポイントで停止中は、変数にカーソルを当てると内容が表示されます
アプリケーションのデプロイ
azure 環境へ、デプロイしてみます。
azure のアカウントを持っていて、以前からvscode で開発していれば、「Deploy to web app」をクリックするとデプロイが始まります。
あとは、順番に node.js のバージョン等を指定します。
kintone アプリのレコード取得を組み込み
ここまでの作業で、azure 上でアプリを動作することが出来ました。
いよいよ kintone アプリのレコードを取得して、公開してみます。kintone JS SDK のインストール
$ cd kintone-view-test1 $ npm install --save @kintone/kintone-js-sdk@v0.6.1app.js の変更
とりあえず、kintone アプリレコードの照会画面用に、app.js 等を変更していきます。
「/customer」の URL でアクセスされたら、kintone の顧客アプリを表示するイメージです。
既存の「/users」と同じように処理を追加します。app.jsvar createError = require('http-errors'); var express = require('express'); var path = require('path'); var cookieParser = require('cookie-parser'); var logger = require('morgan'); var indexRouter = require('./routes/index'); var usersRouter = require('./routes/users'); var customerRouter = require('./routes/customer'); var app = express(); // view engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'pug'); app.use(logger('dev')); app.use(express.json()); app.use(express.urlencoded({ extended: false })); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); app.use('/', indexRouter); app.use('/users', usersRouter); app.use('/customer', usersRouter); // catch 404 and forward to error handler app.use(function(req, res, next) { next(createError(404)); }); // error handler app.use(function(err, req, res, next) { // set locals, only providing error in development res.locals.message = err.message; res.locals.error = req.app.get('env') === 'development' ? err : {}; // render the error page res.status(err.status || 500); res.render('error'); }); module.exports = app;index.pug
index から、顧客一覧へのリンクを追加しておきます。
index.pubextends layout block content h1= title p Welcome to #{title} br a(href="./customer", title="顧客一覧") 顧客一覧customer.js
アプリIDやURLなどは、開発用・本番用で切り替えが必要のので
kintone 接続用の情報は、モジュール化してまとめたほうがよさそうです。customer.jsvar express = require('express'); var router = express.Router(); const kintone = require('@kintone/kintone-js-sdk'); /* GET customers listing. */ router.get('/', function (req, res, next) { const kintoneAuth = new kintone.Auth(); const username = 'xxxxxxxxx'; const password = 'xxxxxxxxx'; kintoneAuth.setPasswordAuth({ username: username, password: password }); const domainName = 'xxxxxxxxx.cybozu.com'; const kintoneConnection = new kintone.Connection({ domain: domainName, auth: kintoneAuth }); const kintoneRecord = new kintone.Record({ connection: kintoneConnection }); const finfos = [ { label: '会社名', fcode: '会社名'}, { label: '担当者名', fcode: '担当者名' }, { label: 'メールアドレス', fcode: 'メールアドレス' } ]; const fields = finfos.map((finfo) => { return finfo.fcode; }); const appId = 549; // target appID const parm = { app: appId, query: 'order by $id', fields: fields }; kintoneRecord.getRecords(parm).then((rsp) => { console.log('rsp', rsp); res.render('customer', { title: '顧客一覧', finfos: finfos, records: rsp.records }); }).catch((err) => { // The promise function always reject with KintoneAPIExeption console.log(err.get()); // res.render('forum', { title: 'rex0220 forum', user: 'error' }); }); }); module.exports = router;customer.pug
顧客一覧用のテンプレートです。
単純なテーブル構造だと簡単ですが、データ量が多くページ制御等があると少し面倒なので、グリッドライブラリを使ったほうがいいかもしれません。customer.pugextends layout block content h1= title table(class="xp-customer-list") thead each finfo in finfos th #{finfo.label} tbody each rec in records tr each finfo in finfos td #{rec[finfo.fcode].value}style sheet
顧客一覧用に少し手直し
見映えをよくする場合は、地道に手直し。style.cssbody { padding: 50px; font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; } a { color: #00B7FF; } .xp-customer-list { background-color: aqua; width: 700px; font-size: 14px; } .xp-customer-list thead { background-color: azure; }取得結果
素のテーブルだけだと、いまいち。
azure へデプロイ
初回と同様に「Deploy to web app」をクリックすると、デプロイされます。
2回目以降は、入力なしにそのまま続行します。azure app service のログ
vscode から azure app service のログを確認できます。
console.log で、kintone レコードを出力したのが、表示されています。
保守・運用のことも考慮して、必要な情報を見やすくログに残したいですね。カスタムドメインでの公開
azure app service 内で、カスタムドメインの購入・割り当てが可能です。
チュートリアルに従って、手順を進めるだけなので簡単です。
お手軽に kintone アプリデータを一般に公開できますね。参考サイト
あとがき
vscode でデバッグ出来るのが、一番うれしい。
azure へのデプロイも vscode から簡単に実行できる。
Express の構成に慣れれば、開発が楽かもしれません。
- 投稿日:2020-03-01T02:53:14+09:00
azure app service で kintone アプリデータ公開その1
kintone のアプリデータをazure app service で公開してみます。
概要
プラグインを購入いただいたお客様のサポートやプラグインのバージョンアップなどで、kintone アプリを使ってどうにか出来ないかと調べています。
kintone アプリデータを外部に公開する外部サービスがありますが、簡単にできる反面、いろいろ制約があったりします。
azure app service で、kintone アプリデータを外部に公開する試作をしてみます。
- azure app service で kintone アプリデータ公開その1
- azure app service で kintone アプリデータ公開その2(環境変数利用)
- azure app service で kintone アプリデータ公開その3(REST API)
- azure app service で kintone アプリデータ公開その4(JS API)
- azure app service で kintone アプリデータ公開その5(グリッド表示)
こんな感じで、しくみを試作します。
環境
いつも使っている PC 環境で開発・テストして、azure へデプロイ。
開発環境
- Windows 10
- Visual source code
- node.js, Express, pug
- kintone JS SDK
azure環境
- east asia (東京)
開発準備
vscode, node, npm あたりがそろっていれば OK。
Express ジェネレーター
アプリ名を指定すれば、基本的な一式をそろえてくれる優れもの。
アプリ名 kintone-view-test1 で作ってみます。
$ mkdir webapp $ cd webapp $ npx express-generator kintone-view-test1 --view pug --git $ cd kintone-view-test1 $ npm install ...アプリケーションの実行
npm start すると、http://localhost:3000 で参照できます。
CTL+C で、終了。$ npm startアプリケーションのデバッグ
vscode で、デバッグが出来るのがうれしい。
下記で、 wwww ファイルを起点とした設定が出来ます。
- vscode で、kintone-view-test1\bin\www を開きます。
- vscode の「デバッグと実行」をクリック
- 「lunch.json ファイルを作成します。」をクリック
- 「Node.js の実行とデバッグ(F5)」をクリック
- ブレークポイント
- index.js にブレークポイントを設定
ブラウザから、http://localhost:3000 で参照
ブレークポイントで停止中は、変数にカーソルを当てると内容が表示されます
アプリケーションのデプロイ
azure 環境へ、デプロイしてみます。
azure のアカウントを持っていて、以前からvscode で開発していれば、「Deploy to web app」をクリックするとデプロイが始まります。
あとは、順番に node.js のバージョン等を指定します。
kintone アプリのレコード取得を組み込み
ここまでの作業で、azure 上でアプリを動作することが出来ました。
いよいよ kintone アプリのレコードを取得して、公開してみます。kintone JS SDK のインストール
$ cd kintone-view-test1 $ npm install --save @kintone/kintone-js-sdk@v0.6.1app.js の変更
とりあえず、kintone アプリレコードの照会画面用に、app.js 等を変更していきます。
「/customer」の URL でアクセスされたら、kintone の顧客アプリを表示するイメージです。
既存の「/users」と同じように処理を追加します。app.jsvar createError = require('http-errors'); var express = require('express'); var path = require('path'); var cookieParser = require('cookie-parser'); var logger = require('morgan'); var indexRouter = require('./routes/index'); var usersRouter = require('./routes/users'); var customerRouter = require('./routes/customer'); var app = express(); // view engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'pug'); app.use(logger('dev')); app.use(express.json()); app.use(express.urlencoded({ extended: false })); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); app.use('/', indexRouter); app.use('/users', usersRouter); app.use('/customer', usersRouter); // catch 404 and forward to error handler app.use(function(req, res, next) { next(createError(404)); }); // error handler app.use(function(err, req, res, next) { // set locals, only providing error in development res.locals.message = err.message; res.locals.error = req.app.get('env') === 'development' ? err : {}; // render the error page res.status(err.status || 500); res.render('error'); }); module.exports = app;index.pug
index から、顧客一覧へのリンクを追加しておきます。
index.pubextends layout block content h1= title p Welcome to #{title} br a(href="./customer", title="顧客一覧") 顧客一覧customer.js
アプリIDやURLなどは、開発用・本番用で切り替えが必要のので
kintone 接続用の情報は、モジュール化してまとめたほうがよさそうです。customer.jsvar express = require('express'); var router = express.Router(); const kintone = require('@kintone/kintone-js-sdk'); /* GET customers listing. */ router.get('/', function (req, res, next) { const kintoneAuth = new kintone.Auth(); const username = 'xxxxxxxxx'; const password = 'xxxxxxxxx'; kintoneAuth.setPasswordAuth({ username: username, password: password }); const domainName = 'xxxxxxxxx.cybozu.com'; const kintoneConnection = new kintone.Connection({ domain: domainName, auth: kintoneAuth }); const kintoneRecord = new kintone.Record({ connection: kintoneConnection }); const finfos = [ { label: '会社名', fcode: '会社名'}, { label: '担当者名', fcode: '担当者名' }, { label: 'メールアドレス', fcode: 'メールアドレス' } ]; const fields = finfos.map((finfo) => { return finfo.fcode; }); const appId = 549; // target appID const parm = { app: appId, query: 'order by $id', fields: fields }; kintoneRecord.getRecords(parm).then((rsp) => { console.log('rsp', rsp); res.render('customer', { title: '顧客一覧', finfos: finfos, records: rsp.records }); }).catch((err) => { // The promise function always reject with KintoneAPIExeption console.log(err.get()); // res.render('forum', { title: 'rex0220 forum', user: 'error' }); }); }); module.exports = router;customer.pug
顧客一覧用のテンプレートです。
単純なテーブル構造だと簡単ですが、データ量が多くページ制御等があると少し面倒なので、グリッドライブラリを使ったほうがいいかもしれません。customer.pugextends layout block content h1= title table(class="xp-customer-list") thead each finfo in finfos th #{finfo.label} tbody each rec in records tr each finfo in finfos td #{rec[finfo.fcode].value}style sheet
顧客一覧用に少し手直し
見映えをよくする場合は、地道に手直し。style.cssbody { padding: 50px; font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; } a { color: #00B7FF; } .xp-customer-list { background-color: aqua; width: 700px; font-size: 14px; } .xp-customer-list thead { background-color: azure; }取得結果
素のテーブルだけだと、いまいち。
azure へデプロイ
初回と同様に「Deploy to web app」をクリックすると、デプロイされます。
2回目以降は、入力なしにそのまま続行します。azure app service のログ
vscode から azure app service のログを確認できます。
console.log で、kintone レコードを出力したのが、表示されています。
保守・運用のことも考慮して、必要な情報を見やすくログに残したいですね。カスタムドメインでの公開
azure app service 内で、カスタムドメインの購入・割り当てが可能です。
チュートリアルに従って、手順を進めるだけなので簡単です。
お手軽に kintone アプリデータを一般に公開できますね。参考サイト
あとがき
vscode でデバッグ出来るのが、一番うれしい。
azure へのデプロイも vscode から簡単に実行できる。
Express の構成に慣れれば、開発が楽かもしれません。
























