graphene
自体で完成しているわけではなく、実は graphene
の下に graphql-core
や graphql-relay
といったライブラリが潜り込んでいる。GraphQL はその生い立ちから JavaScript 環境下でよく利用されているので、graphql-core は移植版になっている。そのコアライブラリである graphql
を、さらに python 的に使いやすくしたものが graphene
となる。graphene
のドキュメントで「記述が不足してるな」と思ったときは、実は下位ライブラリの説明部分だったりする。最終的にはリファレンス実装まで遡ると答えが見つかったりする。
graphene のフィールド定義手順は mixin で追加しやすいようになっている。クラス継承を使おうとすると落とし穴にはまるので、mixin のスタイルがおすすめ。
graphene.relay
: relay 自体は GraphQL をベースとした追加仕様。広く使われているので、基本的に対応したほうが混乱が少ない。Connection
と Node
というインターフェースが目立つ。
Node interface
Node
では id
から node query 経由で単体のオブジェクトが引ける。標準では見えないので、必要に応じて用意する。このようなアクセスパスが望ましくない場合(たとえばセキュリティ上の都合など)は、実装を省略すると良い。
graphene.relay.Node
でアクセスしなくても graphene.Node
でインポートできる。
Connection interface
Connection
の total_count
は、ライブラリで非対応。別途手当しておくとトラブルが少ない。例えば graphene-sqlalchemy で query object から導出しないといけない場合があるので、あえて隔離してあるのだろうと推測される。
https://github.com/graphql-python/graphene/issues/776
https://github.com/graphql-python/graphene-django/issues/162
relay.Connection
対応では relay.Node
側のメタデータで Node
interfaces 対応していることを宣言することになっている。
graphene_sqlalchemy.SQLAlchemyConnection
では Node
interface 宣言をいれると、二重定義を引き起こすので、うまいことやる(現状はハック的な対応で乗り切るのがよさそう)。
ConnectionField の第一引数は lambda: で遅延させると宣言順序の罠を抜け出せる。