[AWS]proxyを使用してAWSのAPIモックを作成[node]

2013.05.08

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

AWSのモック

また、先日node用AWS SDKの正式版がリリースされました
私はpre8あたりからあまりさわっておらず、proxy機能が追加された事も知りませんでした。
本来これは、AWSサービスをプロキシサーバ経由で使用できるようにするオプションだと思いますが、
これを使用すれば AWSのAPIモックが簡単につくれるのでは?と思いました。(モック用途にも使ったりするの?)
実用性があるか知りませんが、proxyを試しつつAPIモックサーバをつくってみましょう。

環境構築方法

今回使用した動作環境は以下のとおりです。

  • OS : MacOS X 10.7.5
  • node : 0.10.4
  • express : 3.2.0
  • AWS SDK for Node : 1.0.0

aws-sdkを使った簡単なサンプルを作成

まずは簡単なクライアント用サンプルを作成します。aws-sdkをインストールして環境設定しましょう。

% mkdir awssample
% cd awssample
% npm install aws-sdk

credentials.jsonを作成し、AWSアカウント情報を設定。

{
    "accessKeyId":"<アクセスキー>",
    "secretAccessKey":"<シークレットアクセスキー>",
    "region":"<リージョン>"
}

client.jsを作成します。ここでは、S3へアクセスしてバケットのリストを取得するだけです。
当然ながら、アカウントが正しくなかったり、インターネットへ接続していなかったりすればエラーになってしまいます。

//client.js
var AWS = require('aws-sdk');
AWS.config.loadFromPath('credentials.json');

var s3 = new AWS.S3();
s3.listBuckets({}, function (err, data) {
  if(err) throw err;
  
  console.log(data);
});

そこで、proxyオプションを追加し、直接AWSへアクセスするのではなく、プロキシサーバを経由するようにしましょう。
アカウント情報を読み込んだ後、update関数でhttpOptions.proxyを設定します。
ここではlocalhost:8080を指定しています。(プロキシサーバはこの後作成)

var AWS = require('aws-sdk');
AWS.config.loadFromPath('credentials.json');
AWS.config.update({
  httpOptions: {
    proxy: 'http://localhost:8080'
  }
});
・
・

プロキシサーバを作成

次に、先ほどproxyで指定したサーバアプリを作成します。面倒なのでexpressでひな形をつくる。

% npm install -g express #インストールしてなければ
% express proxy-server
% cd proxy-server

生成されたapp.jsを修正します。proxy-serverアプリの起動ポートを8080に変更し、
connect middlewareを使ってすべてのリクエストをハンドリングするように修正します。
今回はとりあえず、S3のバケットのリストを返すXMLを返すようにしました。
実際はリクエストされた内容に応じてXMLを変えたり、リクエストパラメータで返すXMLを指定するようにすれば楽だと思います。

・
・
app.set('port', process.env.PORT || 8080);
・
・
//すべてのリクエストをここでハンドリング
app.use(function(req,res,next){
    console.log('%s:%s', req.method, req.url);
    res.set('Content-Type', 'application/xml');
    //S3のバケットリストを返すXMLを返す.
    res.send('<?xml version="1.0" encoding="UTF-8"?><ListAllMyBucketsResult xmlns="http://doc.s3.amazonaws.com/2006-03-01"><Owner><ID>bcaf1ffd86f461ca5fb16fd081034f</ID><DisplayName>webfile</DisplayName></Owner><Buckets><Bucket><Name>quotes</Name><CreationDate>2006-02-03T16:45:09.000Z</CreationDate></Bucket><Bucket><Name>samples</Name><CreationDate>2006-02-03T16:41:58.000Z</CreationDate></Bucket></Buckets></ListAllMyBucketsResult>');
    //next();
});

//middlewareはrouterセットの前に記述すること
app.use(app.router);
・
・

返しているXMLはここで見たsample responseです。

プロキシサーバアプリを起動し、先ほどhttpOptions.proxyを指定したclient.jsを実行してみましょう。
バケット取得メソッドの結果として、プロキシサーバで記述したXMLがかえってきます。

% cd /path/your/proxy-server 
% node app.js &
% cd /path/your/awssample
% node client.js
{ Buckets:
   [ { Name: 'quotes',
       CreationDate: Sat Feb 04 2006 01:45:09 GMT+0900 (JST) },
     { Name: 'samples',
       CreationDate: Sat Feb 04 2006 01:41:58 GMT+0900 (JST) } ],
  Owner: { ID: 'bcaf1ffd86f461ca5fb16fd081034f', DisplayName: 'webfile' },
  RequestId: undefined }

まとめ

aws-sdkのproxyの仕組みを利用して、APIモックをためしてみました。
最近のアプリではなくてはならないサービスとなっているAWSですが、APIを使用してS3やDynamo等のサービスを使用している場合、
ネットに接続していないければ動きませんし、テスト等でアクセスするだけでも微妙にお金がかかります。(本当に微々たるものですが)
あとは、いろいろな単体テストケースを実行するための、実際のデータ作成も手間がかかるかもしれないです。
単体テスト等、わざわざ本当のサービスにアクセスしなくてもいいならそれにこしたことはないので、今回のようなAPIモック使ってみるのも手ではないかと。
もっと楽な方法もある気がするけど気にしない。

なお、そういったソフトウェアを探してみましが、みつかりませんでした。(だれか知っていたら教えて下さい)