GraphQLやってる
前に書いた社内向けの日報Webサービスで、RESTful(RESTish?)なAPIからGraphQLなAPIに書き直しをしてる。
サーバ側
そもそもそんなに大きなアプリケーションではないので、雑にhas manyやらassociationsを辿っていく程度のものはすぐにできた。認証はAuthorizationヘッダにJWTをつけてる。ちょっと前にブログ書いたはずと思ったら3ヶ月近く前で震えた。
Root Fieldとしてはuser
とnippoes
を用意。user
はユーザ名を引数に取る。nippoes
は日付と順序を受け付けて日報のリストを返す。こんなクエリをイメージしていた。
query ($name: String!, $date: String!) { user (name: $name) { nippoes (date: $date, orderBy: {field: DATE, direction: ASC}) { id date content isMine } } }
APIはElixir/Phoenixで書いていたので、absinthe、absinthe_plug、absinthe_ectoを使って実装した。ただ、ある程度世の中のスタンダードを意識したほうがいいんじゃなかろうかと不安になり、absinthe_relayを使って書き直した。
フロント側
次はフロント側ということで、Vue.jsからどうやってクエリ投げようか、というところ。最悪ナイーブに文字列組み立ててPOSTする手もあるけれどせっかくRelay Compliant気味になっているはずなのでライブラリを探す。vue-relayを発見。
どうやらGraphQLクライアントはRelayとApolloという2大派閥があるようで、比較記事を書かれがちな様子が伺えた。当然のようにvue-apolloも発見。
とりあえずvue-relayをnpm i -S
して使ってみるがよくわからない。新しい概念に触れているのだからよくわからなくて当然と思いながら、Vuexとの食い合わせとか要らんこと考え始めてウウーンとなる。ReactとかFluxアーキテクチャとかも、話としては理解できるけど書いてみるとよくわからんということが何度かあって、頭が悪いかfacebookと気が合わないかどっちかだな...という気持ちになった。
じゃあvue-apolloどうなの、といろいろ調べていたら
のissueで「クライアントサイドの状態管理なんてApolloにやってもらえばええやろ」みたいなことが書かれていて、あーそーゆーことね完全に理解した。GraphQLのAPIを楽に叩けるものくらいに捉えていたけど、どうやらもっと大きな存在であるらしい。例えばこれまでよくやっていた「API叩いてその結果をStoreに入れる」のような流れは全部Apolloに任せてキャッシュしてもらって、Vuexからバシバシ仕事を奪っていくべきなのでした。実際Vuexの仕事はほとんど無くなったし、いま見るとvue-relayも使えそうな気がしてくるので、この辺の認識が大切そう。
このあたりで、クライアントにApolloを使うんであればRelay Compliantが邪魔になるなーということに気づく。せっかく一度書き直したのに戻すのかー思ったところで、なんでクライアントで使うライブラリにサーバの実装が左右されなきゃならんのだなんか間違ってねーかコレと考えた。これまでの感覚だと、クライアントの事情は考えず、サーバはリソース設計として適切と思われるように実装されるべきと自分は捉えていた。あくまでそれは理想で、画面の都合でレスポンスの構造が変わってRESTってなんだっけとなるのはあるあるだとしても、まずはクライアントのこと、とくにライブラリなに使うかなんて考えるのおかしくないですか〜という疑問。自分で考えててもよくわからず、たまたま社内の有識者 id:shiro-16 とランチに行く機会があり雑談したら同じようなことを思っていたようで、あーここは意識を変えるタイミングなんだなと思い納得。あまり汎用的なものにしようとはせず、特定のクライアントのために作る気持ちでよさそう。
サーバ側(再)
edges
とかnode
とかRelayの諸々を消していく。mutationsに関して、absinthe_relayのinput
やoutput
も使うのをやめてしまったけど、ここは残してもよかったと思っている。たぶんあとで復活する。Relay Input Object Mutations Specificationだけ読んでも何が嬉しいのかよくわからなかったけど、引数たくさん書くのダルいよね、という記事を見てまあ確かに、と思った。
まとめ
ということで最終的にApolloに乗っかる形になった。RESTが教えてくれた感覚とか、クライアントサイドの状態管理の方法とか、これまで考えてきたことを一回捨てることが一番大変なんじゃないのという印象。実装はそれほどしんどくないなと今のところ思っていて、ライブラリやらツールやらエコシステムが支えてくれる。
次は守備を考える。