SlideShare a Scribd company logo
1 of 91
EWD 3
トレーニング・コース #31
ewd-xpress で Web および REST
サービスを作る
M/Gateway Developments Ltd.
Rob Tweed
訳: 日本ダイナシステム株式会社 嶋 芳成
GT.M版編集: 澤田 潔
※ 本稿オリジナルはCache’向けとして編纂
RESTのための EWD 3 バックエンド
• 2つのアプローチが可能
• EWD 3 モジュールを用いて自分の REST を構築する
• ewd-xpress を拡張する
2016/9/9 EWD 3 トレーニング・コース #31 2
RESTのための EWD 3 バックエンド
• EWD 3 モジュールを用いて独自のRESTを構築する
• 例えば ewd-qoper8-vistapc がどのように作られたか
• 利点
• EWD 3 の部品の内、本当に必要なものだけを利用し、構造を最
適化することができます
• 互換性の問題を考えずに、サード・パーティのモジュールを容易に加
えることができます
• 欠点
• EWD 3 の部品のインターフェースや統合方法について、十分に理
解している必要があります
2016/9/9 EWD 3 トレーニング・コース #31 3
RESTのための EWD 3 バックエンド
• ewd-xpress を拡張する
• 利点
• 既に必要なものはすべてインストールされ、正しくインターフェースさ
れ構成されているのでそれを利用できます
• 実際には、他のサード・パーティのモジュールは、非互換性の恐れを
あまり考えずに追加することができます
• 単一のバックエンドで、Web/RESTサービスと対話的なアプリケー
ションを同時にサポートできます
• 欠点
• REST/Webサービスのみが必要の場合、対話的なアプリケーショ
ン用のコードは利用されません... しかしこれは大したことではない
でしょう!
2016/9/9 EWD 3 トレーニング・コース #31 4
RESTサービスのための ewd-xpress
• 従って、ほとんどの場合、REST/Webサービスを作る
には ewd-xpress を用いるのが最善です
2016/9/9 EWD 3 トレーニング・コース #31 5
ewd-xpress の起動ファイルの例
var config = {
managementPassword: 'keepThisSecret!',
serverName: 'My EWD Server',
port: 8080,
poolSize: 2,
database: {
type: ‘gtm',
params: {
// snip
}
}
};
var ewdXpress = require('ewd-xpress').master;
ewdXpress.start(config)
2016/9/9 EWD 3 トレーニング・コース #31 6
Express ミドルウェアを利用する必要性
• REST/Webサービスをサポートする要点は、ミドル
ウェアの Express を追加することです
• REST/Web サービスは HTTP(S) 要求と応答を用いま
す
• Express は特定の URL パスの前方部分を監視する必
要があります
• 対応する要求が来たときには、それを処理するためワー
カー・プロセスに渡す必要があります
2016/9/9 EWD 3 トレーニング・コース #31 7
Express ミドルウェアを利用する必要性
• EWD 3 にはそのようなモジュールが既に用意してあり
ます
• ewd-qoper8-express
• これは ewd-qoper8 を統合する組み込みのルータを含み
ます
• ewd-xpress はそれを含んでおり、Ajaxメッセージの
ためにそれを用いています
• REST/Webサービスにおいて直接それを利用するこ
とはありません
• しかし、直接利用することもできます
2016/9/9 EWD 3 トレーニング・コース #31 8
ewd-xpress の起動ファイル
var config = {
managementPassword: 'keepThisSecret!',
serverName: 'My EWD Server',
port: 8080,
poolSize: 2,
database: {
type: ‘gtm',
params: {
// snip
}
}
};
var ewdXpress = require('ewd-xpress').master;
var exprss = ewdXpress.intercept();
ewdXpress.start(config)
2016/9/9 EWD 3 トレーニング・コース #31 9
ewd-xpress の起動ファイル
var config = {
managementPassword: 'keepThisSecret!',
serverName: 'My EWD Server',
port: 8080,
poolSize: 2,
database: {
type: ‘gtm',
params: {
// snip
}
}
};
var ewdXpress = require('ewd-xpress').master;
var exprss = ewdXpress.intercept();
// これで、次のものにアクセスできるようになります
// ewd-qoper8 object: exprss.q
// ewd-qoper8-xpress: exprss.qx
// Express middleware: exprss.app
ewdXpress.start(config)
2016/9/9 EWD 3 トレーニング・コース #31 10
単純な Web サービス
var config = {
managementPassword: 'keepThisSecret!',
serverName: 'My EWD Server',
port: 8080,
poolSize: 2,
database: {
type: ‘gtm',
params: {
// snip
}
}
};
var ewdXpress = require('ewd-xpress').master;
var exprss = ewdXpress.intercept();
exprss.app.use('/testWebService', exprss.qx.router());
ewdXpress.start(config)
2016/9/9 EWD 3 トレーニング・コース #31 11
単純な Web サービス
var config = {
managementPassword: 'keepThisSecret!',
serverName: 'My EWD Server',
port: 8080,
poolSize: 2,
database: {
type: ‘gtm',
params: {
// snip
}
}
};
var ewdXpress = require('ewd-xpress').master;
var exprss = ewdXpress.intercept();
exprss.app.use('/testWebService', exprss.qx.router());
// 「/testWebService」 で始まるURLのリクエストを受信すると、それをワーカーに渡し
// 「testWebService」 という名前のモジュールで処理します
ewdXpress.start(config)
2016/9/9 EWD 3 トレーニング・コース #31 12
試してみましょう
2016/9/9 EWD 3 トレーニング・コース #31 13
適切な HTTP クライアントを利用する
• ブラウザは、GET要求をテストすることしかできません
• POST や他の要求 (例えば DELETE、PUT) をテストす
る必要もあります
• WebサービスやRESTのクライアントが利用できます
• Postman
• 私は Chrome の Advanced REST Client (ARC) を
用いています
2016/9/9 EWD 3 トレーニング・コース #31 14
試してみましょう
2016/9/9 EWD 3 トレーニング・コース #31 15
エラーを修正する
• もちろん、要求を処理するバックエンド・モジュールをま
だ作っていません
• モジュール名は URL パスと同じ名前です
• ~/ewd3/node_modules/testWebService.js
2016/9/9 EWD 3 トレーニング・コース #31 16
REST を処理するモジュール
• ewd-xpress のメッセージを処理するモジュールに極
めて似ています
2016/9/9 EWD 3 トレーニング・コース #31 17
REST を処理するモジュール
module.exports = {
restModule: true,
handlers: {
// 要求の type 毎に異なるハンドラ関数
}
};
2016/9/9 EWD 3 トレーニング・コース #31 18
REST を処理するモジュール
module.exports = {
restModule: true, // ewd-xpress にこれは RESTハンドラだと教えています
handlers: {
// 要求の type 毎に異なるハンドラ関数
}
};
RESTだけでなく、すべてのWebサービス要求
2016/9/9 EWD 3 トレーニング・コース #31 19
REST を処理するモジュール
module.exports = {
restModule: true,
handlers: {
{type}: function(messageObj, finished) {
// 受信したこの type の要求に対するハンドラ
}
}
};
2016/9/9 EWD 3 トレーニング・コース #31 20
REST を処理するモジュール
module.exports = {
restModule: true,
handlers: {
myType: function(messageObj, finished) {
// 受信した myType 要求に対するハンドラ
}
}
};
2016/9/9 EWD 3 トレーニング・コース #31 21
REST を処理するモジュール
~/ewd3/node_modules/testWebService.js
module.exports = {
restModule: true,
handlers: {
myType: function(messageObj, finished) {
// 受信した myType 要求に対するハンドラ
}
}
};
http://192.168.1.100:8080/testWebService/myType
2016/9/9 EWD 3 トレーニング・コース #31 22
REST を処理するモジュール
~/ewd3/node_modules/testWebService.js
module.exports = {
restModule: true,
handlers: {
myType: function(messageObj, finished) {
// 受信した myType 要求に対するハンドラ
// URLの残りの部分は、messageObj.properties でアクセス可能
}
}
};
http://192.168.1.100:8080/testWebService/myType/xyz?a=245&b=rob
2016/9/9 EWD 3 トレーニング・コース #31 23
REST を処理するモジュール
~/ewd3/node_modules/testWebService.js
module.exports = {
restModule: true,
handlers: {
myType: function(messageObj, finished) {
// 受信したメッセージ・オブジェクトを処理し、応答オブジェクトを生成
// finished() 関数を呼び出して終了しなくてはなりません
// - 応答オブジェクトをクライアントに送信
// - ワーカー・プロセスを利用可能なプールに戻す
finished(responseObject);
}
}
};
http://192.168.1.100:8080/testWebService/myType
2016/9/9 EWD 3 トレーニング・コース #31 24
REST を処理するモジュール
~/ewd3/node_modules/testWebService.js
module.exports = {
restModule: true,
handlers: {
myType: function(messageObj, finished) {
console.log("*** myType messageObj: " + JSON.stringify(messageObj));
finished({
test: 'finished ok'
});
}
}
};
http://192.168.1.100:8080/testWebService/myType
2016/9/9 EWD 3 トレーニング・コース #31 25
試してみましょう
2016/9/9 EWD 3 トレーニング・コース #31 26
ewd-xpress のログをみてみる
*** myType messageObj: {
"type":"ewd-qoper8-xpress",
"path":"/testWebService/myType",
"method":"GET",
"headers":{
"host":"192.168.1.183:8080",
"content-type":"application/json"
},
"params":{
"type":"myType"
},
"query":{},
"application":"testWebService",
"expressType":"myType"
}
2016/9/9 EWD 3 トレーニング・コース #31 27
ewd-xpress のログをみてみる
*** myType messageObj: {
"type":"ewd-qoper8-xpress",
"path":"/testWebService/myType",
"method":"GET",
"headers":{
"host":"192.168.1.183:8080",
"content-type":"application/json"
},
"params":{
"type":"myType"
},
"query":{},
"application":"testWebService",
"expressType":"myType"
}
2016/9/9 EWD 3 トレーニング・コース #31 28
受信したHTTP要求のすべての要素
は分解されて、受信したメッセージ・オ
ブジェクトの中で利用可能です
これは ewd-qoper8-express の
ルータが行っていることです
簡単な Webサービス
var config = {
managementPassword: 'keepThisSecret!',
serverName: 'My EWD Server',
port: 8080,
poolSize: 2,
database: {
type: ‘gtm',
params: {
// snip
}
}
};
var ewdXpress = require('ewd-xpress').master;
var xprss = ewdXpress.intercept();
exprss.app.use('/testWebService', express.qx.router());
ewdXpress.start(config);
2016/9/9 EWD 3 トレーニング・コース #31 29
ewd-xpress のログをみてみる
*** myType messageObj: {
"type":"ewd-qoper8-xpress",
"path":"/testWebService/myType",
"method":"GET",
"headers":{
"host":"192.168.1.183:8080",
"content-type":"application/json"
},
"params":{
"type":"myType"
},
"query":{},
"application":"testWebService",
"expressType":"myType"
}
2016/9/9 EWD 3 トレーニング・コース #31 30
REST の type は、expressType と
いうプロパティの中に定義されています
type プロパティではないことに注意
ewd-xpress のログをみてみる
*** myType messageObj: {
"type":"ewd-qoper8-xpress",
"path":"/testWebService/myType",
"method":"GET",
"headers":{
"host":"192.168.1.183:8080",
"content-type":"application/json"
},
"params":{
"type":"myType"
},
"query":{},
"application":"testWebService",
"expressType":"myType"
}
2016/9/9 EWD 3 トレーニング・コース #31 31
REST の type は、expressType と
いうプロパティの中に定義されています
type プロパティではないことに注意
しかし、params.type 経由でも利用
可能です
ewd-xpress のログをみてみる
*** myType messageObj: {
"type":"ewd-qoper8-xpress",
"path":"/testWebService/myType",
"method":"GET",
"headers":{
"host":"192.168.1.183:8080",
"content-type":"application/json"
},
"params":{
"type":"myType"
},
"query":{},
"application":"testWebService",
"expressType":"myType"
}
2016/9/9 EWD 3 トレーニング・コース #31 32
メソッドを知りたいということがしばしばあ
ります
例えば、GET か POST か
ewd-xpress のログをみてみる
*** myType messageObj: {
"type":"ewd-qoper8-xpress",
"path":"/testWebService/myType",
"method":"GET",
"headers":{
"host":"192.168.1.183:8080",
"content-type":"application/json"
},
"params":{
"type":"myType"
},
"query":{},
"application":"testWebService",
"expressType":"myType"
}
2016/9/9 EWD 3 トレーニング・コース #31 33
また、ヘッダーの情報を使いたい場合も
あります
特に、セキュリティの処理などに使う場
合です
REST を処理するモジュール
~/ewd3/node_modules/testWebService.js
module.exports = {
restModule: true,
handlers: {
myType: function(messageObj, finished) {
// 受信した myType 要求に対するハンドラ
// URLの残りの部分は、messageObj.properties でアクセス可能
}
}
};
http://192.168.1.100:8080/testWebService/myType/xyz?a=245&b=rob
2016/9/9 EWD 3 トレーニング・コース #31 34
試してみましょう
2016/9/9 EWD 3 トレーニング・コース #31 35
ewd-xpress のログをみてみる
*** myType messageObj: {
"type":"ewd-qoper8-xpress",
"path":"/testWebService/myType/xyz?a=245&b=rob",
"method":"GET",
"headers":{
"host":"192.168.1.183:8080",
"content-type":"application/json"
},
"params":{
"0":"xyz",
"type":"myType"
},
"query":{
"a":"245",
"b":"rob"
},
"application":"testWebService",
"expressType":"myType"
}
2016/9/9 EWD 3 トレーニング・コース #31 36
ewd-xpress のログをみてみる
*** myType messageObj: {
"type":"ewd-qoper8-xpress",
"path":"/testWebService/myType/xyz?a=245&b=rob",
"method":"GET",
"headers":{
"host":"192.168.1.183:8080",
"content-type":"application/json"
},
"params":{
"0":"xyz",
"type":"myType"
},
"query":{
"a":"245",
"b":"rob"
},
"application":"testWebService",
"expressType":"myType"
}
2016/9/9 EWD 3 トレーニング・コース #31 37
完全なパスを得ることができ
ます
ewd-xpress のログをみてみる
*** myType messageObj: {
"type":"ewd-qoper8-xpress",
"path":"/testWebService/myType/xyz?a=245&b=rob",
"method":"GET",
"headers":{
"host":"192.168.1.183:8080",
"content-type":"application/json"
},
"params":{
"0":"xyz",
"type":"myType"
},
"query":{
"a":"245",
"b":"rob"
},
"application":"testWebService",
"expressType":"myType"
}
2016/9/9 EWD 3 トレーニング・コース #31 38
URL パスの 3 番目の部分
は、 params['0'] に入っ
ています
ewd-xpress のログをみてみる
*** myType messageObj: {
"type":"ewd-qoper8-xpress",
"path":"/testWebService/myType/xyz?a=245&b=rob",
"method":"GET",
"headers":{
"host":"192.168.1.183:8080",
"content-type":"application/json"
},
"params":{
"0":"xyz",
"type":"myType"
},
"query":{
"a":"245",
"b":"rob"
},
"application":"testWebService",
"expressType":"myType"
}
2016/9/9 EWD 3 トレーニング・コース #31 39
URL の問い合わせ文字列
の名前/値のペアは、パース
されて query オブジェクト
に入ります
query.a
query.b
さらに長い URL の場合は?
2016/9/9 EWD 3 トレーニング・コース #31 40
試してみましょう
2016/9/9 EWD 3 トレーニング・コース #31 41
ewd-xpress のログをみてみる
*** myType messageObj: {
"type":"ewd-qoper8-xpress",
"path":"/testWebService/myType/how/about/this?a=245&b=rob",
"method":"GET",
"headers":{
"host":"192.168.1.183:8080",
"content-type":"application/json"
},
"params":{
"0":"how/about/this",
"type":"myType"
},
"query":{
"a":"245",
"b":"rob"
},
"application":"testWebService",
"expressType":"myType"
}
2016/9/9 EWD 3 トレーニング・コース #31 42
URL の追加部分は、すべてひとつにして
params['0'] の中に入っています
ewd-xpress のログをみてみる
*** myType messageObj: {
"type":"ewd-qoper8-xpress",
"path":"/testWebService/myType/how/about/this?a=245&b=rob",
"method":"GET",
"headers":{
"host":"192.168.1.183:8080",
"content-type":"application/json"
},
"params":{
"0":"how/about/this",
"type":"myType"
},
"query":{
"a":"245",
"b":"rob"
},
"application":"testWebService",
"expressType":"myType"
}
2016/9/9 EWD 3 トレーニング・コース #31 43
URL の追加部分は、すべてひとつにして
params['0'] の中に入っています
var pathArr =params['0'].split('/');
でパースすることができます
POST + 搭載物(ペイロード) の処理
• 搭載物(ペイロード)/本体 を送る他の HTTP メソッ
ドにも次のことが適用されます
2016/9/9 EWD 3 トレーニング・コース #31 44
POST + 搭載物(ペイロード) の処理
• ewd-xpress はもともと JSONベースの REST/
Webサービスのために設計されました
• 搭載物(ペイロード)/本体 は JSON でなくてはなりません
• ewd-xpress は実際には、どのような content-
type でも処理することができます
• しかし、他のバックエンドの NPM モジュールを追加して構成
する必要があります
• ここでは、application/json のコンテンツに焦点を絞
ります
2016/9/9 EWD 3 トレーニング・コース #31 45
試してみましょう
2016/9/9 EWD 3 トレーニング・コース #31 46
POSTメソッド
コンテント・タイプに注意
JSON のペイロード
注意: これは適切な JSON 書
式でなくてはならず、JavaScript
の文字列フォーマットではいけませ
ん
即ち、名前も値も「"」で囲みます
試してみましょう
2016/9/9 EWD 3 トレーニング・コース #31 47
成功した結果
ewd-xpress のログでは
*** myType messageObj: {
"type":"ewd-qoper8-xpress",
"path":"/testWebService/myType/",
"method":"POST",
"headers":{
"host":"192.168.1.183:8080",
"content-type":"application/json",
"content-length":"30"
},
"params":{
"type":"myType"
},
"query":{},
"application":"testWebService",
"expressType":"myType"
}
2016/9/9 EWD 3 トレーニング・コース #31 48
コンテンツがあったと記録されています
ewd-xpress のログでは
*** myType messageObj: {
"type":"ewd-qoper8-xpress",
"path":"/testWebService/myType/",
"method":"POST",
"headers":{
"host":"192.168.1.183:8080",
"content-type":"application/json",
"content-length":"30"
},
"params":{
"type":"myType"
},
"query":{},
"application":"testWebService",
"expressType":"myType"
}
2016/9/9 EWD 3 トレーニング・コース #31 49
しかし、本体/ペイロードはどこに?
Express のコンテントのパーシング
• Express では、搭載物(ペイロード)/本体の中の
JSON をパースするには、そのように明確に指示しなく
てはなりません
• ミドルウェアはそのためにあるのです!
• body-parser という名前の NPM モジュールがあります
• これをインストールしなくてはなりません
• 実際には、ewd-xpress をインストールしたときに、これは自動的
にインストールされています
• ~/ewd3/node_modules/body-parser を見てください
• しかし、これをロードして利用するには、ewd-xpress のスタート・アッ
プファイル内で明確に指定しなくてはなりません
2016/9/9 EWD 3 トレーニング・コース #31 50
ewd-xpress の起動ファイルを編集する
var config = {
managementPassword: 'keepThisSecret!',
serverName: 'My EWD Server',
port: 8080,
poolSize: 2,
database: {
type: ‘gtm',
params: {
// snip
}
}
};
var ewdXpress = require('ewd-xpress').master;
var exprss = ewdXpress.intercept();
var bodyParser = require('body-parser');
exprss.app.use(bodyParser.json());
express.app.use('/testWebService', express.qx.router());
ewdXpress.start(config)
2016/9/9 EWD 3 トレーニング・コース #31 51
ewd-xpress を再起動して再試行
2016/9/9 EWD 3 トレーニング・コース #31 52
ewd-xpress のログでは
*** myType messageObj: {
"type":"ewd-qoper8-xpress",
"path":"/testWebService/myType/",
"method":"POST",
"headers":{
"host":"192.168.1.183:8080",
"content-type":"application/json",
"content-length":"30"
},
"params":{
"type":"myType"
},
"query":{},
"body":{
"c":"hello",
"d":"world"
},
"application":"testWebService",
"expressType":"myType"
}
2016/9/9 EWD 3 トレーニング・コース #31 53
本体(body)の内容は、パースされて、
messageObj.body の中で利用できます
本体 + 名前/値 のペア?
• POST された HTTP 要求に、本体/搭載物(ペイ
ロード) だけでなく
• もっと URL パスの長いもの
• 追加的な 名前/値のペア の問い合わせ文字列
をもつことはできるでしょうか?
2016/9/9 EWD 3 トレーニング・コース #31 54
試してみましょう
2016/9/9 EWD 3 トレーニング・コース #31 55
試すURLはココ
ペイロードを組み
合わせる
正常に稼働している
また ewd-xpress のログをチェック
*** myType messageObj: {
"type":"ewd-qoper8-xpress",
"path":"/testWebService/myType/how/about/this?a=123&b=rob",
"method":"POST",
"headers":{
"host":"192.168.1.183:8080",
"content-type":"application/json",
"content-length":"30"
},
"params":{
"0":"how/about/this",
"type":"myType"
},
"query":{
"a":"123"
"b":"rob"
},
"body":{
"c":"hello",
"d":"world"
},
"application":"testWebService",
"expressType":"myType"
}
2016/9/9 EWD 3 トレーニング・コース #31 56
長い URL パスはこちら
また ewd-xpress のログをチェック
*** myType messageObj: {
"type":"ewd-qoper8-xpress",
"path":"/testWebService/myType/how/about/this?a=123&b=rob",
"method":"POST",
"headers":{
"host":"192.168.1.183:8080",
"content-type":"application/json",
"content-length":"30"
},
"params":{
"0":"how/about/this",
"type":"myType"
},
"query":{
"a":"123"
"b":"rob"
},
"body":{
"c":"hello",
"d":"world"
},
"application":"testWebService",
"expressType":"myType"
}
2016/9/9 EWD 3 トレーニング・コース #31 57
URL の残りの部分はパースされてここに
また ewd-xpress のログをチェック
*** myType messageObj: {
"type":"ewd-qoper8-xpress",
"path":"/testWebService/myType/how/about/this?a=123&b=rob",
"method":"POST",
"headers":{
"host":"192.168.1.183:8080",
"content-type":"application/json",
"content-length":"30"
},
"params":{
"0":"how/about/this",
"type":"myType"
},
"query":{
"a":"123"
"b":"rob"
},
"body":{
"c":"hello",
"d":"world"
},
"application":"testWebService",
"expressType":"myType"
}
2016/9/9 EWD 3 トレーニング・コース #31 58
問い合わせ文字列の 名前/値 のペアを保
持する query オブジェクトはここに
また ewd-xpress のログをチェック
*** myType messageObj: {
"type":"ewd-qoper8-xpress",
"path":"/testWebService/myType/how/about/this?a=123&b=rob",
"method":"POST",
"headers":{
"host":"192.168.1.183:8080",
"content-type":"application/json",
"content-length":"30"
},
"params":{
"0":"how/about/this",
"type":"myType"
},
"query":{
"a":"123"
"b":"rob"
},
"body":{
"c":"hello",
"d":"world"
},
"application":"testWebService",
"expressType":"myType"
}
2016/9/9 EWD 3 トレーニング・コース #31 59
POST された搭載物(ペイロード)を含む
body オブジェクトがここに
バックエンドの REST type ハンドラ
• これで、バックエンドの type ハンドラ関数には、受信し
た REST および Webサービスへの要求の処理必要
な情報がすべて渡されました
• これをどのように処理するかはあなた次第です
• データベースへは次の方法でアクセスできます
• this.db
• 例えば this.db.function() で従来のMUMPSコードを呼び出
す
• this.documentStore
2016/9/9 EWD 3 トレーニング・コース #31 60
例えば
• ~/ewd3/node_modules/testWebService.js
module.exports = {
restModule: true,
handlers: {
myType: function(messageObj, finished) {
console.log('*** myType messageObj: ' + JSON.stringify(messageObj));
console.log(this.db.version());
var doc = new this.documentStore.DocumentNode('myDoc');
var myObj = {
hello: 'world'
}
doc.setDocument(myObj);
finished({
test: 'finished ok'
});
}
}
};
2016/9/9 EWD 3 トレーニング・コース #31 61
バックエンド・モジュールの違いの要点
• 次の2つの違い
• 対話型アプリケーションにおけるメッセージの処理に使われる
もの
• REST/Webサービスの要求の処理に使われるもの
2016/9/9 EWD 3 トレーニング・コース #31 62
バックエンド・モジュールの違いの要点
• ~/ewd3/node_modules/testWebService.js
module.exports = {
restModule: true,
handlers: {
myType: function(messageObj, finished) {
console.log('*** myType messageObj: ' + JSON.stringify(messageObj));
finished({
test: 'finished ok'
});
}
}
};
2016/9/9 EWD 3 トレーニング・コース #31 63
send() 関数なし
EWDセッションなし
send 関数がない?
• REST と Webサービスは、HTTPベース
• ひとつの要求がひとつの応答を生成します
• 従って、中間メッセージは不適切です
2016/9/9 EWD 3 トレーニング・コース #31 64
send 関数がない?
• REST と Webサービスは、HTTPベース
• ひとつの要求がひとつの応答を生成します
• 従って、中間メッセージは不適切です
• それがあっても良いですが、しかし、ある/すべてのブラウザに
メッセージを送るハンドラ関数は、web-socket 経由です!
2016/9/9 EWD 3 トレーニング・コース #31 65
EWD セッションがない?
• REST と Webサービスは、ステート(状態)レスです
• アプリケーションにはリンクしません
• 暗黙的な EWD セッションは不適切です
2016/9/9 EWD 3 トレーニング・コース #31 66
EWD セッションがない?
• REST と Webサービスは、ステート(状態)レスです
• アプリケーションにはリンクしません
• 暗黙的な EWD セッションは不適切です
• しかし、独自のハンドラで EWD セッションを生成し維
持することは可能です
• このために ewd-session モジュールを使うことができます
• this.sessions
• これが何かというこを知っている必要はあります
2016/9/9 EWD 3 トレーニング・コース #31 67
REST/Webサービスでセッションを使う
• ログイン要求のハンドラを作ります
• セキュリティのためには、POST 要求であるべきでしょう
• ユーザー名、パスワードは本体の搭載物(ペイロード)
内に定義されるべきです
2016/9/9 EWD 3 トレーニング・コース #31 68
REST/Webサービスでセッションを使う
function checkLogin(username,password) {
if (username !== 'rob') return {error: 'Invalid username'};
if (password !== 'secret') return {error: 'Invalid password'};
return {ok: true}
};
module.exports = {
restModule: true,
handlers: {
login: function(messageObj, finished) {
if (messageObj.method !== 'POST') {
finished({error: 'login message must use POST method'});
return;
}
var username = messageObj.body.username;
if (!username || username === '') {
finished({error: 'You must provide a username'});
return;
}
var password = messageObj.body.password;
if (!password || password === '') {
finished({error: 'You must provide a password'});
return;
}
var status = checkLogin(username, password);
if (status.error) {
finished(status);
return;
}
var session = this.sessios.create('testWebService', 3600);
session.authenticated = true;
finished({token: session.token});
}
}
}
2016/9/9 EWD 3 トレーニング・コース #31 69
REST/Webサービスでセッションを使う
function checkLogin(username,password) {
if (username !== 'rob') return {error: 'Invalid username'};
if (password !== 'secret') return {error: 'Invalid password'};
return {ok: true}
};
module.exports = {
restModule: true,
handlers: {
login: function(messageObj, finished) {
if (messageObj.method !== 'POST') {
finished({error: 'login message must use POST method'});
return;
}
var username = messageObj.body.username;
if (!username || username === '') {
finished({error: 'You must provide a username'});
return;
}
var password = messageObj.body.password;
if (!password || password === '') {
finished({error: 'You must provide a password'});
return;
}
var status = checkLogin(username, password);
if (status.error) {
finished(status);
return;
}
var session = this.sessios.create('testWebService', 3600);
session.authenticated = true;
finished({token: session.token});
}
}
}
2016/9/9 EWD 3 トレーニング・コース #31 70
セキュリティ上の理由で、POST要求で
なくてはなりません
REST/Webサービスでセッションを使う
function checkLogin(username,password) {
if (username !== 'rob') return {error: 'Invalid username'};
if (password !== 'secret') return {error: 'Invalid password'};
return {ok: true}
};
module.exports = {
restModule: true,
handlers: {
login: function(messageObj, finished) {
if (messageObj.method !== 'POST') {
finished({error: 'login message must use POST method'});
return;
}
var username = messageObj.body.username;
if (!username || username === '') {
finished({error: 'You must provide a username'});
return;
}
var password = messageObj.body.password;
if (!password || password === '') {
finished({error: 'You must provide a password'});
return;
}
var status = checkLogin(username, password);
if (status.error) {
finished(status);
return;
}
var session = this.sessios.create('testWebService', 3600);
session.authenticated = true;
finished({token: session.token});
}
}
}
2016/9/9 EWD 3 トレーニング・コース #31 71
ユーザ名とパスワードは、要求の本体
(body) から得られます
REST/Webサービスでセッションを使う
function checkLogin(username,password) {
if (username !== 'rob') return {error: 'Invalid username'};
if (password !== 'secret') return {error: 'Invalid password'};
return {ok: true}
};
module.exports = {
restModule: true,
handlers: {
login: function(messageObj, finished) {
if (messageObj.method !== 'POST') {
finished({error: 'login message must use POST method'});
return;
}
var username = messageObj.body.username;
if (!username || username === '') {
finished({error: 'You must provide a username'});
return;
}
var password = messageObj.body.password;
if (!password || password === '') {
finished({error: 'You must provide a password'});
return;
}
var status = checkLogin(username, password);
if (status.error) {
finished(status);
return;
}
var session = this.sessios.create('testWebService', 3600);
session.authenticated = true;
finished({token: session.token});
}
}
}
2016/9/9 EWD 3 トレーニング・コース #31 72
ユーザ名とパスワードの検証
もし正しくなければエラー応答を返す
REST/Webサービスでセッションを使う
function checkLogin(username,password) {
if (username !== 'rob') return {error: 'Invalid username'};
if (password !== 'secret') return {error: 'Invalid password'};
return {ok: true}
};
module.exports = {
restModule: true,
handlers: {
login: function(messageObj, finished) {
if (messageObj.method !== 'POST') {
finished({error: 'login message must use POST method'});
return;
}
var username = messageObj.body.username;
if (!username || username === '') {
finished({error: 'You must provide a username'});
return;
}
var password = messageObj.body.password;
if (!password || password === '') {
finished({error: 'You must provide a password'});
return;
}
var status = checkLogin(username, password);
if (status.error) {
finished(status);
return;
}
var session = this.sessios.create('testWebService', 3600);
session.authenticated = true;
finished({token: session.token});
}
}
}
2016/9/9 EWD 3 トレーニング・コース #31 73
認証が正しければ、testWebService
という名前のアプリケーション用に、新しい
EWDセッションを作ります
このセッションの有効期限は1時間です
REST/Webサービスでセッションを使う
function checkLogin(username,password) {
if (username !== 'rob') return {error: 'Invalid username'};
if (password !== 'secret') return {error: 'Invalid password'};
return {ok: true}
};
module.exports = {
restModule: true,
handlers: {
login: function(messageObj, finished) {
if (messageObj.method !== 'POST') {
finished({error: 'login message must use POST method'});
return;
}
var username = messageObj.body.username;
if (!username || username === '') {
finished({error: 'You must provide a username'});
return;
}
var password = messageObj.body.password;
if (!password || password === '') {
finished({error: 'You must provide a password'});
return;
}
var status = checkLogin(username, password);
if (status.error) {
finished(status);
return;
}
var session = this.sessios.create('testWebService', 3600);
session.authenticated = true;
finished({token: session.token});
}
}
}
2016/9/9 EWD 3 トレーニング・コース #31 74
このセッションは認証済というフラグ
REST/Webサービスでセッションを使う
function checkLogin(username,password) {
if (username !== 'rob') return {error: 'Invalid username'};
if (password !== 'secret') return {error: 'Invalid password'};
return {ok: true}
};
module.exports = {
restModule: true,
handlers: {
login: function(messageObj, finished) {
if (messageObj.method !== 'POST') {
finished({error: 'login message must use POST method'});
return;
}
var username = messageObj.body.username;
if (!username || username === '') {
finished({error: 'You must provide a username'});
return;
}
var password = messageObj.body.password;
if (!password || password === '') {
finished({error: 'You must provide a password'});
return;
}
var status = checkLogin(username, password);
if (status.error) {
finished(status);
return;
}
var session = this.sessios.create('testWebService', 3600);
session.authenticated = true;
finished({token: session.token});
}
}
}
2016/9/9 EWD 3 トレーニング・コース #31 75
最後に、/login の応答として、セッショ
ン・トークンを返します
試してみましょう
2016/9/9 EWD 3 トレーニング・コース #31 76
ログイン URL
間違ったパスワードを
JSON のペイロードとして
POSTする
エラー応答
試してみましょう
2016/9/9 EWD 3 トレーニング・コース #31 77
ログイン URL
エラー応答
GET を用い、問い合わせ
文字列にユーザ名とパス
ワードを指定する
試してみましょう
2016/9/9 EWD 3 トレーニング・コース #31 78
今回はセッション・
トークンが返される
正しいユーザ名とパスワード
をPOSTのペイロードとして
渡す
次は何?
• 次に続く要求は、通常ヘッダ内に、セッション・トークン
を返します
• 例えば、権限付与ヘッダー
• バックエンドの要求ハンドラは、要求を認証しなくてはな
りません
• トークンが正しく、期限切れでないことをチェックします
• するとハンドラーは、ユーザーが続けている会話の一時
データのためにセッションを用いることができます
2016/9/9 EWD 3 トレーニング・コース #31 79
REST/Web サービスでセッションを用いる
module.exports = {
restModule: true,
handlers: {
login: function(messageObj, finished) {
// 以前に示した通り
},
doSomethingNext: function(messageObj, finished) {
var token = messageOgj.headers.authorization;
if (!token || token === '') {
finished({error: 'Missing authorization token'});
return;
}
var status = this.sessions.authenticate(token);
if (status.error) {
finished(status);
return;
}
var session = status.session;
// ユーザの要求の認証に成功した
// ユーザーのセッションを適切に用いるためのアクセス権を持っています
// ここで要求のコンテンツ/ペイロードを用いて、すべきことを何でもすることができます
// 最後に応答オブジェクト(responseObj)を作ります
finished(responseObj);
}
}
2016/9/9 EWD 3 トレーニング・コース #31 80
REST/Web サービスでセッションを用いる
module.exports = {
restModule: true,
handlers: {
login: function(messageObj, finished) {
// 以前に示した通り
},
doSomethingNext: function(messageObj, finished) {
var token = messageOgj.headers.authorization;
if (!token || token === '') {
finished({error: 'Missing authorization token'});
return;
}
var status = this.sessions.authenticate(token);
if (status.error) {
finished(status);
return;
}
var session = status.session;
// ユーザの要求の認証に成功した
// ユーザーのセッションを適切に用いるためのアクセス権を持っています
// ここで要求のコンテンツ/ペイロードを用いて、すべきことを何でもすることができます
// 最後に応答オブジェクト(responseObj)を作ります
finished(responseObj);
}
}
2016/9/9 EWD 3 トレーニング・コース #31 81
要求に権限認証ヘッダが付い
ていることを確認する
REST/Web サービスでセッションを用いる
module.exports = {
restModule: true,
handlers: {
login: function(messageObj, finished) {
// 以前に示した通り
},
doSomethingNext: function(messageObj, finished) {
var token = messageOgj.headers.authorization;
if (!token || token === '') {
finished({error: 'Missing authorization token'});
return;
}
var status = this.sessions.authenticate(token);
if (status.error) {
finished(status);
return;
}
var session = status.session;
// ユーザの要求の認証に成功した
// ユーザーのセッションを適切に用いるためのアクセス権を持っています
// ここで要求のコンテンツ/ペイロードを用いて、すべきことを何でもすることができます
// 最後に応答オブジェクト(responseObj)を作ります
finished(responseObj);
}
}
2016/9/9 EWD 3 トレーニング・コース #31 82
セッション・トークンを認証する
REST/Web サービスでセッションを用いる
module.exports = {
restModule: true,
handlers: {
login: function(messageObj, finished) {
// 以前に示した通り
},
doSomethingNext: function(messageObj, finished) {
var token = messageOgj.headers.authorization;
if (!token || token === '') {
finished({error: 'Missing authorization token'});
return;
}
var status = this.sessions.authenticate(token);
if (status.error) {
finished(status);
return;
}
var session = status.session;
// ユーザの要求の認証に成功した
// ユーザーのセッションを適切に用いるためのアクセス権を持っています
// ここで要求のコンテンツ/ペイロードを用いて、すべきことを何でもすることができます
// 最後に応答オブジェクト(responseObj)を作ります
finished(responseObj);
}
}
2016/9/9 EWD 3 トレーニング・コース #31 83
トークンは正しく、期限切れでもない
従ってユーザーのセッションにアクセス
することができる
REST/Web サービスでセッションを用いる
module.exports = {
restModule: true,
handlers: {
login: function(messageObj, finished) {
// 以前に示した通り
},
doSomethingNext: function(messageObj, finished) {
var token = messageOgj.headers.authorization;
if (!token || token === '') {
finished({error: 'Missing authorization token'});
return;
}
var status = this.sessions.authenticate(token);
if (status.error) {
finished(status);
return;
}
var session = status.session;
// ユーザの要求の認証に成功した
// ユーザーのセッションを適切に用いるためのアクセス権を持っています
// ここで要求のコンテンツ/ペイロードを用いて、すべきことを何でもすることができます
// 最後に応答オブジェクト(responseObj)を作ります
finished(responseObj);
}
}
2016/9/9 EWD 3 トレーニング・コース #31 84
必要な処理をして、応答オブジェ
クトを返す
試してみましょう
2016/9/9 EWD 3 トレーニング・コース #31 85
/doSomethingNext
という要求を送る
エラー応答
間違った、あるいは
期限切れのトークン
試してみましょう
2016/9/9 EWD 3 トレーニング・コース #31 86
エラー応答
権限付与するヘッダーが
定義されていない
試してみましょう
2016/9/9 EWD 3 トレーニング・コース #31 87
今度は成功
権限付与ヘッダーに
正しいtokenがある
セッションのログアウト?
• 明示的な /logout 要求は必要ありません
• セッションは自動的に期限切れになります
• もしログアウトしたければ、セッションを非認証にセットす
ることができます
• session.authenticated = false;
2016/9/9 EWD 3 トレーニング・コース #31 88
セッションのログアウト?
• 一旦トークンが認証されセッションが確立すれば、標準
的なメッセージ・ハンドラ内でタイムアウトを変更し、有
効期限を更新することができます
• session.timeout = 600;
• session.updateExpiry();
2016/9/9 EWD 3 トレーニング・コース #31 89
REST と Web サービス
• これであなたの ewd-xpress システム上で REST と
Web サービスをサポートするために必要なものはすべ
て揃いました
• 同じ ewd-xpress サーバー上で 対話的なアプリケーショ
ンをサポートするのに加えてです
• ewd-xpress の起動ファイルに、REST/Webサー
ビスを、必要ならどれだけでも加え、定義することができ
ます
2016/9/9 EWD 3 トレーニング・コース #31 90
ewd-xpress 起動ファイルの拡張
var config = {
managementPassword: 'keepThisSecret!',
serverName: 'My EWD Server',
port: 8080,
poolSize: 2,
database: {
type: ‘gtm',
params: {
// snip
}
}
};
var ewdXpress = require('ewd-xpress').master,
var exprss = ewdXpress.intercept();
var bodyParser = require('body-parser');
exprss.app.use(bodyParser.json());
exprss.app.use('/testWebService', exprss.qx.router());
exprss.app.use('/accounts', exprss.qx.router());
exprss.app.use('/stockControl', exprss.qx.router());
ewdXpress.start(config);
2016/9/9 EWD 3 トレーニング・コース #31 91
そして、対応するモジュールを
/node_modules の中に作
ります
- accounts.js
- stockControl.js

More Related Content

What's hot

Windows スクリプトセミナー WMI編 VBScript&WMI
Windows スクリプトセミナー WMI編 VBScript&WMIWindows スクリプトセミナー WMI編 VBScript&WMI
Windows スクリプトセミナー WMI編 VBScript&WMIjunichi anno
 
MySQL ガチBeginnerがやってみたことと反省したこと
MySQL ガチBeginnerがやってみたことと反省したことMySQL ガチBeginnerがやってみたことと反省したこと
MySQL ガチBeginnerがやってみたことと反省したことSatoshi Suzuki
 
第12回CloudStackユーザ会_ApacheCloudStack最新情報
第12回CloudStackユーザ会_ApacheCloudStack最新情報第12回CloudStackユーザ会_ApacheCloudStack最新情報
第12回CloudStackユーザ会_ApacheCloudStack最新情報Midori Oge
 
PowerShellを使用したWindows Serverの管理
PowerShellを使用したWindows Serverの管理PowerShellを使用したWindows Serverの管理
PowerShellを使用したWindows Serverの管理junichi anno
 
はじめてのSpring Boot
はじめてのSpring BootはじめてのSpring Boot
はじめてのSpring Bootなべ
 
tcpdump & xtrabackup @ MySQL Casual Talks #1
tcpdump & xtrabackup @ MySQL Casual Talks #1tcpdump & xtrabackup @ MySQL Casual Talks #1
tcpdump & xtrabackup @ MySQL Casual Talks #1Ryosuke IWANAGA
 
My sql casual_in_fukuoka_vol1
My sql casual_in_fukuoka_vol1My sql casual_in_fukuoka_vol1
My sql casual_in_fukuoka_vol1Makoto Haruyama
 
Using SockJS(Websocket) with Sencha Ext JS
Using SockJS(Websocket) with Sencha Ext JSUsing SockJS(Websocket) with Sencha Ext JS
Using SockJS(Websocket) with Sencha Ext JSKazuhiro Kotsutsumi
 
10分で作る Node.js Auto Scale 環境 with CloudFormation
10分で作る Node.js Auto Scale 環境 with CloudFormation10分で作る Node.js Auto Scale 環境 with CloudFormation
10分で作る Node.js Auto Scale 環境 with CloudFormationKazuyuki Honda
 
Webサーバ勉強会 発表資料
Webサーバ勉強会 発表資料Webサーバ勉強会 発表資料
Webサーバ勉強会 発表資料oranie Narut
 
Vue.jsの関連ツール・ライブラリ(Vuex, Vue-Router, Nuxt)
Vue.jsの関連ツール・ライブラリ(Vuex, Vue-Router, Nuxt)Vue.jsの関連ツール・ライブラリ(Vuex, Vue-Router, Nuxt)
Vue.jsの関連ツール・ライブラリ(Vuex, Vue-Router, Nuxt)Kei Yagi
 
PHP 2大 web フレームワークの徹底比較!
PHP 2大 web フレームワークの徹底比較!PHP 2大 web フレームワークの徹底比較!
PHP 2大 web フレームワークの徹底比較!Shohei Okada
 
自作node.jsフレームワークとnginxを使ってラジオサイトを作ってみた
自作node.jsフレームワークとnginxを使ってラジオサイトを作ってみた自作node.jsフレームワークとnginxを使ってラジオサイトを作ってみた
自作node.jsフレームワークとnginxを使ってラジオサイトを作ってみたYuki Takei
 
プロダクトに 1 から Vue.js を導入した話
プロダクトに 1 から Vue.js を導入した話プロダクトに 1 から Vue.js を導入した話
プロダクトに 1 から Vue.js を導入した話Shohei Okada
 
Webアプリケーションの パフォーマンス向上のコツ 実践編
 Webアプリケーションの パフォーマンス向上のコツ 実践編 Webアプリケーションの パフォーマンス向上のコツ 実践編
Webアプリケーションの パフォーマンス向上のコツ 実践編Masahiro Nagano
 
MySQL Casual Talks in Fukuoka vol.2
MySQL Casual Talks in Fukuoka vol.2MySQL Casual Talks in Fukuoka vol.2
MySQL Casual Talks in Fukuoka vol.2学 松崎
 
Introduction to JShell: the Java REPL Tool #jjug_ccc #ccc_ab4
Introduction to JShell: the Java REPL Tool #jjug_ccc #ccc_ab4Introduction to JShell: the Java REPL Tool #jjug_ccc #ccc_ab4
Introduction to JShell: the Java REPL Tool #jjug_ccc #ccc_ab4bitter_fox
 
DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!kwatch
 

What's hot (20)

Windows スクリプトセミナー WMI編 VBScript&WMI
Windows スクリプトセミナー WMI編 VBScript&WMIWindows スクリプトセミナー WMI編 VBScript&WMI
Windows スクリプトセミナー WMI編 VBScript&WMI
 
MySQL ガチBeginnerがやってみたことと反省したこと
MySQL ガチBeginnerがやってみたことと反省したことMySQL ガチBeginnerがやってみたことと反省したこと
MySQL ガチBeginnerがやってみたことと反省したこと
 
第12回CloudStackユーザ会_ApacheCloudStack最新情報
第12回CloudStackユーザ会_ApacheCloudStack最新情報第12回CloudStackユーザ会_ApacheCloudStack最新情報
第12回CloudStackユーザ会_ApacheCloudStack最新情報
 
PowerShellを使用したWindows Serverの管理
PowerShellを使用したWindows Serverの管理PowerShellを使用したWindows Serverの管理
PowerShellを使用したWindows Serverの管理
 
はじめてのSpring Boot
はじめてのSpring BootはじめてのSpring Boot
はじめてのSpring Boot
 
tcpdump & xtrabackup @ MySQL Casual Talks #1
tcpdump & xtrabackup @ MySQL Casual Talks #1tcpdump & xtrabackup @ MySQL Casual Talks #1
tcpdump & xtrabackup @ MySQL Casual Talks #1
 
My sql casual_in_fukuoka_vol1
My sql casual_in_fukuoka_vol1My sql casual_in_fukuoka_vol1
My sql casual_in_fukuoka_vol1
 
Mod mrubyについて
Mod mrubyについてMod mrubyについて
Mod mrubyについて
 
Using SockJS(Websocket) with Sencha Ext JS
Using SockJS(Websocket) with Sencha Ext JSUsing SockJS(Websocket) with Sencha Ext JS
Using SockJS(Websocket) with Sencha Ext JS
 
10分で作る Node.js Auto Scale 環境 with CloudFormation
10分で作る Node.js Auto Scale 環境 with CloudFormation10分で作る Node.js Auto Scale 環境 with CloudFormation
10分で作る Node.js Auto Scale 環境 with CloudFormation
 
Webサーバ勉強会 発表資料
Webサーバ勉強会 発表資料Webサーバ勉強会 発表資料
Webサーバ勉強会 発表資料
 
One night Vue.js
One night Vue.jsOne night Vue.js
One night Vue.js
 
Vue.jsの関連ツール・ライブラリ(Vuex, Vue-Router, Nuxt)
Vue.jsの関連ツール・ライブラリ(Vuex, Vue-Router, Nuxt)Vue.jsの関連ツール・ライブラリ(Vuex, Vue-Router, Nuxt)
Vue.jsの関連ツール・ライブラリ(Vuex, Vue-Router, Nuxt)
 
PHP 2大 web フレームワークの徹底比較!
PHP 2大 web フレームワークの徹底比較!PHP 2大 web フレームワークの徹底比較!
PHP 2大 web フレームワークの徹底比較!
 
自作node.jsフレームワークとnginxを使ってラジオサイトを作ってみた
自作node.jsフレームワークとnginxを使ってラジオサイトを作ってみた自作node.jsフレームワークとnginxを使ってラジオサイトを作ってみた
自作node.jsフレームワークとnginxを使ってラジオサイトを作ってみた
 
プロダクトに 1 から Vue.js を導入した話
プロダクトに 1 から Vue.js を導入した話プロダクトに 1 から Vue.js を導入した話
プロダクトに 1 から Vue.js を導入した話
 
Webアプリケーションの パフォーマンス向上のコツ 実践編
 Webアプリケーションの パフォーマンス向上のコツ 実践編 Webアプリケーションの パフォーマンス向上のコツ 実践編
Webアプリケーションの パフォーマンス向上のコツ 実践編
 
MySQL Casual Talks in Fukuoka vol.2
MySQL Casual Talks in Fukuoka vol.2MySQL Casual Talks in Fukuoka vol.2
MySQL Casual Talks in Fukuoka vol.2
 
Introduction to JShell: the Java REPL Tool #jjug_ccc #ccc_ab4
Introduction to JShell: the Java REPL Tool #jjug_ccc #ccc_ab4Introduction to JShell: the Java REPL Tool #jjug_ccc #ccc_ab4
Introduction to JShell: the Java REPL Tool #jjug_ccc #ccc_ab4
 
DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!
 

Viewers also liked

EWD 3トレーニングコース#17 Globalストレジ・データベース入門
EWD 3トレーニングコース#17 Globalストレジ・データベース入門EWD 3トレーニングコース#17 Globalストレジ・データベース入門
EWD 3トレーニングコース#17 Globalストレジ・データベース入門Kiyoshi Sawada
 
EWD 3トレーニングコース#14 ewd-xpressメッセージ用にAjaxを用いる
EWD 3トレーニングコース#14 ewd-xpressメッセージ用にAjaxを用いるEWD 3トレーニングコース#14 ewd-xpressメッセージ用にAjaxを用いる
EWD 3トレーニングコース#14 ewd-xpressメッセージ用にAjaxを用いるKiyoshi Sawada
 
EWD 3トレーニングコース#12 ewd-xpressのセッション・タイムアウトの制御
EWD 3トレーニングコース#12 ewd-xpressのセッション・タイムアウトの制御EWD 3トレーニングコース#12 ewd-xpressのセッション・タイムアウトの制御
EWD 3トレーニングコース#12 ewd-xpressのセッション・タイムアウトの制御Kiyoshi Sawada
 
EWD 3トレーニングコース#27 GlobalストレージのJavaScript用抽象化 - (h) EWD 3 セッション
EWD 3トレーニングコース#27 GlobalストレージのJavaScript用抽象化 - (h) EWD 3 セッションEWD 3トレーニングコース#27 GlobalストレージのJavaScript用抽象化 - (h) EWD 3 セッション
EWD 3トレーニングコース#27 GlobalストレージのJavaScript用抽象化 - (h) EWD 3 セッションKiyoshi Sawada
 
EWD 3トレーニングコース#23 GlobalストレージのJavaScript用抽象化-(d) ノードの範囲を渡り歩く
EWD 3トレーニングコース#23 GlobalストレージのJavaScript用抽象化-(d) ノードの範囲を渡り歩くEWD 3トレーニングコース#23 GlobalストレージのJavaScript用抽象化-(d) ノードの範囲を渡り歩く
EWD 3トレーニングコース#23 GlobalストレージのJavaScript用抽象化-(d) ノードの範囲を渡り歩くKiyoshi Sawada
 
EWD 3トレーニングコース#33 ewd-xpressアプリケーションからREST/Webサービスにアクセスする
EWD 3トレーニングコース#33 ewd-xpressアプリケーションからREST/WebサービスにアクセスするEWD 3トレーニングコース#33 ewd-xpressアプリケーションからREST/Webサービスにアクセスする
EWD 3トレーニングコース#33 ewd-xpressアプリケーションからREST/WebサービスにアクセスするKiyoshi Sawada
 
EWD 3トレーニングコース#1 Node.jsとCacheの連携
EWD 3トレーニングコース#1 Node.jsとCacheの連携EWD 3トレーニングコース#1 Node.jsとCacheの連携
EWD 3トレーニングコース#1 Node.jsとCacheの連携Kiyoshi Sawada
 
EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する
EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化するEWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する
EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化するKiyoshi Sawada
 
EWD 3トレーニングコース#28 従来のMUMPSコードをewd-xpressと統合する
EWD 3トレーニングコース#28 従来のMUMPSコードをewd-xpressと統合するEWD 3トレーニングコース#28 従来のMUMPSコードをewd-xpressと統合する
EWD 3トレーニングコース#28 従来のMUMPSコードをewd-xpressと統合するKiyoshi Sawada
 
EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する
EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化するEWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する
EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化するKiyoshi Sawada
 
EWD 3トレーニングコース#27 GlobalストレージのJavaScript用抽象化-(h) EWD 3 セッション
EWD 3トレーニングコース#27 GlobalストレージのJavaScript用抽象化-(h) EWD 3 セッションEWD 3トレーニングコース#27 GlobalストレージのJavaScript用抽象化-(h) EWD 3 セッション
EWD 3トレーニングコース#27 GlobalストレージのJavaScript用抽象化-(h) EWD 3 セッションKiyoshi Sawada
 
EWD 3トレーニング・コース #2 EWD 3 の概要
EWD 3トレーニング・コース #2 EWD 3 の概要EWD 3トレーニング・コース #2 EWD 3 の概要
EWD 3トレーニング・コース #2 EWD 3 の概要Kiyoshi Sawada
 
EWD 3トレーニングコース#17 Globalストレジ・データベース入門
EWD 3トレーニングコース#17 Globalストレジ・データベース入門EWD 3トレーニングコース#17 Globalストレジ・データベース入門
EWD 3トレーニングコース#17 Globalストレジ・データベース入門Kiyoshi Sawada
 
EWD 3トレーニングコース#15 ewd-xpressでjQuery以外のフレームワークを利用する
EWD 3トレーニングコース#15 ewd-xpressでjQuery以外のフレームワークを利用するEWD 3トレーニングコース#15 ewd-xpressでjQuery以外のフレームワークを利用する
EWD 3トレーニングコース#15 ewd-xpressでjQuery以外のフレームワークを利用するKiyoshi Sawada
 
EWD 3トレーニングコース#16 ewd-xpressサービス
EWD 3トレーニングコース#16 ewd-xpressサービスEWD 3トレーニングコース#16 ewd-xpressサービス
EWD 3トレーニングコース#16 ewd-xpressサービスKiyoshi Sawada
 
EWD 3トレーニングコース#22 GlobalストレージのJavaScript用抽象化-(c) ドキュメントを渡り歩く
EWD 3トレーニングコース#22 GlobalストレージのJavaScript用抽象化-(c) ドキュメントを渡り歩くEWD 3トレーニングコース#22 GlobalストレージのJavaScript用抽象化-(c) ドキュメントを渡り歩く
EWD 3トレーニングコース#22 GlobalストレージのJavaScript用抽象化-(c) ドキュメントを渡り歩くKiyoshi Sawada
 
EWD 3トレーニングコース#6 ewd-xpressアプリ開始時に何が起こるか
EWD 3トレーニングコース#6 ewd-xpressアプリ開始時に何が起こるかEWD 3トレーニングコース#6 ewd-xpressアプリ開始時に何が起こるか
EWD 3トレーニングコース#6 ewd-xpressアプリ開始時に何が起こるかKiyoshi Sawada
 
EWD 3トレーニングコース#8 ewd-xpressメッセージ・サイクルの解剖
EWD 3トレーニングコース#8 ewd-xpressメッセージ・サイクルの解剖EWD 3トレーニングコース#8 ewd-xpressメッセージ・サイクルの解剖
EWD 3トレーニングコース#8 ewd-xpressメッセージ・サイクルの解剖Kiyoshi Sawada
 
EWD 3トレーニングコース#5 ewd-xpressアプリ開発第1ステップ
EWD 3トレーニングコース#5 ewd-xpressアプリ開発第1ステップEWD 3トレーニングコース#5 ewd-xpressアプリ開発第1ステップ
EWD 3トレーニングコース#5 ewd-xpressアプリ開発第1ステップKiyoshi Sawada
 

Viewers also liked (19)

EWD 3トレーニングコース#17 Globalストレジ・データベース入門
EWD 3トレーニングコース#17 Globalストレジ・データベース入門EWD 3トレーニングコース#17 Globalストレジ・データベース入門
EWD 3トレーニングコース#17 Globalストレジ・データベース入門
 
EWD 3トレーニングコース#14 ewd-xpressメッセージ用にAjaxを用いる
EWD 3トレーニングコース#14 ewd-xpressメッセージ用にAjaxを用いるEWD 3トレーニングコース#14 ewd-xpressメッセージ用にAjaxを用いる
EWD 3トレーニングコース#14 ewd-xpressメッセージ用にAjaxを用いる
 
EWD 3トレーニングコース#12 ewd-xpressのセッション・タイムアウトの制御
EWD 3トレーニングコース#12 ewd-xpressのセッション・タイムアウトの制御EWD 3トレーニングコース#12 ewd-xpressのセッション・タイムアウトの制御
EWD 3トレーニングコース#12 ewd-xpressのセッション・タイムアウトの制御
 
EWD 3トレーニングコース#27 GlobalストレージのJavaScript用抽象化 - (h) EWD 3 セッション
EWD 3トレーニングコース#27 GlobalストレージのJavaScript用抽象化 - (h) EWD 3 セッションEWD 3トレーニングコース#27 GlobalストレージのJavaScript用抽象化 - (h) EWD 3 セッション
EWD 3トレーニングコース#27 GlobalストレージのJavaScript用抽象化 - (h) EWD 3 セッション
 
EWD 3トレーニングコース#23 GlobalストレージのJavaScript用抽象化-(d) ノードの範囲を渡り歩く
EWD 3トレーニングコース#23 GlobalストレージのJavaScript用抽象化-(d) ノードの範囲を渡り歩くEWD 3トレーニングコース#23 GlobalストレージのJavaScript用抽象化-(d) ノードの範囲を渡り歩く
EWD 3トレーニングコース#23 GlobalストレージのJavaScript用抽象化-(d) ノードの範囲を渡り歩く
 
EWD 3トレーニングコース#33 ewd-xpressアプリケーションからREST/Webサービスにアクセスする
EWD 3トレーニングコース#33 ewd-xpressアプリケーションからREST/WebサービスにアクセスするEWD 3トレーニングコース#33 ewd-xpressアプリケーションからREST/Webサービスにアクセスする
EWD 3トレーニングコース#33 ewd-xpressアプリケーションからREST/Webサービスにアクセスする
 
EWD 3トレーニングコース#1 Node.jsとCacheの連携
EWD 3トレーニングコース#1 Node.jsとCacheの連携EWD 3トレーニングコース#1 Node.jsとCacheの連携
EWD 3トレーニングコース#1 Node.jsとCacheの連携
 
EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する
EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化するEWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する
EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する
 
EWD 3トレーニングコース#28 従来のMUMPSコードをewd-xpressと統合する
EWD 3トレーニングコース#28 従来のMUMPSコードをewd-xpressと統合するEWD 3トレーニングコース#28 従来のMUMPSコードをewd-xpressと統合する
EWD 3トレーニングコース#28 従来のMUMPSコードをewd-xpressと統合する
 
EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する
EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化するEWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する
EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する
 
EWD 3トレーニングコース#27 GlobalストレージのJavaScript用抽象化-(h) EWD 3 セッション
EWD 3トレーニングコース#27 GlobalストレージのJavaScript用抽象化-(h) EWD 3 セッションEWD 3トレーニングコース#27 GlobalストレージのJavaScript用抽象化-(h) EWD 3 セッション
EWD 3トレーニングコース#27 GlobalストレージのJavaScript用抽象化-(h) EWD 3 セッション
 
EWD 3トレーニング・コース #2 EWD 3 の概要
EWD 3トレーニング・コース #2 EWD 3 の概要EWD 3トレーニング・コース #2 EWD 3 の概要
EWD 3トレーニング・コース #2 EWD 3 の概要
 
EWD 3トレーニングコース#17 Globalストレジ・データベース入門
EWD 3トレーニングコース#17 Globalストレジ・データベース入門EWD 3トレーニングコース#17 Globalストレジ・データベース入門
EWD 3トレーニングコース#17 Globalストレジ・データベース入門
 
EWD 3トレーニングコース#15 ewd-xpressでjQuery以外のフレームワークを利用する
EWD 3トレーニングコース#15 ewd-xpressでjQuery以外のフレームワークを利用するEWD 3トレーニングコース#15 ewd-xpressでjQuery以外のフレームワークを利用する
EWD 3トレーニングコース#15 ewd-xpressでjQuery以外のフレームワークを利用する
 
EWD 3トレーニングコース#16 ewd-xpressサービス
EWD 3トレーニングコース#16 ewd-xpressサービスEWD 3トレーニングコース#16 ewd-xpressサービス
EWD 3トレーニングコース#16 ewd-xpressサービス
 
EWD 3トレーニングコース#22 GlobalストレージのJavaScript用抽象化-(c) ドキュメントを渡り歩く
EWD 3トレーニングコース#22 GlobalストレージのJavaScript用抽象化-(c) ドキュメントを渡り歩くEWD 3トレーニングコース#22 GlobalストレージのJavaScript用抽象化-(c) ドキュメントを渡り歩く
EWD 3トレーニングコース#22 GlobalストレージのJavaScript用抽象化-(c) ドキュメントを渡り歩く
 
EWD 3トレーニングコース#6 ewd-xpressアプリ開始時に何が起こるか
EWD 3トレーニングコース#6 ewd-xpressアプリ開始時に何が起こるかEWD 3トレーニングコース#6 ewd-xpressアプリ開始時に何が起こるか
EWD 3トレーニングコース#6 ewd-xpressアプリ開始時に何が起こるか
 
EWD 3トレーニングコース#8 ewd-xpressメッセージ・サイクルの解剖
EWD 3トレーニングコース#8 ewd-xpressメッセージ・サイクルの解剖EWD 3トレーニングコース#8 ewd-xpressメッセージ・サイクルの解剖
EWD 3トレーニングコース#8 ewd-xpressメッセージ・サイクルの解剖
 
EWD 3トレーニングコース#5 ewd-xpressアプリ開発第1ステップ
EWD 3トレーニングコース#5 ewd-xpressアプリ開発第1ステップEWD 3トレーニングコース#5 ewd-xpressアプリ開発第1ステップ
EWD 3トレーニングコース#5 ewd-xpressアプリ開発第1ステップ
 

Similar to EWD 3トレーニングコース#31 ewd-xpressでWebおよびRESTサービスを作る

EWD 3トレーニング・コース #3 EWD 3 モジュールの概要
EWD 3トレーニング・コース #3 EWD 3 モジュールの概要EWD 3トレーニング・コース #3 EWD 3 モジュールの概要
EWD 3トレーニング・コース #3 EWD 3 モジュールの概要Kiyoshi Sawada
 
EWD 3トレーニングコース#3 EWD 3 モジュールの概要
EWD 3トレーニングコース#3 EWD 3 モジュールの概要EWD 3トレーニングコース#3 EWD 3 モジュールの概要
EWD 3トレーニングコース#3 EWD 3 モジュールの概要Kiyoshi Sawada
 
EWD 3トレーニングコース#4 ewd-xpressのインストールと構成
EWD 3トレーニングコース#4 ewd-xpressのインストールと構成EWD 3トレーニングコース#4 ewd-xpressのインストールと構成
EWD 3トレーニングコース#4 ewd-xpressのインストールと構成Kiyoshi Sawada
 
EWD 3トレーニング・コース #4 ewd-xpressのインストールと構成
EWD 3トレーニング・コース #4 ewd-xpressのインストールと構成EWD 3トレーニング・コース #4 ewd-xpressのインストールと構成
EWD 3トレーニング・コース #4 ewd-xpressのインストールと構成Kiyoshi Sawada
 
EWD 3トレーニングコース#5 ewd-xpressアプリ開発第1ステップ
EWD 3トレーニングコース#5 ewd-xpressアプリ開発第1ステップEWD 3トレーニングコース#5 ewd-xpressアプリ開発第1ステップ
EWD 3トレーニングコース#5 ewd-xpressアプリ開発第1ステップKiyoshi Sawada
 
EWD 3トレーニングコース#6 ewd-xpressアプリ開始時に何が起こるか
EWD 3トレーニングコース#6 ewd-xpressアプリ開始時に何が起こるかEWD 3トレーニングコース#6 ewd-xpressアプリ開始時に何が起こるか
EWD 3トレーニングコース#6 ewd-xpressアプリ開始時に何が起こるかKiyoshi Sawada
 
13016 n分で作るtype scriptでnodejs
13016 n分で作るtype scriptでnodejs13016 n分で作るtype scriptでnodejs
13016 n分で作るtype scriptでnodejsTakayoshi Tanaka
 
EWD 3トレーニングコース#33 ewd-xpressアプリケーションからREST/Webサービスにアクセスする
EWD 3トレーニングコース#33 ewd-xpressアプリケーションからREST/WebサービスにアクセスするEWD 3トレーニングコース#33 ewd-xpressアプリケーションからREST/Webサービスにアクセスする
EWD 3トレーニングコース#33 ewd-xpressアプリケーションからREST/WebサービスにアクセスするKiyoshi Sawada
 
EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する
EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用するEWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する
EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用するKiyoshi Sawada
 
EWD 3トレーニングコース#2 EWD 3の概要
EWD 3トレーニングコース#2 EWD 3の概要EWD 3トレーニングコース#2 EWD 3の概要
EWD 3トレーニングコース#2 EWD 3の概要Kiyoshi Sawada
 
Next2Dで始めるゲーム開発 - Game Development Starting with Next2D
Next2Dで始めるゲーム開発  - Game Development Starting with Next2DNext2Dで始めるゲーム開発  - Game Development Starting with Next2D
Next2Dで始めるゲーム開発 - Game Development Starting with Next2DToshiyuki Ienaga
 
Node.js勉強会 Framework Koa
Node.js勉強会 Framework KoaNode.js勉強会 Framework Koa
Node.js勉強会 Framework Koakamiyam .
 
EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する
EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用するEWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する
EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用するKiyoshi Sawada
 
EWD 3 トレーニング・コース #1 Node.jsとGT.Mの統合方法
EWD 3トレーニング・コース #1 Node.jsとGT.Mの統合方法EWD 3トレーニング・コース #1 Node.jsとGT.Mの統合方法
EWD 3 トレーニング・コース #1 Node.jsとGT.Mの統合方法Kiyoshi Sawada
 
EWD 3トレーニングコース#19 JavaScriptからGlobalストレジにアクセスする
EWD 3トレーニングコース#19 JavaScriptからGlobalストレジにアクセスするEWD 3トレーニングコース#19 JavaScriptからGlobalストレジにアクセスする
EWD 3トレーニングコース#19 JavaScriptからGlobalストレジにアクセスするKiyoshi Sawada
 
Nodejuku01 ohtsu
Nodejuku01 ohtsuNodejuku01 ohtsu
Nodejuku01 ohtsuNanha Park
 
EWD 3トレーニングコース#28 従来のMUMPSコードをewd-xpressと統合する
EWD 3トレーニングコース#28 従来のMUMPSコードをewd-xpressと統合するEWD 3トレーニングコース#28 従来のMUMPSコードをewd-xpressと統合する
EWD 3トレーニングコース#28 従来のMUMPSコードをewd-xpressと統合するKiyoshi Sawada
 
社内勉強会資料(Varnish Module)
社内勉強会資料(Varnish Module)社内勉強会資料(Varnish Module)
社内勉強会資料(Varnish Module)Iwana Chan
 

Similar to EWD 3トレーニングコース#31 ewd-xpressでWebおよびRESTサービスを作る (20)

EWD 3トレーニング・コース #3 EWD 3 モジュールの概要
EWD 3トレーニング・コース #3 EWD 3 モジュールの概要EWD 3トレーニング・コース #3 EWD 3 モジュールの概要
EWD 3トレーニング・コース #3 EWD 3 モジュールの概要
 
EWD 3トレーニングコース#3 EWD 3 モジュールの概要
EWD 3トレーニングコース#3 EWD 3 モジュールの概要EWD 3トレーニングコース#3 EWD 3 モジュールの概要
EWD 3トレーニングコース#3 EWD 3 モジュールの概要
 
EWD 3トレーニングコース#4 ewd-xpressのインストールと構成
EWD 3トレーニングコース#4 ewd-xpressのインストールと構成EWD 3トレーニングコース#4 ewd-xpressのインストールと構成
EWD 3トレーニングコース#4 ewd-xpressのインストールと構成
 
EWD 3トレーニング・コース #4 ewd-xpressのインストールと構成
EWD 3トレーニング・コース #4 ewd-xpressのインストールと構成EWD 3トレーニング・コース #4 ewd-xpressのインストールと構成
EWD 3トレーニング・コース #4 ewd-xpressのインストールと構成
 
EWD 3トレーニングコース#5 ewd-xpressアプリ開発第1ステップ
EWD 3トレーニングコース#5 ewd-xpressアプリ開発第1ステップEWD 3トレーニングコース#5 ewd-xpressアプリ開発第1ステップ
EWD 3トレーニングコース#5 ewd-xpressアプリ開発第1ステップ
 
EWD 3トレーニングコース#6 ewd-xpressアプリ開始時に何が起こるか
EWD 3トレーニングコース#6 ewd-xpressアプリ開始時に何が起こるかEWD 3トレーニングコース#6 ewd-xpressアプリ開始時に何が起こるか
EWD 3トレーニングコース#6 ewd-xpressアプリ開始時に何が起こるか
 
13016 n分で作るtype scriptでnodejs
13016 n分で作るtype scriptでnodejs13016 n分で作るtype scriptでnodejs
13016 n分で作るtype scriptでnodejs
 
EWD 3トレーニングコース#33 ewd-xpressアプリケーションからREST/Webサービスにアクセスする
EWD 3トレーニングコース#33 ewd-xpressアプリケーションからREST/WebサービスにアクセスするEWD 3トレーニングコース#33 ewd-xpressアプリケーションからREST/Webサービスにアクセスする
EWD 3トレーニングコース#33 ewd-xpressアプリケーションからREST/Webサービスにアクセスする
 
ASP.NET MVC 1.0
ASP.NET MVC 1.0ASP.NET MVC 1.0
ASP.NET MVC 1.0
 
EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する
EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用するEWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する
EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する
 
EWD 3トレーニングコース#2 EWD 3の概要
EWD 3トレーニングコース#2 EWD 3の概要EWD 3トレーニングコース#2 EWD 3の概要
EWD 3トレーニングコース#2 EWD 3の概要
 
Next2Dで始めるゲーム開発 - Game Development Starting with Next2D
Next2Dで始めるゲーム開発  - Game Development Starting with Next2DNext2Dで始めるゲーム開発  - Game Development Starting with Next2D
Next2Dで始めるゲーム開発 - Game Development Starting with Next2D
 
Node.js勉強会 Framework Koa
Node.js勉強会 Framework KoaNode.js勉強会 Framework Koa
Node.js勉強会 Framework Koa
 
EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する
EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用するEWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する
EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する
 
Clrh 110716 wcfwf
Clrh 110716 wcfwfClrh 110716 wcfwf
Clrh 110716 wcfwf
 
EWD 3 トレーニング・コース #1 Node.jsとGT.Mの統合方法
EWD 3トレーニング・コース #1 Node.jsとGT.Mの統合方法EWD 3トレーニング・コース #1 Node.jsとGT.Mの統合方法
EWD 3 トレーニング・コース #1 Node.jsとGT.Mの統合方法
 
EWD 3トレーニングコース#19 JavaScriptからGlobalストレジにアクセスする
EWD 3トレーニングコース#19 JavaScriptからGlobalストレジにアクセスするEWD 3トレーニングコース#19 JavaScriptからGlobalストレジにアクセスする
EWD 3トレーニングコース#19 JavaScriptからGlobalストレジにアクセスする
 
Nodejuku01 ohtsu
Nodejuku01 ohtsuNodejuku01 ohtsu
Nodejuku01 ohtsu
 
EWD 3トレーニングコース#28 従来のMUMPSコードをewd-xpressと統合する
EWD 3トレーニングコース#28 従来のMUMPSコードをewd-xpressと統合するEWD 3トレーニングコース#28 従来のMUMPSコードをewd-xpressと統合する
EWD 3トレーニングコース#28 従来のMUMPSコードをewd-xpressと統合する
 
社内勉強会資料(Varnish Module)
社内勉強会資料(Varnish Module)社内勉強会資料(Varnish Module)
社内勉強会資料(Varnish Module)
 

More from Kiyoshi Sawada

EWD 3トレーニングコース#29 ewd-xpressをWindows上のサービスとして稼働させる
EWD 3トレーニングコース#29 ewd-xpressをWindows上のサービスとして稼働させるEWD 3トレーニングコース#29 ewd-xpressをWindows上のサービスとして稼働させる
EWD 3トレーニングコース#29 ewd-xpressをWindows上のサービスとして稼働させるKiyoshi Sawada
 
EWD 3トレーニングコース#26 GlobalストレージのJavaScript用抽象化-(g) イベント駆動の索引管理
EWD 3トレーニングコース#26 GlobalストレージのJavaScript用抽象化-(g) イベント駆動の索引管理EWD 3トレーニングコース#26 GlobalストレージのJavaScript用抽象化-(g) イベント駆動の索引管理
EWD 3トレーニングコース#26 GlobalストレージのJavaScript用抽象化-(g) イベント駆動の索引管理Kiyoshi Sawada
 
EWD 3トレーニングコース#25 GlobalストレージのJavaScript用抽象化-(f) Documentデータベースのできること
EWD 3トレーニングコース#25 GlobalストレージのJavaScript用抽象化-(f) DocumentデータベースのできることEWD 3トレーニングコース#25 GlobalストレージのJavaScript用抽象化-(f) Documentデータベースのできること
EWD 3トレーニングコース#25 GlobalストレージのJavaScript用抽象化-(f) DocumentデータベースのできることKiyoshi Sawada
 
EWD 3トレーニングコース#24 GlobalストレージのJavaScript用抽象化-(e) ドキュメントの末端ノードを渡り歩く
EWD 3トレーニングコース#24 GlobalストレージのJavaScript用抽象化-(e) ドキュメントの末端ノードを渡り歩くEWD 3トレーニングコース#24 GlobalストレージのJavaScript用抽象化-(e) ドキュメントの末端ノードを渡り歩く
EWD 3トレーニングコース#24 GlobalストレージのJavaScript用抽象化-(e) ドキュメントの末端ノードを渡り歩くKiyoshi Sawada
 
EWD 3トレーニングコース#23 GlobalストレージのJavaScript用抽象化-(d) ノードの範囲を渡り歩く
EWD 3トレーニングコース#23 GlobalストレージのJavaScript用抽象化-(d) ノードの範囲を渡り歩くEWD 3トレーニングコース#23 GlobalストレージのJavaScript用抽象化-(d) ノードの範囲を渡り歩く
EWD 3トレーニングコース#23 GlobalストレージのJavaScript用抽象化-(d) ノードの範囲を渡り歩くKiyoshi Sawada
 
EWD 3トレーニングコース#21 GlobalストレージのJavaScript用抽象化-(b) JavaScriptの永続オブジェクト
EWD 3トレーニングコース#21 GlobalストレージのJavaScript用抽象化-(b) JavaScriptの永続オブジェクトEWD 3トレーニングコース#21 GlobalストレージのJavaScript用抽象化-(b) JavaScriptの永続オブジェクト
EWD 3トレーニングコース#21 GlobalストレージのJavaScript用抽象化-(b) JavaScriptの永続オブジェクトKiyoshi Sawada
 
EWD 3トレーニングコース#20 GlobalストレージのJavaScript用抽象化-(a)DocumentNodeオブジェクト
EWD 3トレーニングコース#20 GlobalストレージのJavaScript用抽象化-(a)DocumentNodeオブジェクトEWD 3トレーニングコース#20 GlobalストレージのJavaScript用抽象化-(a)DocumentNodeオブジェクト
EWD 3トレーニングコース#20 GlobalストレージのJavaScript用抽象化-(a)DocumentNodeオブジェクトKiyoshi Sawada
 
EWD 3トレーニングコース#18 GlobalストレジでNoSQLデータベースをモデル化する
EWD 3トレーニングコース#18 GlobalストレジでNoSQLデータベースをモデル化するEWD 3トレーニングコース#18 GlobalストレジでNoSQLデータベースをモデル化する
EWD 3トレーニングコース#18 GlobalストレジでNoSQLデータベースをモデル化するKiyoshi Sawada
 
EWD 3トレーニングコース#14 ewd-xpressメッセージ用にAjaxを用いる
EWD 3トレーニングコース#14 ewd-xpressメッセージ用にAjaxを用いるEWD 3トレーニングコース#14 ewd-xpressメッセージ用にAjaxを用いる
EWD 3トレーニングコース#14 ewd-xpressメッセージ用にAjaxを用いるKiyoshi Sawada
 
EWD 3トレーニングコース#13 全てをひとつにまとめてewd-xpressで稼働させてみる
EWD 3トレーニングコース#13 全てをひとつにまとめてewd-xpressで稼働させてみるEWD 3トレーニングコース#13 全てをひとつにまとめてewd-xpressで稼働させてみる
EWD 3トレーニングコース#13 全てをひとつにまとめてewd-xpressで稼働させてみるKiyoshi Sawada
 
EWD 3トレーニングコース#11 ewd-xpressでのエラー処理
EWD 3トレーニングコース#11 ewd-xpressでのエラー処理EWD 3トレーニングコース#11 ewd-xpressでのエラー処理
EWD 3トレーニングコース#11 ewd-xpressでのエラー処理Kiyoshi Sawada
 
EWD 3トレーニングコース#10 ewd-xpressのSessionとユーザー認証
EWD 3トレーニングコース#10 ewd-xpressのSessionとユーザー認証EWD 3トレーニングコース#10 ewd-xpressのSessionとユーザー認証
EWD 3トレーニングコース#10 ewd-xpressのSessionとユーザー認証Kiyoshi Sawada
 
EWD 3トレーニングコース#9 複雑なewd-xpressメッセージと応答
EWD 3トレーニングコース#9 複雑なewd-xpressメッセージと応答EWD 3トレーニングコース#9 複雑なewd-xpressメッセージと応答
EWD 3トレーニングコース#9 複雑なewd-xpressメッセージと応答Kiyoshi Sawada
 

More from Kiyoshi Sawada (13)

EWD 3トレーニングコース#29 ewd-xpressをWindows上のサービスとして稼働させる
EWD 3トレーニングコース#29 ewd-xpressをWindows上のサービスとして稼働させるEWD 3トレーニングコース#29 ewd-xpressをWindows上のサービスとして稼働させる
EWD 3トレーニングコース#29 ewd-xpressをWindows上のサービスとして稼働させる
 
EWD 3トレーニングコース#26 GlobalストレージのJavaScript用抽象化-(g) イベント駆動の索引管理
EWD 3トレーニングコース#26 GlobalストレージのJavaScript用抽象化-(g) イベント駆動の索引管理EWD 3トレーニングコース#26 GlobalストレージのJavaScript用抽象化-(g) イベント駆動の索引管理
EWD 3トレーニングコース#26 GlobalストレージのJavaScript用抽象化-(g) イベント駆動の索引管理
 
EWD 3トレーニングコース#25 GlobalストレージのJavaScript用抽象化-(f) Documentデータベースのできること
EWD 3トレーニングコース#25 GlobalストレージのJavaScript用抽象化-(f) DocumentデータベースのできることEWD 3トレーニングコース#25 GlobalストレージのJavaScript用抽象化-(f) Documentデータベースのできること
EWD 3トレーニングコース#25 GlobalストレージのJavaScript用抽象化-(f) Documentデータベースのできること
 
EWD 3トレーニングコース#24 GlobalストレージのJavaScript用抽象化-(e) ドキュメントの末端ノードを渡り歩く
EWD 3トレーニングコース#24 GlobalストレージのJavaScript用抽象化-(e) ドキュメントの末端ノードを渡り歩くEWD 3トレーニングコース#24 GlobalストレージのJavaScript用抽象化-(e) ドキュメントの末端ノードを渡り歩く
EWD 3トレーニングコース#24 GlobalストレージのJavaScript用抽象化-(e) ドキュメントの末端ノードを渡り歩く
 
EWD 3トレーニングコース#23 GlobalストレージのJavaScript用抽象化-(d) ノードの範囲を渡り歩く
EWD 3トレーニングコース#23 GlobalストレージのJavaScript用抽象化-(d) ノードの範囲を渡り歩くEWD 3トレーニングコース#23 GlobalストレージのJavaScript用抽象化-(d) ノードの範囲を渡り歩く
EWD 3トレーニングコース#23 GlobalストレージのJavaScript用抽象化-(d) ノードの範囲を渡り歩く
 
EWD 3トレーニングコース#21 GlobalストレージのJavaScript用抽象化-(b) JavaScriptの永続オブジェクト
EWD 3トレーニングコース#21 GlobalストレージのJavaScript用抽象化-(b) JavaScriptの永続オブジェクトEWD 3トレーニングコース#21 GlobalストレージのJavaScript用抽象化-(b) JavaScriptの永続オブジェクト
EWD 3トレーニングコース#21 GlobalストレージのJavaScript用抽象化-(b) JavaScriptの永続オブジェクト
 
EWD 3トレーニングコース#20 GlobalストレージのJavaScript用抽象化-(a)DocumentNodeオブジェクト
EWD 3トレーニングコース#20 GlobalストレージのJavaScript用抽象化-(a)DocumentNodeオブジェクトEWD 3トレーニングコース#20 GlobalストレージのJavaScript用抽象化-(a)DocumentNodeオブジェクト
EWD 3トレーニングコース#20 GlobalストレージのJavaScript用抽象化-(a)DocumentNodeオブジェクト
 
EWD 3トレーニングコース#18 GlobalストレジでNoSQLデータベースをモデル化する
EWD 3トレーニングコース#18 GlobalストレジでNoSQLデータベースをモデル化するEWD 3トレーニングコース#18 GlobalストレジでNoSQLデータベースをモデル化する
EWD 3トレーニングコース#18 GlobalストレジでNoSQLデータベースをモデル化する
 
EWD 3トレーニングコース#14 ewd-xpressメッセージ用にAjaxを用いる
EWD 3トレーニングコース#14 ewd-xpressメッセージ用にAjaxを用いるEWD 3トレーニングコース#14 ewd-xpressメッセージ用にAjaxを用いる
EWD 3トレーニングコース#14 ewd-xpressメッセージ用にAjaxを用いる
 
EWD 3トレーニングコース#13 全てをひとつにまとめてewd-xpressで稼働させてみる
EWD 3トレーニングコース#13 全てをひとつにまとめてewd-xpressで稼働させてみるEWD 3トレーニングコース#13 全てをひとつにまとめてewd-xpressで稼働させてみる
EWD 3トレーニングコース#13 全てをひとつにまとめてewd-xpressで稼働させてみる
 
EWD 3トレーニングコース#11 ewd-xpressでのエラー処理
EWD 3トレーニングコース#11 ewd-xpressでのエラー処理EWD 3トレーニングコース#11 ewd-xpressでのエラー処理
EWD 3トレーニングコース#11 ewd-xpressでのエラー処理
 
EWD 3トレーニングコース#10 ewd-xpressのSessionとユーザー認証
EWD 3トレーニングコース#10 ewd-xpressのSessionとユーザー認証EWD 3トレーニングコース#10 ewd-xpressのSessionとユーザー認証
EWD 3トレーニングコース#10 ewd-xpressのSessionとユーザー認証
 
EWD 3トレーニングコース#9 複雑なewd-xpressメッセージと応答
EWD 3トレーニングコース#9 複雑なewd-xpressメッセージと応答EWD 3トレーニングコース#9 複雑なewd-xpressメッセージと応答
EWD 3トレーニングコース#9 複雑なewd-xpressメッセージと応答
 

EWD 3トレーニングコース#31 ewd-xpressでWebおよびRESTサービスを作る

  • 1. EWD 3 トレーニング・コース #31 ewd-xpress で Web および REST サービスを作る M/Gateway Developments Ltd. Rob Tweed 訳: 日本ダイナシステム株式会社 嶋 芳成 GT.M版編集: 澤田 潔 ※ 本稿オリジナルはCache’向けとして編纂
  • 2. RESTのための EWD 3 バックエンド • 2つのアプローチが可能 • EWD 3 モジュールを用いて自分の REST を構築する • ewd-xpress を拡張する 2016/9/9 EWD 3 トレーニング・コース #31 2
  • 3. RESTのための EWD 3 バックエンド • EWD 3 モジュールを用いて独自のRESTを構築する • 例えば ewd-qoper8-vistapc がどのように作られたか • 利点 • EWD 3 の部品の内、本当に必要なものだけを利用し、構造を最 適化することができます • 互換性の問題を考えずに、サード・パーティのモジュールを容易に加 えることができます • 欠点 • EWD 3 の部品のインターフェースや統合方法について、十分に理 解している必要があります 2016/9/9 EWD 3 トレーニング・コース #31 3
  • 4. RESTのための EWD 3 バックエンド • ewd-xpress を拡張する • 利点 • 既に必要なものはすべてインストールされ、正しくインターフェースさ れ構成されているのでそれを利用できます • 実際には、他のサード・パーティのモジュールは、非互換性の恐れを あまり考えずに追加することができます • 単一のバックエンドで、Web/RESTサービスと対話的なアプリケー ションを同時にサポートできます • 欠点 • REST/Webサービスのみが必要の場合、対話的なアプリケーショ ン用のコードは利用されません... しかしこれは大したことではない でしょう! 2016/9/9 EWD 3 トレーニング・コース #31 4
  • 5. RESTサービスのための ewd-xpress • 従って、ほとんどの場合、REST/Webサービスを作る には ewd-xpress を用いるのが最善です 2016/9/9 EWD 3 トレーニング・コース #31 5
  • 6. ewd-xpress の起動ファイルの例 var config = { managementPassword: 'keepThisSecret!', serverName: 'My EWD Server', port: 8080, poolSize: 2, database: { type: ‘gtm', params: { // snip } } }; var ewdXpress = require('ewd-xpress').master; ewdXpress.start(config) 2016/9/9 EWD 3 トレーニング・コース #31 6
  • 7. Express ミドルウェアを利用する必要性 • REST/Webサービスをサポートする要点は、ミドル ウェアの Express を追加することです • REST/Web サービスは HTTP(S) 要求と応答を用いま す • Express は特定の URL パスの前方部分を監視する必 要があります • 対応する要求が来たときには、それを処理するためワー カー・プロセスに渡す必要があります 2016/9/9 EWD 3 トレーニング・コース #31 7
  • 8. Express ミドルウェアを利用する必要性 • EWD 3 にはそのようなモジュールが既に用意してあり ます • ewd-qoper8-express • これは ewd-qoper8 を統合する組み込みのルータを含み ます • ewd-xpress はそれを含んでおり、Ajaxメッセージの ためにそれを用いています • REST/Webサービスにおいて直接それを利用するこ とはありません • しかし、直接利用することもできます 2016/9/9 EWD 3 トレーニング・コース #31 8
  • 9. ewd-xpress の起動ファイル var config = { managementPassword: 'keepThisSecret!', serverName: 'My EWD Server', port: 8080, poolSize: 2, database: { type: ‘gtm', params: { // snip } } }; var ewdXpress = require('ewd-xpress').master; var exprss = ewdXpress.intercept(); ewdXpress.start(config) 2016/9/9 EWD 3 トレーニング・コース #31 9
  • 10. ewd-xpress の起動ファイル var config = { managementPassword: 'keepThisSecret!', serverName: 'My EWD Server', port: 8080, poolSize: 2, database: { type: ‘gtm', params: { // snip } } }; var ewdXpress = require('ewd-xpress').master; var exprss = ewdXpress.intercept(); // これで、次のものにアクセスできるようになります // ewd-qoper8 object: exprss.q // ewd-qoper8-xpress: exprss.qx // Express middleware: exprss.app ewdXpress.start(config) 2016/9/9 EWD 3 トレーニング・コース #31 10
  • 11. 単純な Web サービス var config = { managementPassword: 'keepThisSecret!', serverName: 'My EWD Server', port: 8080, poolSize: 2, database: { type: ‘gtm', params: { // snip } } }; var ewdXpress = require('ewd-xpress').master; var exprss = ewdXpress.intercept(); exprss.app.use('/testWebService', exprss.qx.router()); ewdXpress.start(config) 2016/9/9 EWD 3 トレーニング・コース #31 11
  • 12. 単純な Web サービス var config = { managementPassword: 'keepThisSecret!', serverName: 'My EWD Server', port: 8080, poolSize: 2, database: { type: ‘gtm', params: { // snip } } }; var ewdXpress = require('ewd-xpress').master; var exprss = ewdXpress.intercept(); exprss.app.use('/testWebService', exprss.qx.router()); // 「/testWebService」 で始まるURLのリクエストを受信すると、それをワーカーに渡し // 「testWebService」 という名前のモジュールで処理します ewdXpress.start(config) 2016/9/9 EWD 3 トレーニング・コース #31 12
  • 13. 試してみましょう 2016/9/9 EWD 3 トレーニング・コース #31 13
  • 14. 適切な HTTP クライアントを利用する • ブラウザは、GET要求をテストすることしかできません • POST や他の要求 (例えば DELETE、PUT) をテストす る必要もあります • WebサービスやRESTのクライアントが利用できます • Postman • 私は Chrome の Advanced REST Client (ARC) を 用いています 2016/9/9 EWD 3 トレーニング・コース #31 14
  • 15. 試してみましょう 2016/9/9 EWD 3 トレーニング・コース #31 15
  • 16. エラーを修正する • もちろん、要求を処理するバックエンド・モジュールをま だ作っていません • モジュール名は URL パスと同じ名前です • ~/ewd3/node_modules/testWebService.js 2016/9/9 EWD 3 トレーニング・コース #31 16
  • 17. REST を処理するモジュール • ewd-xpress のメッセージを処理するモジュールに極 めて似ています 2016/9/9 EWD 3 トレーニング・コース #31 17
  • 18. REST を処理するモジュール module.exports = { restModule: true, handlers: { // 要求の type 毎に異なるハンドラ関数 } }; 2016/9/9 EWD 3 トレーニング・コース #31 18
  • 19. REST を処理するモジュール module.exports = { restModule: true, // ewd-xpress にこれは RESTハンドラだと教えています handlers: { // 要求の type 毎に異なるハンドラ関数 } }; RESTだけでなく、すべてのWebサービス要求 2016/9/9 EWD 3 トレーニング・コース #31 19
  • 20. REST を処理するモジュール module.exports = { restModule: true, handlers: { {type}: function(messageObj, finished) { // 受信したこの type の要求に対するハンドラ } } }; 2016/9/9 EWD 3 トレーニング・コース #31 20
  • 21. REST を処理するモジュール module.exports = { restModule: true, handlers: { myType: function(messageObj, finished) { // 受信した myType 要求に対するハンドラ } } }; 2016/9/9 EWD 3 トレーニング・コース #31 21
  • 22. REST を処理するモジュール ~/ewd3/node_modules/testWebService.js module.exports = { restModule: true, handlers: { myType: function(messageObj, finished) { // 受信した myType 要求に対するハンドラ } } }; http://192.168.1.100:8080/testWebService/myType 2016/9/9 EWD 3 トレーニング・コース #31 22
  • 23. REST を処理するモジュール ~/ewd3/node_modules/testWebService.js module.exports = { restModule: true, handlers: { myType: function(messageObj, finished) { // 受信した myType 要求に対するハンドラ // URLの残りの部分は、messageObj.properties でアクセス可能 } } }; http://192.168.1.100:8080/testWebService/myType/xyz?a=245&b=rob 2016/9/9 EWD 3 トレーニング・コース #31 23
  • 24. REST を処理するモジュール ~/ewd3/node_modules/testWebService.js module.exports = { restModule: true, handlers: { myType: function(messageObj, finished) { // 受信したメッセージ・オブジェクトを処理し、応答オブジェクトを生成 // finished() 関数を呼び出して終了しなくてはなりません // - 応答オブジェクトをクライアントに送信 // - ワーカー・プロセスを利用可能なプールに戻す finished(responseObject); } } }; http://192.168.1.100:8080/testWebService/myType 2016/9/9 EWD 3 トレーニング・コース #31 24
  • 25. REST を処理するモジュール ~/ewd3/node_modules/testWebService.js module.exports = { restModule: true, handlers: { myType: function(messageObj, finished) { console.log("*** myType messageObj: " + JSON.stringify(messageObj)); finished({ test: 'finished ok' }); } } }; http://192.168.1.100:8080/testWebService/myType 2016/9/9 EWD 3 トレーニング・コース #31 25
  • 26. 試してみましょう 2016/9/9 EWD 3 トレーニング・コース #31 26
  • 27. ewd-xpress のログをみてみる *** myType messageObj: { "type":"ewd-qoper8-xpress", "path":"/testWebService/myType", "method":"GET", "headers":{ "host":"192.168.1.183:8080", "content-type":"application/json" }, "params":{ "type":"myType" }, "query":{}, "application":"testWebService", "expressType":"myType" } 2016/9/9 EWD 3 トレーニング・コース #31 27
  • 28. ewd-xpress のログをみてみる *** myType messageObj: { "type":"ewd-qoper8-xpress", "path":"/testWebService/myType", "method":"GET", "headers":{ "host":"192.168.1.183:8080", "content-type":"application/json" }, "params":{ "type":"myType" }, "query":{}, "application":"testWebService", "expressType":"myType" } 2016/9/9 EWD 3 トレーニング・コース #31 28 受信したHTTP要求のすべての要素 は分解されて、受信したメッセージ・オ ブジェクトの中で利用可能です これは ewd-qoper8-express の ルータが行っていることです
  • 29. 簡単な Webサービス var config = { managementPassword: 'keepThisSecret!', serverName: 'My EWD Server', port: 8080, poolSize: 2, database: { type: ‘gtm', params: { // snip } } }; var ewdXpress = require('ewd-xpress').master; var xprss = ewdXpress.intercept(); exprss.app.use('/testWebService', express.qx.router()); ewdXpress.start(config); 2016/9/9 EWD 3 トレーニング・コース #31 29
  • 30. ewd-xpress のログをみてみる *** myType messageObj: { "type":"ewd-qoper8-xpress", "path":"/testWebService/myType", "method":"GET", "headers":{ "host":"192.168.1.183:8080", "content-type":"application/json" }, "params":{ "type":"myType" }, "query":{}, "application":"testWebService", "expressType":"myType" } 2016/9/9 EWD 3 トレーニング・コース #31 30 REST の type は、expressType と いうプロパティの中に定義されています type プロパティではないことに注意
  • 31. ewd-xpress のログをみてみる *** myType messageObj: { "type":"ewd-qoper8-xpress", "path":"/testWebService/myType", "method":"GET", "headers":{ "host":"192.168.1.183:8080", "content-type":"application/json" }, "params":{ "type":"myType" }, "query":{}, "application":"testWebService", "expressType":"myType" } 2016/9/9 EWD 3 トレーニング・コース #31 31 REST の type は、expressType と いうプロパティの中に定義されています type プロパティではないことに注意 しかし、params.type 経由でも利用 可能です
  • 32. ewd-xpress のログをみてみる *** myType messageObj: { "type":"ewd-qoper8-xpress", "path":"/testWebService/myType", "method":"GET", "headers":{ "host":"192.168.1.183:8080", "content-type":"application/json" }, "params":{ "type":"myType" }, "query":{}, "application":"testWebService", "expressType":"myType" } 2016/9/9 EWD 3 トレーニング・コース #31 32 メソッドを知りたいということがしばしばあ ります 例えば、GET か POST か
  • 33. ewd-xpress のログをみてみる *** myType messageObj: { "type":"ewd-qoper8-xpress", "path":"/testWebService/myType", "method":"GET", "headers":{ "host":"192.168.1.183:8080", "content-type":"application/json" }, "params":{ "type":"myType" }, "query":{}, "application":"testWebService", "expressType":"myType" } 2016/9/9 EWD 3 トレーニング・コース #31 33 また、ヘッダーの情報を使いたい場合も あります 特に、セキュリティの処理などに使う場 合です
  • 34. REST を処理するモジュール ~/ewd3/node_modules/testWebService.js module.exports = { restModule: true, handlers: { myType: function(messageObj, finished) { // 受信した myType 要求に対するハンドラ // URLの残りの部分は、messageObj.properties でアクセス可能 } } }; http://192.168.1.100:8080/testWebService/myType/xyz?a=245&b=rob 2016/9/9 EWD 3 トレーニング・コース #31 34
  • 35. 試してみましょう 2016/9/9 EWD 3 トレーニング・コース #31 35
  • 36. ewd-xpress のログをみてみる *** myType messageObj: { "type":"ewd-qoper8-xpress", "path":"/testWebService/myType/xyz?a=245&b=rob", "method":"GET", "headers":{ "host":"192.168.1.183:8080", "content-type":"application/json" }, "params":{ "0":"xyz", "type":"myType" }, "query":{ "a":"245", "b":"rob" }, "application":"testWebService", "expressType":"myType" } 2016/9/9 EWD 3 トレーニング・コース #31 36
  • 37. ewd-xpress のログをみてみる *** myType messageObj: { "type":"ewd-qoper8-xpress", "path":"/testWebService/myType/xyz?a=245&b=rob", "method":"GET", "headers":{ "host":"192.168.1.183:8080", "content-type":"application/json" }, "params":{ "0":"xyz", "type":"myType" }, "query":{ "a":"245", "b":"rob" }, "application":"testWebService", "expressType":"myType" } 2016/9/9 EWD 3 トレーニング・コース #31 37 完全なパスを得ることができ ます
  • 38. ewd-xpress のログをみてみる *** myType messageObj: { "type":"ewd-qoper8-xpress", "path":"/testWebService/myType/xyz?a=245&b=rob", "method":"GET", "headers":{ "host":"192.168.1.183:8080", "content-type":"application/json" }, "params":{ "0":"xyz", "type":"myType" }, "query":{ "a":"245", "b":"rob" }, "application":"testWebService", "expressType":"myType" } 2016/9/9 EWD 3 トレーニング・コース #31 38 URL パスの 3 番目の部分 は、 params['0'] に入っ ています
  • 39. ewd-xpress のログをみてみる *** myType messageObj: { "type":"ewd-qoper8-xpress", "path":"/testWebService/myType/xyz?a=245&b=rob", "method":"GET", "headers":{ "host":"192.168.1.183:8080", "content-type":"application/json" }, "params":{ "0":"xyz", "type":"myType" }, "query":{ "a":"245", "b":"rob" }, "application":"testWebService", "expressType":"myType" } 2016/9/9 EWD 3 トレーニング・コース #31 39 URL の問い合わせ文字列 の名前/値のペアは、パース されて query オブジェクト に入ります query.a query.b
  • 40. さらに長い URL の場合は? 2016/9/9 EWD 3 トレーニング・コース #31 40
  • 41. 試してみましょう 2016/9/9 EWD 3 トレーニング・コース #31 41
  • 42. ewd-xpress のログをみてみる *** myType messageObj: { "type":"ewd-qoper8-xpress", "path":"/testWebService/myType/how/about/this?a=245&b=rob", "method":"GET", "headers":{ "host":"192.168.1.183:8080", "content-type":"application/json" }, "params":{ "0":"how/about/this", "type":"myType" }, "query":{ "a":"245", "b":"rob" }, "application":"testWebService", "expressType":"myType" } 2016/9/9 EWD 3 トレーニング・コース #31 42 URL の追加部分は、すべてひとつにして params['0'] の中に入っています
  • 43. ewd-xpress のログをみてみる *** myType messageObj: { "type":"ewd-qoper8-xpress", "path":"/testWebService/myType/how/about/this?a=245&b=rob", "method":"GET", "headers":{ "host":"192.168.1.183:8080", "content-type":"application/json" }, "params":{ "0":"how/about/this", "type":"myType" }, "query":{ "a":"245", "b":"rob" }, "application":"testWebService", "expressType":"myType" } 2016/9/9 EWD 3 トレーニング・コース #31 43 URL の追加部分は、すべてひとつにして params['0'] の中に入っています var pathArr =params['0'].split('/'); でパースすることができます
  • 44. POST + 搭載物(ペイロード) の処理 • 搭載物(ペイロード)/本体 を送る他の HTTP メソッ ドにも次のことが適用されます 2016/9/9 EWD 3 トレーニング・コース #31 44
  • 45. POST + 搭載物(ペイロード) の処理 • ewd-xpress はもともと JSONベースの REST/ Webサービスのために設計されました • 搭載物(ペイロード)/本体 は JSON でなくてはなりません • ewd-xpress は実際には、どのような content- type でも処理することができます • しかし、他のバックエンドの NPM モジュールを追加して構成 する必要があります • ここでは、application/json のコンテンツに焦点を絞 ります 2016/9/9 EWD 3 トレーニング・コース #31 45
  • 46. 試してみましょう 2016/9/9 EWD 3 トレーニング・コース #31 46 POSTメソッド コンテント・タイプに注意 JSON のペイロード 注意: これは適切な JSON 書 式でなくてはならず、JavaScript の文字列フォーマットではいけませ ん 即ち、名前も値も「"」で囲みます
  • 47. 試してみましょう 2016/9/9 EWD 3 トレーニング・コース #31 47 成功した結果
  • 48. ewd-xpress のログでは *** myType messageObj: { "type":"ewd-qoper8-xpress", "path":"/testWebService/myType/", "method":"POST", "headers":{ "host":"192.168.1.183:8080", "content-type":"application/json", "content-length":"30" }, "params":{ "type":"myType" }, "query":{}, "application":"testWebService", "expressType":"myType" } 2016/9/9 EWD 3 トレーニング・コース #31 48 コンテンツがあったと記録されています
  • 49. ewd-xpress のログでは *** myType messageObj: { "type":"ewd-qoper8-xpress", "path":"/testWebService/myType/", "method":"POST", "headers":{ "host":"192.168.1.183:8080", "content-type":"application/json", "content-length":"30" }, "params":{ "type":"myType" }, "query":{}, "application":"testWebService", "expressType":"myType" } 2016/9/9 EWD 3 トレーニング・コース #31 49 しかし、本体/ペイロードはどこに?
  • 50. Express のコンテントのパーシング • Express では、搭載物(ペイロード)/本体の中の JSON をパースするには、そのように明確に指示しなく てはなりません • ミドルウェアはそのためにあるのです! • body-parser という名前の NPM モジュールがあります • これをインストールしなくてはなりません • 実際には、ewd-xpress をインストールしたときに、これは自動的 にインストールされています • ~/ewd3/node_modules/body-parser を見てください • しかし、これをロードして利用するには、ewd-xpress のスタート・アッ プファイル内で明確に指定しなくてはなりません 2016/9/9 EWD 3 トレーニング・コース #31 50
  • 51. ewd-xpress の起動ファイルを編集する var config = { managementPassword: 'keepThisSecret!', serverName: 'My EWD Server', port: 8080, poolSize: 2, database: { type: ‘gtm', params: { // snip } } }; var ewdXpress = require('ewd-xpress').master; var exprss = ewdXpress.intercept(); var bodyParser = require('body-parser'); exprss.app.use(bodyParser.json()); express.app.use('/testWebService', express.qx.router()); ewdXpress.start(config) 2016/9/9 EWD 3 トレーニング・コース #31 51
  • 52. ewd-xpress を再起動して再試行 2016/9/9 EWD 3 トレーニング・コース #31 52
  • 53. ewd-xpress のログでは *** myType messageObj: { "type":"ewd-qoper8-xpress", "path":"/testWebService/myType/", "method":"POST", "headers":{ "host":"192.168.1.183:8080", "content-type":"application/json", "content-length":"30" }, "params":{ "type":"myType" }, "query":{}, "body":{ "c":"hello", "d":"world" }, "application":"testWebService", "expressType":"myType" } 2016/9/9 EWD 3 トレーニング・コース #31 53 本体(body)の内容は、パースされて、 messageObj.body の中で利用できます
  • 54. 本体 + 名前/値 のペア? • POST された HTTP 要求に、本体/搭載物(ペイ ロード) だけでなく • もっと URL パスの長いもの • 追加的な 名前/値のペア の問い合わせ文字列 をもつことはできるでしょうか? 2016/9/9 EWD 3 トレーニング・コース #31 54
  • 55. 試してみましょう 2016/9/9 EWD 3 トレーニング・コース #31 55 試すURLはココ ペイロードを組み 合わせる 正常に稼働している
  • 56. また ewd-xpress のログをチェック *** myType messageObj: { "type":"ewd-qoper8-xpress", "path":"/testWebService/myType/how/about/this?a=123&b=rob", "method":"POST", "headers":{ "host":"192.168.1.183:8080", "content-type":"application/json", "content-length":"30" }, "params":{ "0":"how/about/this", "type":"myType" }, "query":{ "a":"123" "b":"rob" }, "body":{ "c":"hello", "d":"world" }, "application":"testWebService", "expressType":"myType" } 2016/9/9 EWD 3 トレーニング・コース #31 56 長い URL パスはこちら
  • 57. また ewd-xpress のログをチェック *** myType messageObj: { "type":"ewd-qoper8-xpress", "path":"/testWebService/myType/how/about/this?a=123&b=rob", "method":"POST", "headers":{ "host":"192.168.1.183:8080", "content-type":"application/json", "content-length":"30" }, "params":{ "0":"how/about/this", "type":"myType" }, "query":{ "a":"123" "b":"rob" }, "body":{ "c":"hello", "d":"world" }, "application":"testWebService", "expressType":"myType" } 2016/9/9 EWD 3 トレーニング・コース #31 57 URL の残りの部分はパースされてここに
  • 58. また ewd-xpress のログをチェック *** myType messageObj: { "type":"ewd-qoper8-xpress", "path":"/testWebService/myType/how/about/this?a=123&b=rob", "method":"POST", "headers":{ "host":"192.168.1.183:8080", "content-type":"application/json", "content-length":"30" }, "params":{ "0":"how/about/this", "type":"myType" }, "query":{ "a":"123" "b":"rob" }, "body":{ "c":"hello", "d":"world" }, "application":"testWebService", "expressType":"myType" } 2016/9/9 EWD 3 トレーニング・コース #31 58 問い合わせ文字列の 名前/値 のペアを保 持する query オブジェクトはここに
  • 59. また ewd-xpress のログをチェック *** myType messageObj: { "type":"ewd-qoper8-xpress", "path":"/testWebService/myType/how/about/this?a=123&b=rob", "method":"POST", "headers":{ "host":"192.168.1.183:8080", "content-type":"application/json", "content-length":"30" }, "params":{ "0":"how/about/this", "type":"myType" }, "query":{ "a":"123" "b":"rob" }, "body":{ "c":"hello", "d":"world" }, "application":"testWebService", "expressType":"myType" } 2016/9/9 EWD 3 トレーニング・コース #31 59 POST された搭載物(ペイロード)を含む body オブジェクトがここに
  • 60. バックエンドの REST type ハンドラ • これで、バックエンドの type ハンドラ関数には、受信し た REST および Webサービスへの要求の処理必要 な情報がすべて渡されました • これをどのように処理するかはあなた次第です • データベースへは次の方法でアクセスできます • this.db • 例えば this.db.function() で従来のMUMPSコードを呼び出 す • this.documentStore 2016/9/9 EWD 3 トレーニング・コース #31 60
  • 61. 例えば • ~/ewd3/node_modules/testWebService.js module.exports = { restModule: true, handlers: { myType: function(messageObj, finished) { console.log('*** myType messageObj: ' + JSON.stringify(messageObj)); console.log(this.db.version()); var doc = new this.documentStore.DocumentNode('myDoc'); var myObj = { hello: 'world' } doc.setDocument(myObj); finished({ test: 'finished ok' }); } } }; 2016/9/9 EWD 3 トレーニング・コース #31 61
  • 63. バックエンド・モジュールの違いの要点 • ~/ewd3/node_modules/testWebService.js module.exports = { restModule: true, handlers: { myType: function(messageObj, finished) { console.log('*** myType messageObj: ' + JSON.stringify(messageObj)); finished({ test: 'finished ok' }); } } }; 2016/9/9 EWD 3 トレーニング・コース #31 63 send() 関数なし EWDセッションなし
  • 64. send 関数がない? • REST と Webサービスは、HTTPベース • ひとつの要求がひとつの応答を生成します • 従って、中間メッセージは不適切です 2016/9/9 EWD 3 トレーニング・コース #31 64
  • 65. send 関数がない? • REST と Webサービスは、HTTPベース • ひとつの要求がひとつの応答を生成します • 従って、中間メッセージは不適切です • それがあっても良いですが、しかし、ある/すべてのブラウザに メッセージを送るハンドラ関数は、web-socket 経由です! 2016/9/9 EWD 3 トレーニング・コース #31 65
  • 66. EWD セッションがない? • REST と Webサービスは、ステート(状態)レスです • アプリケーションにはリンクしません • 暗黙的な EWD セッションは不適切です 2016/9/9 EWD 3 トレーニング・コース #31 66
  • 67. EWD セッションがない? • REST と Webサービスは、ステート(状態)レスです • アプリケーションにはリンクしません • 暗黙的な EWD セッションは不適切です • しかし、独自のハンドラで EWD セッションを生成し維 持することは可能です • このために ewd-session モジュールを使うことができます • this.sessions • これが何かというこを知っている必要はあります 2016/9/9 EWD 3 トレーニング・コース #31 67
  • 68. REST/Webサービスでセッションを使う • ログイン要求のハンドラを作ります • セキュリティのためには、POST 要求であるべきでしょう • ユーザー名、パスワードは本体の搭載物(ペイロード) 内に定義されるべきです 2016/9/9 EWD 3 トレーニング・コース #31 68
  • 69. REST/Webサービスでセッションを使う function checkLogin(username,password) { if (username !== 'rob') return {error: 'Invalid username'}; if (password !== 'secret') return {error: 'Invalid password'}; return {ok: true} }; module.exports = { restModule: true, handlers: { login: function(messageObj, finished) { if (messageObj.method !== 'POST') { finished({error: 'login message must use POST method'}); return; } var username = messageObj.body.username; if (!username || username === '') { finished({error: 'You must provide a username'}); return; } var password = messageObj.body.password; if (!password || password === '') { finished({error: 'You must provide a password'}); return; } var status = checkLogin(username, password); if (status.error) { finished(status); return; } var session = this.sessios.create('testWebService', 3600); session.authenticated = true; finished({token: session.token}); } } } 2016/9/9 EWD 3 トレーニング・コース #31 69
  • 70. REST/Webサービスでセッションを使う function checkLogin(username,password) { if (username !== 'rob') return {error: 'Invalid username'}; if (password !== 'secret') return {error: 'Invalid password'}; return {ok: true} }; module.exports = { restModule: true, handlers: { login: function(messageObj, finished) { if (messageObj.method !== 'POST') { finished({error: 'login message must use POST method'}); return; } var username = messageObj.body.username; if (!username || username === '') { finished({error: 'You must provide a username'}); return; } var password = messageObj.body.password; if (!password || password === '') { finished({error: 'You must provide a password'}); return; } var status = checkLogin(username, password); if (status.error) { finished(status); return; } var session = this.sessios.create('testWebService', 3600); session.authenticated = true; finished({token: session.token}); } } } 2016/9/9 EWD 3 トレーニング・コース #31 70 セキュリティ上の理由で、POST要求で なくてはなりません
  • 71. REST/Webサービスでセッションを使う function checkLogin(username,password) { if (username !== 'rob') return {error: 'Invalid username'}; if (password !== 'secret') return {error: 'Invalid password'}; return {ok: true} }; module.exports = { restModule: true, handlers: { login: function(messageObj, finished) { if (messageObj.method !== 'POST') { finished({error: 'login message must use POST method'}); return; } var username = messageObj.body.username; if (!username || username === '') { finished({error: 'You must provide a username'}); return; } var password = messageObj.body.password; if (!password || password === '') { finished({error: 'You must provide a password'}); return; } var status = checkLogin(username, password); if (status.error) { finished(status); return; } var session = this.sessios.create('testWebService', 3600); session.authenticated = true; finished({token: session.token}); } } } 2016/9/9 EWD 3 トレーニング・コース #31 71 ユーザ名とパスワードは、要求の本体 (body) から得られます
  • 72. REST/Webサービスでセッションを使う function checkLogin(username,password) { if (username !== 'rob') return {error: 'Invalid username'}; if (password !== 'secret') return {error: 'Invalid password'}; return {ok: true} }; module.exports = { restModule: true, handlers: { login: function(messageObj, finished) { if (messageObj.method !== 'POST') { finished({error: 'login message must use POST method'}); return; } var username = messageObj.body.username; if (!username || username === '') { finished({error: 'You must provide a username'}); return; } var password = messageObj.body.password; if (!password || password === '') { finished({error: 'You must provide a password'}); return; } var status = checkLogin(username, password); if (status.error) { finished(status); return; } var session = this.sessios.create('testWebService', 3600); session.authenticated = true; finished({token: session.token}); } } } 2016/9/9 EWD 3 トレーニング・コース #31 72 ユーザ名とパスワードの検証 もし正しくなければエラー応答を返す
  • 73. REST/Webサービスでセッションを使う function checkLogin(username,password) { if (username !== 'rob') return {error: 'Invalid username'}; if (password !== 'secret') return {error: 'Invalid password'}; return {ok: true} }; module.exports = { restModule: true, handlers: { login: function(messageObj, finished) { if (messageObj.method !== 'POST') { finished({error: 'login message must use POST method'}); return; } var username = messageObj.body.username; if (!username || username === '') { finished({error: 'You must provide a username'}); return; } var password = messageObj.body.password; if (!password || password === '') { finished({error: 'You must provide a password'}); return; } var status = checkLogin(username, password); if (status.error) { finished(status); return; } var session = this.sessios.create('testWebService', 3600); session.authenticated = true; finished({token: session.token}); } } } 2016/9/9 EWD 3 トレーニング・コース #31 73 認証が正しければ、testWebService という名前のアプリケーション用に、新しい EWDセッションを作ります このセッションの有効期限は1時間です
  • 74. REST/Webサービスでセッションを使う function checkLogin(username,password) { if (username !== 'rob') return {error: 'Invalid username'}; if (password !== 'secret') return {error: 'Invalid password'}; return {ok: true} }; module.exports = { restModule: true, handlers: { login: function(messageObj, finished) { if (messageObj.method !== 'POST') { finished({error: 'login message must use POST method'}); return; } var username = messageObj.body.username; if (!username || username === '') { finished({error: 'You must provide a username'}); return; } var password = messageObj.body.password; if (!password || password === '') { finished({error: 'You must provide a password'}); return; } var status = checkLogin(username, password); if (status.error) { finished(status); return; } var session = this.sessios.create('testWebService', 3600); session.authenticated = true; finished({token: session.token}); } } } 2016/9/9 EWD 3 トレーニング・コース #31 74 このセッションは認証済というフラグ
  • 75. REST/Webサービスでセッションを使う function checkLogin(username,password) { if (username !== 'rob') return {error: 'Invalid username'}; if (password !== 'secret') return {error: 'Invalid password'}; return {ok: true} }; module.exports = { restModule: true, handlers: { login: function(messageObj, finished) { if (messageObj.method !== 'POST') { finished({error: 'login message must use POST method'}); return; } var username = messageObj.body.username; if (!username || username === '') { finished({error: 'You must provide a username'}); return; } var password = messageObj.body.password; if (!password || password === '') { finished({error: 'You must provide a password'}); return; } var status = checkLogin(username, password); if (status.error) { finished(status); return; } var session = this.sessios.create('testWebService', 3600); session.authenticated = true; finished({token: session.token}); } } } 2016/9/9 EWD 3 トレーニング・コース #31 75 最後に、/login の応答として、セッショ ン・トークンを返します
  • 76. 試してみましょう 2016/9/9 EWD 3 トレーニング・コース #31 76 ログイン URL 間違ったパスワードを JSON のペイロードとして POSTする エラー応答
  • 77. 試してみましょう 2016/9/9 EWD 3 トレーニング・コース #31 77 ログイン URL エラー応答 GET を用い、問い合わせ 文字列にユーザ名とパス ワードを指定する
  • 78. 試してみましょう 2016/9/9 EWD 3 トレーニング・コース #31 78 今回はセッション・ トークンが返される 正しいユーザ名とパスワード をPOSTのペイロードとして 渡す
  • 79. 次は何? • 次に続く要求は、通常ヘッダ内に、セッション・トークン を返します • 例えば、権限付与ヘッダー • バックエンドの要求ハンドラは、要求を認証しなくてはな りません • トークンが正しく、期限切れでないことをチェックします • するとハンドラーは、ユーザーが続けている会話の一時 データのためにセッションを用いることができます 2016/9/9 EWD 3 トレーニング・コース #31 79
  • 80. REST/Web サービスでセッションを用いる module.exports = { restModule: true, handlers: { login: function(messageObj, finished) { // 以前に示した通り }, doSomethingNext: function(messageObj, finished) { var token = messageOgj.headers.authorization; if (!token || token === '') { finished({error: 'Missing authorization token'}); return; } var status = this.sessions.authenticate(token); if (status.error) { finished(status); return; } var session = status.session; // ユーザの要求の認証に成功した // ユーザーのセッションを適切に用いるためのアクセス権を持っています // ここで要求のコンテンツ/ペイロードを用いて、すべきことを何でもすることができます // 最後に応答オブジェクト(responseObj)を作ります finished(responseObj); } } 2016/9/9 EWD 3 トレーニング・コース #31 80
  • 81. REST/Web サービスでセッションを用いる module.exports = { restModule: true, handlers: { login: function(messageObj, finished) { // 以前に示した通り }, doSomethingNext: function(messageObj, finished) { var token = messageOgj.headers.authorization; if (!token || token === '') { finished({error: 'Missing authorization token'}); return; } var status = this.sessions.authenticate(token); if (status.error) { finished(status); return; } var session = status.session; // ユーザの要求の認証に成功した // ユーザーのセッションを適切に用いるためのアクセス権を持っています // ここで要求のコンテンツ/ペイロードを用いて、すべきことを何でもすることができます // 最後に応答オブジェクト(responseObj)を作ります finished(responseObj); } } 2016/9/9 EWD 3 トレーニング・コース #31 81 要求に権限認証ヘッダが付い ていることを確認する
  • 82. REST/Web サービスでセッションを用いる module.exports = { restModule: true, handlers: { login: function(messageObj, finished) { // 以前に示した通り }, doSomethingNext: function(messageObj, finished) { var token = messageOgj.headers.authorization; if (!token || token === '') { finished({error: 'Missing authorization token'}); return; } var status = this.sessions.authenticate(token); if (status.error) { finished(status); return; } var session = status.session; // ユーザの要求の認証に成功した // ユーザーのセッションを適切に用いるためのアクセス権を持っています // ここで要求のコンテンツ/ペイロードを用いて、すべきことを何でもすることができます // 最後に応答オブジェクト(responseObj)を作ります finished(responseObj); } } 2016/9/9 EWD 3 トレーニング・コース #31 82 セッション・トークンを認証する
  • 83. REST/Web サービスでセッションを用いる module.exports = { restModule: true, handlers: { login: function(messageObj, finished) { // 以前に示した通り }, doSomethingNext: function(messageObj, finished) { var token = messageOgj.headers.authorization; if (!token || token === '') { finished({error: 'Missing authorization token'}); return; } var status = this.sessions.authenticate(token); if (status.error) { finished(status); return; } var session = status.session; // ユーザの要求の認証に成功した // ユーザーのセッションを適切に用いるためのアクセス権を持っています // ここで要求のコンテンツ/ペイロードを用いて、すべきことを何でもすることができます // 最後に応答オブジェクト(responseObj)を作ります finished(responseObj); } } 2016/9/9 EWD 3 トレーニング・コース #31 83 トークンは正しく、期限切れでもない 従ってユーザーのセッションにアクセス することができる
  • 84. REST/Web サービスでセッションを用いる module.exports = { restModule: true, handlers: { login: function(messageObj, finished) { // 以前に示した通り }, doSomethingNext: function(messageObj, finished) { var token = messageOgj.headers.authorization; if (!token || token === '') { finished({error: 'Missing authorization token'}); return; } var status = this.sessions.authenticate(token); if (status.error) { finished(status); return; } var session = status.session; // ユーザの要求の認証に成功した // ユーザーのセッションを適切に用いるためのアクセス権を持っています // ここで要求のコンテンツ/ペイロードを用いて、すべきことを何でもすることができます // 最後に応答オブジェクト(responseObj)を作ります finished(responseObj); } } 2016/9/9 EWD 3 トレーニング・コース #31 84 必要な処理をして、応答オブジェ クトを返す
  • 85. 試してみましょう 2016/9/9 EWD 3 トレーニング・コース #31 85 /doSomethingNext という要求を送る エラー応答 間違った、あるいは 期限切れのトークン
  • 86. 試してみましょう 2016/9/9 EWD 3 トレーニング・コース #31 86 エラー応答 権限付与するヘッダーが 定義されていない
  • 87. 試してみましょう 2016/9/9 EWD 3 トレーニング・コース #31 87 今度は成功 権限付与ヘッダーに 正しいtokenがある
  • 88. セッションのログアウト? • 明示的な /logout 要求は必要ありません • セッションは自動的に期限切れになります • もしログアウトしたければ、セッションを非認証にセットす ることができます • session.authenticated = false; 2016/9/9 EWD 3 トレーニング・コース #31 88
  • 90. REST と Web サービス • これであなたの ewd-xpress システム上で REST と Web サービスをサポートするために必要なものはすべ て揃いました • 同じ ewd-xpress サーバー上で 対話的なアプリケーショ ンをサポートするのに加えてです • ewd-xpress の起動ファイルに、REST/Webサー ビスを、必要ならどれだけでも加え、定義することができ ます 2016/9/9 EWD 3 トレーニング・コース #31 90
  • 91. ewd-xpress 起動ファイルの拡張 var config = { managementPassword: 'keepThisSecret!', serverName: 'My EWD Server', port: 8080, poolSize: 2, database: { type: ‘gtm', params: { // snip } } }; var ewdXpress = require('ewd-xpress').master, var exprss = ewdXpress.intercept(); var bodyParser = require('body-parser'); exprss.app.use(bodyParser.json()); exprss.app.use('/testWebService', exprss.qx.router()); exprss.app.use('/accounts', exprss.qx.router()); exprss.app.use('/stockControl', exprss.qx.router()); ewdXpress.start(config); 2016/9/9 EWD 3 トレーニング・コース #31 91 そして、対応するモジュールを /node_modules の中に作 ります - accounts.js - stockControl.js