LoginSignup
49
45

More than 5 years have passed since last update.

Falcor 概要:もう1つのクエリー言語型 API

Posted at

概要

GraphQLとは別のクエリー言語型の API である Falcor 1について調べました。

Falcor とは

Netflix が開発したサーバーとクライアント間のデータのやりとりの仕様です。
Facebook の GraphQL / relay と同じように、RESTful な API の問題を解決するために開発されました。

REST の問題点は Facebook の GraphQL のページにまとめられています。(参考)
Falcor でも次のような問題が解決できます。

  • 複雑なデータを取ろうとすると API を何度も呼ばないといけない。
    • 例:一覧を取得後に、各要素の詳細を1つずつ取得する、など
  • 不要なデータフィールドも取得してしまう。
    • 例:name だけ欲しいのに avatar_url とかもついてくる。

準備

Falcor のサンプルの falcor-express-demo を使って動きを見ながら Falcor の仕様を理解したいと思います。

サンプルを npm install && npm start し、http://localhost:9090 アクセスすると真っ白な画面が表示されます。
※ mac では node.js v4 ではnpm iでエラーになったので、node.js v0.12 で確認しています。

GraphQLのスキーマのように API の形が簡単にわかる方法がないようですので、サーバーのソースコード を参考にしながらいろいろ試してみます。

Path

REST では URI によってリソースを指定しますが、falcor では Path によって指定します。
Path は名前の通り、データの階層をパスを使って指定しますが、簡単なクエリーも指定できます。

サンプルコードでは genrelist というジャンルのリストを取得するパスが用意されています。

まず、ジャンルリストの1つ目を取得してみます。

method には get, set, call が指定でき、取得は get です。
paths が path で [[path1], [path2]] のように複数の path を指定できます。1つの場合は [[path]] になります。

上にアクセスすると、次のような json が取得できます。

"genrelist",0
{
    "jsonGraph": {
        "genrelist": {
            "0": {
                "$type": "atom"
            }
        }
    }
}

$type はタイプを表し、atom はデータを持つオブジェクトを表します。

上記の path には取得するデータのフィールドが指定されていないため、$type のみ返されました。
genrelist には name があるので取得します。

"genrelist",0,"name"
{
    "jsonGraph": {
        "genrelist": {
            "0": {
                "name": "Popular on Netflix"
            }
        }
    }
}

さらに titles もあるので、titlesも取得します。

{
    "jsonGraph": {
        "genrelist": {
            "0": {
                "name": "Popular on Netflix", 
                "titles": {
                    "$type": "atom"
                }
            }
        }
    }
}

なお、["name","titles"] を2つの path に分けて(["genrelist",0,"name"],["genrelist",0,"titles"])も結果はマージされて同じように出力されます。

次に 0 が指定されている部分で {"from":1,"to":3} のように指定すると複数取得することができます。

"genrelist",{"from"
{
    "jsonGraph": {
        "genrelist": {
            "1": {
                "name": "Action & Adventure"
            }, 
            "2": {
                "name": "My List"
            }, 
            "3": {
                "name": "Goofy TV Shows"
            }
        }
    }
}

JSON Graph

falcor から取得できるデータは json ですが、重複したデータを効率よく扱うため、独自の定義をしています。

上の例で、$typeatom とありましたが、全部で3つあります。

  • atom : データ
  • ref : 参照
  • error : エラー

参照は重複したデータをまとめるためにあります。
genrelisttitlesname を取得します。

{
    "jsonGraph": {
        "genrelist": {
            "0": {
                "titles": {
                    "0": {
                        "$type": "ref", 
                        "value": [
                            "titlesById", 
                            1
                        ]
                    }
                }
            }, 
            "1": {
                "titles": {
                    "0": {
                        "$type": "ref", 
                        "value": [
                            "titlesById", 
                            8
                        ]
                    }
                }
            }
        }, 
        "titlesById": {
            "1": {
                "name": "Curious George"
            }, 
            "8": {
                "name": "Blitz"
            }
        }
    }
}

title は複数の genre に登録されていることがあるため、上のように参照型で返すことができます。
この構造は通信量を減らすだけでなく、クライアントでもこの構造で持つことによってメモリを効率的に使うことができます。

最後に

Falcor の基礎的な機能を使ってみました。
まだ、Falcor も GraphQL も十分理解できていませんが、今の印象としては

  • クエリーは GraphQL の方が強力
  • 取得できるデータの表現は、Falcor の JSON graph の方が強力

です。

検索してみると、すでに GraphSQL vs Falcor のようになっています。(伸びてないですが、ReactJSからこんなポストも)

Facebook と Netflix が強力して組み合わせてはどうでしょうか :smile:

参考

関連記事


  1. falcor で検索するとネバーエンディング・ストーリーのfalkorの画像が大量に。 Phoenix / Elixir に続いてファンタジーが流行りでしょうか。 

49
45
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
49
45