On Github masakura / kintone-cafe-handson
「kintone API でアプリを作って Arukas で動かしてみよう!」
2016/6/11 (土)
政倉 智
本日はこんな感じのハンズオンをやります!
kintone アプリで受注管理 kintone API でオンラインショップ開発 Arukas でオンラインショップを公開ハンズオンを開始する前に、教材をダウンロード
GitHub にあるので、フォークして WebStorm で開く
GitHub にある教材にアクセス https://github.com/masakura/taniyama-shopping
右上の Fork ボタンをクリック
URL や左上のユーザー名があなたになっていることを確認
あなただけの作業スペースになるので、失敗しても OK
Clone or download をクリックして URL をコピー
git@github... でピンとこない方は Use HTTPS をクリック
Web Storm を起動する
こんな感じでエディターが表示された方は File -> Close Project で閉じてね!
Check out from Version Control をクリックし、Git を選択
Git Repository URL にコピーした URL をペーストして Clone ボタンをクリック
Yes をクリック
左下のアイコンをクリック
左端の 1: Project をクリック
▶ をクリックしてプロジェクトファイル一覧を開く
準備完了!
プログラミングせずに作れる
kintoneは特別なスキルがなくても大丈夫。 どなたでもカンタンにアプリが作れます。
今回作るアプリの構成はこんな感じ
まずは kintone アプリから
WebStorm で取得した教材から、オンラインショップのスペーステンプレートを読み込みます
スペースは kintone アプリを複数取り扱うことができる便利な空間です
kintone 環境を開きます
https://xxxxxx.cybozu.com/ こんな URL が来てませんか?
ログイン名とパスワードを入力し、ログイン ボタンをクリック
kintone をクリック
右上の歯車アイコンをクリックし、kintone システム管理を選択
スペースのスペーステンプレートをクリック
読み込むをクリック
参照 ボタンをクリック
taniyama-shopping/kintone/onlineshop.sptpl を開く
読み込むボタンをクリック
スペーステンプレートが読み込まれた!
読み込んだテンプレートを使ってショップスペースを作成します
まずはホームへ移動
+ 作成ボタンをクリックしスペースを作成を選択
オンラインショップを選択
スペースができて、アプリもインポートされた!
オンラインショップに掲載する商品を登録します
商品管理 をクリック
+ ボタンをクリック
商品コード・商品名・金額を入力して保存ボタンをクリック
画像 URI はお好みで (https:// がいいと思う...)
商品が追加できた! 何点か登録してね!
一覧に戻るにはパンくずリストの商品管理をクリック
こんどは注文を登録します
パンくずリストのオンラインショップをクリック
受注管理をクリック
+ ボタンで注文を追加
注文情報を入力する
+ で商品を追加できる
保存ボタンクリックで保存
ステータス: 入金待ちなのを確認! 確認だけよ!
ボタン押さないでね!
注文登録完了!
注文を一覧で、形式を変えて見てみます
パンくずリストの受注管理をクリック
一覧が受注一覧の時は全注文を表示
一覧はいろいろと選べる
入金待ち一覧にすると注文が表示される
発送待ち一覧にすると注文は表示されない
注文は入金待ちなので、発送待ちではない
次は入金確認
(事務員に気持ちになって) 入金を確認します
一覧を入金待ちにする
注文の左のボタンをクリック
入金確認しましたボタンをクリックし、実行を選択
ステータス: 発送待ちに変化!
パンくずリストの絞り込みをクリックして入金待ち一覧に戻る
入金が確認されたので一覧からは消えている!
発送待ち一覧には表示される
次は発送
入金と同じように発送もできる
発送しましたボタンをクリック
ステータス: 発送完了に
一覧発送待ちから消えた!
発送もできた!
次はここを作ります!
でも、本日は Express のハンズオンではないので、コピペです!
本日は kintone API を使った開発のハンズオンですので!
プログラムを書き始める前に、kintone API の仕様をおさえる
REST API の仕様は丁寧に公式ドキュメントが丁寧でいい感じ
REST API の前に、kintone のアプリの URL の読み方を覚える
項目 意味 サブドメイン あなたの kintone 環境で固有のものです アプリ ID アプリごとの ID で、商品管理と受注管理で違いますkintone アプリの URL https://7nkse.cybozu.com/k/21/ ~~~~~ ~~ サブドメイン アプリ ID
すべてのレコードを取得
kintone アプリの URL https://7nkse.cybozu.com/k/34/ ~~~~~ ~~ サブドメイン アプリ ID アプリのすべてのレコードを取得 (GET) https://7nkse.cybozu.com/k/v1/records.json?app=34 ~~~~~ ~~ サブドメイン アプリ ID
ID を複数指定して取得
kintone アプリの URL https://7nkse.cybozu.com/k/34/ ~~~~~ ~~ サブドメイン アプリ ID アプリのすべてのレコードを取得 (GET) https://7nkse.cybozu.com/k/v1/records.json?app=34&query=%24id%20in%20(1%2C2%2C3) ~~~~~ ~~ ~~~~~~~~~~~~~~~~~~~~~ サブドメイン アプリ ID 条件
id%20in%20(1%2C2%2C3) は $id in (1,2,3) を URL エンコードしたもの
レコードを一件取得
kintone アプリの URL https://7nkse.cybozu.com/k/34/ ~~~~~ ~~ サブドメイン アプリ ID アプリから ID が 1 のレコードを取得 (GET) https://7nkse.cybozu.com/k/v1/record.json?app=34&id=1 ~~~~~ ~~ ~ サブドメイン アプリ ID レコード ID
今回は使いません!
詳しくは公式ドキュメントを!
API を呼び出すためのトークンを取得します
商品管理アプリを開く
歯車アイコンをクリックし、このアプリの設定を選択
下の方にある詳細設定をクリック
下の方にある API トークンをクリック
生成するボタンをクリックして API トークンを生成
レコード閲覧のみがチェックされていることを確認する
生成された API トークンとアプリ ID をセットで記録しておいてください
保存ボタンで保存します
右上の設定完了ボタンで運用環境に反映
受注管理アプリでも同じように! (レコード追加だけをチェック)
API トークンとアプリ ID を組で記録しておくのを忘れないように!
API トークンの取得が完了しました
次は実際に呼び出してみます
API トークンを使って REST API を呼び出すためには X-Cybozu-API-Token: {API トークン} を HTTP ヘッダに含めます
Google Chrome の DHC アプリを使って試しに呼び出してみる
慣れてる人は curl 使おう!
Chrome DHC で検索して DHC アプリを Chrome にインストール
https://chrome.google.com/webstore/detail/dhc-rest-client/aejoelaoggembcahagimdiliamlcdmfm
Chrome のアドレスバーに chrome://apps を入力し、DHC を選択
REQUEST に商品管理アプリにアクセスする URL を入力する
https://{サブドメイン}.cybozu.com/v1/records.json?app={アプリ ID}
+ ボタンをクリックしてヘッダーを追加
GET なのを確認して Send をクリック!
Open ボタンをクリックし、下へスクロールするとデータが見られる
データはこんな感じ
{ "records": [ { "$id": { "type": "__ID__", "value": "1" }, "code": { "type": "SINGLE_LINE_TEXT", // フィールドの型 "value": "ITEM001" // 値 }, /* ... */ } /* ... */ ], "totalCount": null }
一般的な (かどうかは微妙だけど) シンプルなデータ
ちょっと違うので注意。
[ { "$id": "1", "code": "ITEM001", // 値のみ /* ... */ }, /* ... */ ]
うまく行かなかった人は以下を見なおしてね!
プロジェクトを実行するための設定を WebStorm に行う
必要なライブラリのインストール 環境変数に kintone 環境やアクセストークンを設定package.json を右クリックから Run 'npm install' を選択し、ライブラリをインストール (ちょっと時間かかる)
インストールが終わったら同じく package.json をクリックして Show npm Scripts を選択
taniyama-shoppings/package.json を右クリックし、npm Settings... を選択
Node Interpriter に Node v6 を設定
環境変数を設定するため ... をクリック
+ ボタンをクリックして Name に KINTONE_BASE を、Value に https://{サブドメイン}.cybozu.com/k/v1/ を入力
以下を全部入力
名前 値 KINTONE_BASE kintone 環境の URL KINTONE_APP_ITEMS_ID 商品管理アプリ ID KINTONE_APP_ITEMS_TOKEN 商品管理アプリのトークン KINTONE_APP_ORDERS_ID 受注管理アプリ ID KINTONE_APP_ORDERS_TOKEN 受注管理アプリのトークン DEBUG onlineshop:*すべて入力したら OK ボタンで保存
OK ボタンをクリックして設定を保存
以上で設定完了!
オンラインショップアプリを実行する
npm ウインドウの start をダブルクリック! ウェブブラウザーで http://localhost:3000 にアクセス!npm ウインドウの start をダブルクリック!
http://localhost:3000 にアクセス!
入力した商品が表示されない!
まだ kintone API を呼び出してません...
今から実装していきます!
大まかなファイル構成
ファイル 目的 views/*.ejs HTML テンプレート routes/*.js ルーター JS libs/*.js kintone API との通信 JSHTML テンプレート、<% for とか <%= item.name %> とかに注目
<!-- views/index.html --> <div class="container"> <div class="row"> <% for (const item of items) { %> <div class="col-xs-12 col-sm-6 col-md-4"> <div class="card app-item"> <img src="<%= item.imageUri %>" alt="" class="card-img-top img-fluid"> <div class="card-block"> <h4 class="card-title"><%= item.name %></h4> <p class="card-text"> <%= item.summary %> </p> </div>
ビューではこんなデータの配列を表示している
名前 目的 item.id 商品 ID item.code 商品コード item.name 商品名 item.summary 説明 item.price 価格商品一覧を表示するルーター
itemService から商品一覧を取得してテンプレートに渡している
// routes/index.js /* GET home page. */ router.get('/', (req, res) => { const itemsService = new ItemsService(req); itemsService.getItems() .then(items => res.render('index', { title: 'たにやまショッピング', items})); }); module.exports = router;
kintone API との通信 JS ファイル
環境変数から kintone API にアクセスする情報を取得
// libs/itemsService.js /** * kintone API を呼び出すための情報。 */ const kintoneApp = { // ex: https://7nkse.cybozu.com/k/v1/ base: process.env['KINTONE_BASE'], // ex: 21 id: process.env['KINTONE_APP_ITEMS_ID'], token: process.env['KINTONE_APP_ITEMS_TOKEN'] };
kintone API との通信 JS ファイル
まだ通信しておらず、ダミーデータを返すだけ
// libs/itemsService.js class ItemsService { getItems(ids) { return Promise.resolve([ { id: 1, code: 'DUMMY001', name: 'ダミー商品', summary: 'ダミーの商品', price: 1280 } ]); } }
本日はこのメソッドを実装します
商品管理アプリから商品一覧を取り出す実装を書く
通信をとりあえず書いてみる (通信結果は捨ててる)
// libs/itemsService.js getItems(ids) { const uri = `${kintoneApp.base}records.json?app=${kintoneApp.id}`; debug(`GET ${uri}`); return fetch(uri, { agent, headers: { 'X-Cybozu-API-Token': kintoneApp.token } }) .then(res => res.json()) .then(data => { debug(data); return [{id: 1, name: 'ダミー商品', summary: 'ダミーの商品', price: 1280}] }, debug); }
fetch 関数は XMLHttpRequest に変わる新しい API で、戻り値は Promise
ServiceWorker とかはこっちしか使えない
今回使ったのは Node.js 用の Polyfill の node-fetch
Promise は非同期をサポートする ECMAScript 6 の機能
fetch('...') .then(res => { /* 正常終了時はここが呼び出される */ return res; }, error => { /* 異常終了時はここが呼び出される */ return error }) .catch(error => { /*エラー時はここも呼び出される */ });
バッククォートで囲まれたところは変数展開可能にする ECMAScript 6 の機能
const name = 'abc'; // Hello, Mr. abc. console.log(`Hello, Mr. ${name}.`);
その他...
再実行する
通信はしたけど結果を変えてないのでリロードしても見た目は変わりません
コンソールに通信結果が表示されています
ビューに表示できるようデータを変換するコードを挿入
// libs/itemsService.js .then(res => res.json()) .then(data => { debug(data); // データがないとき records プロパティがないので対策 const records = data.records || []; // 商品情報の形式を、kintone の形式から表示に適した形式に変換する。 const items = records .map(row => ({ /* ここに変換コードを書く */ })); // ID 順でソート items.sort((a, b) => a.id - b.id); return items; }, debug);
変換コードを追加する
// libs/itemsService.js // 商品情報の形式を、kintone の形式から表示に適した形式に変換する。 const items = records .map(row => ({ id: row.レコード番号.value, code: row.code.value, name: row.name.value, price: row.price.value, imageUri: row.imageUri.value || '//placehold.it/640x340?text=no image', summary: row.summary.value }));
修正後に WebStorm でリロードし、ブラウザーをリロードすると...
きたーーー!
商品一覧の取得はカートや注文の登録でも使われます
このとき、指定された商品 ID のデータのみを取得する必要がありますので、こちらを実装します
引数 ids があった時は、フィルタがかかるように
// libs/itemsService.js getItems(ids) { // レコード ID が指定されていた場合は、そのレコード ID のみ取得する。 let params = ''; if (ids) { const query = encodeURIComponent(`$id in (${ids.join(',')})`); params += `&query=${query}`; } const uri = `${kintoneApp.base}records.json?app=${kintoneApp.id}${params}`; debug(`GET ${uri}`);
WebStorm とブラウザーをリロードして商品をカートに入れると...
きたああああああ!
注文を登録する実装もやろうと思ったけど...
時間がなさそうなのでなしで! できてます!
libs/ordersService.jsがそれです!
間違いがなければ受注管理アプリに注文が入っています!
購入手続きへ進むをクリック
適当に入力して購入するボタンをクリック
kintone で確認すると注文が!
管理やフローが必要なところを kintone でさくっと作って、お客さんに動作確認や調整をしてもらいつつ、ウェブアプリで機能を補完するという開発は非常に面白かった!
今回の REST API 以外にも、JavaScript によるアプリのカスタマイズや他のサービスの API の呼び出しとかもできるようなので、夢が広がる!
Arukas is the simplest-to-use Container-as-a-service that makes it easy to deploy and manage apps at scale.
Build, Ship, Run
An open platform for distributed applications for developers and sysadmins
アプリを配置するときはこんな感じ
OS・ミドルウェア・アプリ全てをパッケージングして配布したい!
これを叶えるのが Docker!
OVF (VMware とかのエクスポート) でもできるんですが...
用語はこんな感じ (らしい)
名前 意味 Docker Engine コンテナをたくさん実行する環境 Docker Image コンテナで動作させるイメージ Docker Container 実行単位 Docker Hub イメージを (like GitHub) 管理する場所Ship better code, faster.
The modern continuous integration and delivery platform that software teams love to use.
CircleCI の自動ビルドの設定を行います
CircleCI と GutHub のアカウント連携 CircleCI でプロジェクト設定をするhttps://circleci.com/ にアクセス!
Sign Up For Free ボタンをクリック
Authorize With GitHub ボタンをクリック
Username と Password を入力して Sign in ボタンをクリック
Authorize application ボタンをクリック
ダッシュボードが表示される!
多分、みんなはプロジェクトがないので画面違うと思う
アカウント連携は完了!
次は、プロジェクト設定
Add Projects ボタンをクリック
自分のアカウントを選択して taniyama-shopping の Build project ボタンをクリック
ビルドが走り出します!
しかしプロジェクト設定がまだなので失敗!
Project settings をクリック
Environment Variables をクリック
Name に DOCKER_EMAIL をValue に Docker Hub に登録したメールアドレスを入力し、Save variables ボタンをクリック
同じ手順で Docker Hub アカウントを環境変数を登録
Name Value DOCKER_EMAIL メールアドレス DOCKER_USER Docker ID DOCKER_PASS パスワードこんな感じ
以上で CircleCI プロジェクトの設定まで完了!
dependencies: override: - docker build -t $DOCKER_USER/shopping:`git rev-parse --short HEAD` .
deployment: hub: commands: - docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS - docker push $DOCKER_USER/shopping:`git rev-parse --short HEAD`
FROM node:6
ENV APP_HOME /app WORKDIR ${APP_HOME}
ADD package.json package.json RUN npm install --no-progress && rm -rf /root/.npm
ADD app.js app.js ADD bin bin ADD libs libs ADD public public ADD routes routes ADD views views
EXPOSE 3000/tcp
ENTRYPOINT npm start
CircleCI でビルドするには、GitHub に変更を Push するだけ!
WebStorm の Commit Changes ボタンをクリック (矢印が上を向いている方)
Commit Message を適当に入力して Commit ボタンの上にマウスカーソルを置いて、Commit and Push... をクリック
レビューをするかと聞かれるけど、今回は無視して Commit ボタンをクリック
Push ボタンをクリック
GitHub の Username とパスワードを入力して、OK ボタンをクリック
マスターパスワードの設定は今回はキャンセル
CircleCI に戻って View taniyama-shopping をクリック
Running をクリックしてビルドの確認
しばらく待つと、成功するはずです (FIXED じゃないかも)
5 分くらいかな?
Docker Hub にイメージが Push されているはずなので、
確認をする
https://hub.docker.com/ にアクセスし、Log In ボタンをクリック
Docker Hub の Username とパスワードを入力して Log In ボタンをクリック
イメージがあった! ので DETAILS ボタンクリックで詳細を確認
Tags をクリック
イメージ名とタグをどこかにか記録してください
イメージ名は {Docker ID}/shopping:{tag} になる
例: masakura/shopping:a2ebd1b
Docker Hub にイメージが Push されたらあともうちょっと!
Arukas で動かすのはとても簡単!
まずは Arukas アカウントを取得する アプリを作るArukas は CirlceCI と同じで GitHub 連携できるので簡単!
ダッシュボードが表示されたら完了
あともうちょっと!
Arukas でアプリを作って公開します
新しいアプリケーションを作成 ボタンをクリック
こんな感じで入力
指定する をチェックし、+ ボタンで環境変数を入力
WebStorm で設定したものと一緒!
名前 値 KINTONE_BASE kintone 環境の URL KINTONE_APP_ITEMS_ID 商品管理アプリ ID KINTONE_APP_ITEMS_TOKEN 商品管理アプリのトークン KINTONE_APP_ORDERS_ID 受注管理アプリ ID KINTONE_APP_ORDERS_TOKEN 受注管理アプリのトークンアプリケーションを作成でアプリを作成!
作成された shopping をクリック
起動 ボタンをクリックして OK を選択し、コンテナを起動
デプロイ中のまましばらく待つ (五分くらい?)
起動したので Endpoint をクリック
きたああああ!
これで Arukas に配置が完了です!
おまけ
itemsService.getItems() .then(items => res.render('index', { title: '書き換えました!', items})); // ~~~~~~~~~~~~~~~ ここを修正する
昔からの夢だった Blue-Green Deployment がこんなに簡単にできるとは思いませんでした!
今回はハンズオンのための構成だけど、実際はこんな感じになるんじゃないかな?
あまり話すとボロが出るのでこの辺で! (笑)
おつかれさまでした!