でぃするだいありー?

そんな気はないんだれど、でぃすっちゃってる。 でぃすでれ?

はじめてのGraphQL

2016年に建てた自宅サーバLAMPの亜流(Raspblian、ApacheMySQLPython)だった。

Raspberry PIでやりたいことに必要とする知識、電子工作、GPIO、Pythonなどは初めて尽くしで、書籍やWEBの参考記事やサンプルプログラムを見ながら、やっつけでとりあえず動くようにしたというものでもあった。Pythonを選択したのも、そもそも興味を持ったきっかけである記事がPythonで実装していたからに過ぎない。

WebページとのやりとりはPythonによるCGI的なもので、赤外線LED発光とBME280から取得したデータの取得、MySQLとのやりとりという内容である。このうち、赤外線LED制御とBME280制御の部分はRaspbianないしはカーネルのバージョンアップでたびたび動かなくなり、バージョンアップに影響されない実装を求めて今年、node.js + Express を用いたWEB API化を図ったが、Raspbian Busterの登場によってまたしても動かなくなり、カーネルの変更に際しては表層的な実装の工夫ではどうにもならないことを理解した。
実感として、少なくとも Raspbian 上ではGPIOまわりのnode.jsライブラリは開発が止まっていたりして、あまり向いていないのではないかとも思う。

WEB APIの実装については前述の影響はなかったが、URL設計に困難を感じるようになった。
とあるテーブルから範囲指定でデータを取得したい場合、どのようなインターフェイスが適当なのか思いつかない。調べてもこれといった例が見当たらない。力技で適当なURLをひねり出すのもためらわれて、どうしたもんかと悩んでいた時に GraphQLを知った。URLではなく、クエリでデータを取得するAPIである。

知った当初は良さがわからず、試してみるまでにずいぶんとかかってしまったが、突如、発想の神が降りてきて、クエリなら範囲取得についてあれこれ考えずに済みそうだと理解した。

具体的には、次のようなクエリを書いた。
periodFrom、periodTo は、date + time で範囲指定するパラメータである。

type Query {
  tempTbs(date: String, time: String, periodFrom: String, periodTo: String): [TempTb]!
}

type TempTb {
  date: Date!
  dow: String
  time: String!
  temp: Float
  humidity: Float
  pressure: Float
  cpu_temp: Float
}

伝わりにくいが、推しとなるポイントは以下となる。

  • エンドポイントを集約できる。
  • 「適切なURL」について思い悩むことなく、わりと勢いで実装できる。

Expressで作ったAPIの動作確認にはCURLやブラウザでURLを指定する手法でやっていたが、GraphQLではGraphiQLという強力なツールが備わっており、同様の作業について比較にならないほど容易だった。
参考にしたサイトが ApolloServer + GraphQL という組み合わせで非常にためになったが、クライアント側は ApolloClient + React でWindows環境では動作するがRaspberry PIでは重すぎて動いたり動かなかったりするので断念した。

programmagick.com

既存Webページへの適用も、JSONデータの形状が若干異なるために実装の変更を必要としたが、容易だった。
WEB APIの経験がそもそも数か月程度しかないわけで、適切な比較はできないが、設計的なボリュームの面で非常に楽であると感じられる。