先日紹介した Windows Azure SDK for Node.js でテーブルストレージを利用する〜失敗編?〜 id:waritohutsu:20120126:1327602448 では、ストレージサービスのアクセスに失敗していたことが分かった。今回は、更に検証し、ストレージサービスに無事疎通が完了したノウハウを共有する。
本記事のサンプルを利用するには、以下のコマンドを実行して必須ライブラリのインストールが完了していることが前提になることに留意して頂きたい。
>npm install azure node-uuid
ローカルエミュレータのテーブルストレージへアクセス
以下のコードでストレージサービスにデータを挿入することが可能
- テーブルストレージへの挿入(基礎編)
var azure = require('azure'); var ServiceClient = azure.ServiceClient; var TableQuery = azure.TableQuery; var uuid = require('node-uuid'); var tableName = 'posts'; var partition = 'part1'; var tableClient = azure.createTableService(ServiceClient.DEVSTORE_STORAGE_ACCOUNT, ServiceClient.DEVSTORE_STORAGE_ACCESS_KEY, ServiceClient.DEVSTORE_TABLE_HOST); tableClient.createTableIfNotExists(tableName, function (err, created) { console.log('Setting up demo data ...'); //「var now = new Date().toString();」 だと「Thu Feb 09 2012 01:48:37 GMT+0900 (東京 (標準時))」とかで半角が入って死ぬ var now = new Date().toGMTString(); var entity = { PartitionKey: partition, RowKey: uuid(), title: 'Post one', body: 'Body one', created_at: now }; tableClient.insertEntity(tableName, entity, null, function(err){ console.log(err); }); });
上記はエンティティの挿入ごとにトランザクションが発生する例だが、Entity Group Transaction も利用可能だ。以下に利用例を記載する。
- テーブルストレージへの挿入(Entity Group Transaction編)
var azure = require('azure'); var ServiceClient = azure.ServiceClient; var TableQuery = azure.TableQuery; var uuid = require('node-uuid'); var tableName = 'posts'; var partition = 'part1'; tableClient = azure.createTableService( ServiceClient.DEVSTORE_STORAGE_ACCOUNT, ServiceClient.DEVSTORE_STORAGE_ACCESS_KEY, ServiceClient.DEVSTORE_TABLE_HOST); tableClient.createTableIfNotExists(tableName, function (err, created) { if (created) { console.log('Setting up demo data ...'); //トランザクションの開始を宣言 tableClient.beginBatch(); var now = new Date().toGMTString(); tableClient.insertEntity(tableName, { PartitionKey: partition, RowKey: uuid(), title: 'Post one', body: 'Body one', created_at: now }); tableClient.insertEntity(tableName, { PartitionKey: partition, RowKey: uuid(), title: 'Post two', body: 'Body two', created_at: now }); tableClient.insertEntity(tableName, { PartitionKey: partition, RowKey: uuid(), title: 'Post three', body: 'Body three', created_at: now }); tableClient.insertEntity(tableName, { PartitionKey: partition, RowKey: uuid(), title: 'Post four', body: 'Body four', created_at: now }); //トランザクションを実行 tableClient.commitBatch(function () { console.log('Done'); }); } });
時刻の文字列を取得する際に、 new Date().toString() の場合には日本語が入ってしまう。私が試した時点の Node.js 版のストレージサービス・ライブラリは日本語が取り扱えなかったため、「テーブルストレージの挿入(基礎編)」では以下のエラーログが出力された。
C:\tmp\MyService\WorkerRole1>node.exe server.js Setting up demo data ... { code: 'OutOfRangeInput', message: 'One of the request inputs is out of range.' } var now = new Date().toGMTString();
次に、テーブルストレージの検索例を以下に記載する。
- テーブルストレージの検索
var azure = require('azure'); var ServiceClient = azure.ServiceClient; var TableQuery = azure.TableQuery; var uuid = require('node-uuid'); var tableName = 'posts'; var partition = 'part1'; tableClient = azure.createTableService( ServiceClient.DEVSTORE_STORAGE_ACCOUNT, ServiceClient.DEVSTORE_STORAGE_ACCESS_KEY, ServiceClient.DEVSTORE_TABLE_HOST); var tableQuery = TableQuery.select().from(tableName); tableClient.queryEntities(tableQuery, function( error, posts ){ console.log(posts.length) if( posts.length > 0 ){ console.log( posts[0] ); } });
以下の様にデータが取得できる。エンティティに対してのプロパティ(posts[i].body等)で値を取得が可能だ。
>node.exe table-main.js 4 { id: 'http://127.0.0.1:10002/devstoreaccount1/posts(PartitionKey=\'part10\',Row link: 'posts(PartitionKey=\'part10\',RowKey=\'0e04ff7f-5fe8-4c8b-b971-c1e30306 updated: '2012-02-11T08:04:30Z', etag: 'W/"datetime\'2012-02-09T15%3A17%3A15.88Z\'"', PartitionKey: 'part10', RowKey: '0e04ff7f-5fe8-4c8b-b971-c1e3030600cb', Timestamp: Thu, 09 Feb 2012 15:17:15 GMT, title: 'Post four', body: 'Body four', created_at: 'Thu, 09 Feb 2012 15:17:15 GMT' } (省略)
ストレージサービス(本番)へのアクセス
本番側へアクセスする際に留意事項が存在ので紹介する。TableClientを作成する createTableService() メソッドの第三引数に対し、本番アクセス用のURLを渡すとDNS解決の失敗を示すエラーが表示された。テーブルストレージに対し、カスタムドメイン等を設定していなければ以下の例に従う事を推奨したい。
var azure = require('azure'); var ServiceClient = azure.ServiceClient; var TableQuery = azure.TableQuery; var uuid = require('node-uuid'); var tableName = 'posts'; var partition = 'part1'; tableClient = azure.createTableService( "<アカウント名>", "<プライマリキー>");