Data Pipeline

Data PipelineはRedux)用のデータ変換ライブラリです。また、ここで述べるData PipelineはAWS DataPiplineとは異なります。

Data Pipelineはデータ生成者とデータ利用者の依存性を断つことにより、データにまつわる様々な問題を解決することを目標に作成しています。

Concept

Data PipelineはFluxアーキテクチャにデータを変換するActivityとデータを流すPipelineを追加します。ActivityはPipelineに流れるデータを別のデータに変換してパイプラインに流します。また、Activityからdispatchすることも可能です。 起点となるデータはViewもしくはMiddlewareから配置できます。

Data Pipelineに流れるデータには、必ずデータを表すURIが設定します。このURIを観測することで任意のデータに対するハンドラを実行することができます。これはRouterのURLとハンドラの関係に近いと言えます。

次のコードは基本的なパイプラインの使用方法です。3つのハンドラがtakeメソッドで設定されていますが、この3つのハンドラすべてが後のputメソッドでパイプラインに載るデータに対して発火します。


// pipelineはパイプラインのシングルトンインスタンス

// takeメソッドで、第1引数で指定するURIのデータに対するハンドラを設定する。
pipeline.take('localhost/products/:id', (context, product) => {
  console.log(context.uri) // 'localhost/products/1'
  console.log(context.params.id) // 1
})

// ルートパラメータ指定に'*'を使用すると、以降の'/'を含む文字列が格納されます。
pipline.take('localhost/*path', (context, data) => {
  console.log(context.uri) // 'localhost/products/1'
  console.log(context.params.path) // 'products/1'
})

// '*'単体をURI指定するとすべてのデータを監視します。
pipeline.take('*', (context, payload) => {
  console.log(context.uri) // 'localhost/products/1'
})

// データをパイプラインに載せます。
pipeline.put('localhost/products/1', { name: 'Product A' })

このData Piplineが効果を発揮するユースケースはAjaxを行って取得するリモートリソースを扱うケースです。通常このケースであれば、Promiseを返す関数(fetchなど)を利用することが定石でしょう。しかし、通信中の状態を取得したい(プログレスなど)、または、その通信中の状態を操作したい(キャンセルなど)場合ではXMLHttpRequestをストアしておくことになります。

Data PipelineはRequestデータをAjax用の中間データとしてstoreに保存します。Viewではこの中間データのコレクションを読み、インジゲータの表示などに利用できます。

Ajaxが完了した際に、Responseデータがパイプラインに載ります。このResponseデータをハンドリングしてbodyからJSONデータをパースする、もしくは、さらにRequestデータを発行するなど柔軟にデータフローを作成することができます。

上図では、RequestデータがAjaxの中間データを経て、Responseデータ、目当てのProductデータに移るデータフローを示しています。この中で、パイプラインに流れるデータは青色で表されてる3つのデータです。

Data PipelineではRequestデータを処理し、Ajaxの中間データに関するActionを発行するAjaxActivityを提供しているため、ユーザはResponse以降のデータフローを記述することになります。

Example

View example code on Github

Demo

Libraries

pipeline

interface Pipeline {
  take: (uri: string, handler: (context: { uri: string, params: any }, ...payload: any[]) => void ) => void,
  put: (uri: string, ...payload: any[] ) => void
}
pipeline: Pipeline

initAjaxActivity

initAjaxActivity: (pipeline: Pipeline, dispatcher: { dispatch: (action: any) => void }) => void

ajaxRequests

ajaxRequests is reducer for ajax requests.

cancelAjax

cancelAjax is middleware for ajax requests.

putReqToPipeline

putReqToPipeline is middleware for ajax requests.

How to use

Install

npm install data-pipeline

Setup

setup Reducers, Store, and Activities.
/**
 * reducer
 */
import { combineReducers } from 'redux'
import { ajaxRequests } from 'data-pipeline'

const reducers combineReducers({ ajaxRequests, /* more reducers! */ })

/**
 * store
 */
import { createStore, applyMiddleware } from 'redux'
import { cancelAjax, putReqToPipeline } from 'data-pipeline'

const createStoreWithMiddleware = applyMiddleware(
  cancelAjax,
  putReqToPipeline,
)(createStore)
const store = createStoreWithMiddleware(reducers)

/**
 * activities
 */
import { pipeline, initAjaxActivity } from 'data-pipeline'
import initProductsActivity from './ProductsActivity'

initAjaxActivity(pipeline, store)
// more activities...
// ex. initProductsActivity(pipeline, store)

License

The MIT License (MIT) Copyright (c) 2016 iwate

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.