ちょっと話題の記事

Web APIをUNIXパイプで繋ぐツール IOpipe を試してみた

2016.03.30

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

ども、大瀧です。 IOpipeというツールが面白そうだったので、試してみた様子をレポートします。

IOpipeとは

IOpipeは、Web APIからのレスポンスを受け取りNode.jsでロジックを記述したフィルタ処理を適用、その結果をAPIへのリクエストとして送信するCLIツールです。標準入力および標準出力にも対応しているのでUNIXパイプによる他のコマンドとの組み合わせが可能です。また、NodeJS SDK版もありNode.jsアプリケーションに組み込めるようにもなっています。

以下のサイトでIOpipeのコンセプトが紹介されており、AWS LambdaGoogle Cloud Functionsに対応する予定で、サーバーレスアーキテクチャのツールとしても機能する予定のようです(現在は未実装)。

IOpipeのインストール

IOpipeは、GitHubのリリースページからバイナリをダウンロードし、実行します。

iopipe01

Mac OS Xの場合は「iopipe-0.0.1alpha2-osx-x86_64」ですね *1。ダウンロードしたらPATHの通っているディレクトリに配置し、実行権を付与しましょう。以下のようにヘルプが出ればOKです。

$ curl -L -o ~/bin/iopipe https://github.com/iopipe/iopipe/releases/download/0.0.1-alpha2/iopipe-0.0.1alpha2-osx-x86_64
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   621    0   621    0     0    391      0 --:--:--  0:00:01 --:--:--   391
100 11.5M  100 11.5M    0     0   965k      0  0:00:12  0:00:12 --:--:-- 2401k
$ chmod +x ~/bin/iopipe
$ iopipe --help
NAME:
   iopipe - cross-API interoperability & data manager

USAGE:
   iopipe [global options] command [command options] [arguments...]

VERSION:
   0.0.0

COMMANDS:
   remove	Remove filter from local index.
   exec		Pipe from <src> to stdout
   export	Export will write a Javascript library for the given pipeline
   import	Import will bring a filter in from a javascript file or STDIN for -
   list		List local and subscribed pipes
   login	Login to an endpoint
   tag		Tag a pipescript or pipeline to a name
   help, h	Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --debug		enable debugging output
   --help, -h		show help
   --version, -v	print the version
$

これで準備完了です。

実装例

今回はWeb APIの例として、AWSが公開するAWSのIPアドレスの範囲(https://ip-ranges.amazonaws.com/ip-ranges.json)のJSONデータを入力とし、その中からIPアドレスのみを抜き出すフィルタ処理を実装してみます。入力となるJSONデータは以下のような感じです。

{
  "syncToken": "1458939735",
  "createDate": "2016-03-25-21-22-16",
  "prefixes": [
    {
      "ip_prefix": "23.20.0.0/14",
      "region": "us-east-1",
      "service": "AMAZON"
    },
    {
      "ip_prefix": "27.0.0.0/22",
      "region": "ap-northeast-1",
      "service": "AMAZON"
    },
    :(以下略)

IPアドレスは、prefixes[].ip_prefixですね。これを抜き出すIOpipeのロジック(IOpipeではカーネルと呼びます)は以下のようになります。

ip-ranges.js

module.exports = function(input,context) {
  var ipRanges = JSON.parse(input)
  var ip_prefixes = ''
  ipRanges['prefixes'].forEach(function(value, index){
    ip_prefixes += value.ip_prefix + '\n'
  })
  return ip_prefixes
}

このままだとデバッグが辛いので、以下のスタブを用意してデバックしてました。

index.js

var ipranges = require('./ip-ranges.js')
var result = ipranges('{"prefixes":[{"ip_prefix":"10.0.0.0/24"}]}')
console.log(result)
$ node index.js
10.0.0.0/24

$

node.jsのコードとしては問題なさそうなので、IOpipeでやってみます。まずは、作成したコードをカーネルとしてIOpipeに登録するiopipe importを実行します。

$ iopipe import --name ip-ranges ip-ranges.js
cd50bceb526a19a0a3e4eccd58dabe5733918b000a2bc89f9c1484af60e2c81c
$

--nameオプションで指定したip-rangesがカーネルとしての登録名になります。では、実際のAPIリクエストを入力にしてカーネルを実行してみましょう。iopipe execの引数にAPIのURLとカーネル名を指定します。

$ iopipe exec https://ip-ranges.amazonaws.com/ip-ranges.json ip-ranges
INFO[0000] pipe[arg]: https://ip-ranges.amazonaws.com/ip-ranges.json
INFO[0001] pipe[arg]: ip-ranges
23.20.0.0/14
27.0.0.0/22
43.250.192.0/24
43.250.193.0/24
46.51.128.0/18
46.51.192.0/20
46.51.216.0/21
46.51.224.0/19
46.137.0.0/17
  :(以下略)
$

期待通りの出力が出てきました。では今度は、出力結果を別のAPIへのリクエストにしてみましょう。iopipe execの第三引数にAPIのURLを追加するだけです。簡単!今回はRequestBinを指定してみました。

$ iopipe exec https://ip-ranges.amazonaws.com/ip-ranges.json \
> ip-ranges \
> http://requestb.in/XXXXXXXX
INFO[0000] pipe[arg]: https://ip-ranges.amazonaws.com/ip-ranges.json
INFO[0000] pipe[arg]: ip-ranges
INFO[0001] pipe[arg]: http://requestb.in/XXXXXXXX
ok
$

RequestBinを確認してみると。。。

iopipe03

出力がPOSTのリクエストボディにセットされているのがわかりますね。

ちなみに、APIの代わりに標準入力を使う場合は、URLの部分を-にします。

$ cat ip-ranges.json | iopipe exec - ip-ranges
INFO[0000] pipe[arg]: -
INFO[0000] pipe[arg]: ip-ranges
23.20.0.0/14
27.0.0.0/22
43.250.192.0/24
43.250.193.0/24
46.51.128.0/18
46.51.192.0/20
46.51.216.0/21
46.51.224.0/19
46.137.0.0/17
  :

良い感じですね。

まとめ

Web APIを手軽に入出力として扱える、IOpipeをご紹介しました。node.jsなのでJSONが簡単に扱えるため、Web APIは関係なしにjqの代替として使えるのでは?なんて淡い期待を持っていたりします *2。まだアルファ版なので実務で使うにはパフォーマンス面など不安はありますが、今後が楽しみなツールです。 一方でLambda対応もどのような展開になるのか期待大ですね。作者のEricが5月にニューヨークで開催されるServerlessConfにスピーカーとして参加するようなので、その辺の話が聞けるんじゃないでしょうか。ServerlessConf行きたい!

脚注

  1. Windowsの方も、Goで書かれているツールなのでDockerもしくはgo buildの独自ビルドで動かせるかも知れません。参考 : GitHubのREAMDEにある「Build & Install from source」
  2. jqの構文に悩まされる日々から解放されるかも!