Upgrade to Pro — share decks privately, control downloads, hide ads and more …

async_graphqlのguardが便利だった話

 async_graphqlのguardが便利だった話

「Rust、何もわからない...#8」

estie | エスティ

June 05, 2023
Tweet

More Decks by estie | エスティ

Other Decks in Programming

Transcript

  1. async_graphqlのguardが便利だった話
    2022/5/22
    Rust、何もわからない….vol8
    hige_yy @kia5n_y2_mud

    View full-size slide

  2. higeです。
    • 本名は山中です
    • 202012~ estie
    • 元々はフロントエンド領域
    • オーディオオタク
    • ビアポンなるパーティゲームの元日本代表
    1

    View full-size slide

  3. 2
    1. async_graphqlを使ってGraphQL移行した話
    2. 便利だったものの話
    3. 大変だったことの話
    4. まとめ
    こういう話しますよ

    View full-size slide

  4. GraphQLに移行するぞ!!!

    View full-size slide

  5. 4
    1. 現状はReact + Rust(REST)の構成だが、ユースケースごとにフロントでリソースの結合
    成形を行っている箇所が複数あってちょっとつらい
    2. 見た目のちょっとした変更のためにバックエンドまで変更しなければならないことが
    多々ある
    3. フィールド単位で参照の権限を設定したいが、似たような実装が毎回必要になる
    4. ……etc
    なぜGraphQLにしたいか
    移行したいので検証を実施した
    - Juniperで試しに実装してみる話 (Rust何もわからないvol.4)
    - 結果、やりたいことはできそう。

    View full-size slide

  6. 5
    Juniper or async_graphqlで検討
    差分は大きくなかったが以下が決め手になりasync_graphqlを使うことに
    - OneofObjectが使える
    - Inputで値が入ったEnumが使える
    - Fieldの定義とGuardが柔軟に行えそう
    - Fieldごとに設定可能でResolver実行前に実行されるもの
    技術選定の話

    View full-size slide

  7. 6
    - crateをいくつかにわけて開発
    - api
    - sql
    - usecase
    - middleware
    - ……etc
    元々どんな感じで作っていたか

    View full-size slide

  8. 7
    - crateをいくつかにわけて開発
    - api <- ここを部分的にgqlに移行
    - sql
    - usecase
    - middleware
    - ……etc
    どんな感じで移行するか

    View full-size slide

  9. 8
    ざっくりと実装はこんなイメージ

    View full-size slide

  10. 9
    移行していく
    開発チームを一時的に機能開発組と移行組に分割して実施
    移行できて嬉しいものから移行していった
    結果、1週間と少しで主要な参照が移行完了。
    以降、作成されるAPIはgqlになり順次作成・更新系を移行中。

    View full-size slide

  11. 10
    運用に移って
    GraphQLにチーム全員が慣れているわけではないので、ちょくちょくつま
    づきは起きていますが、おおむね問題なく運用できています。
    当初困っていたフロントエンドが複雑になる部分は無事解消されました。

    View full-size slide

  12. 便利だったものの話

    View full-size slide

  13. 12
    FieldGuard
    こう定義して こうやって使う

    View full-size slide

  14. 13
    なぜ便利だったかの話
    不動産ドメインには多くの登場人物が存在します
    - ビルを保有する人
    - ビルを管理する人
    - 募集を出す人
    - 営業をする人
    - 部屋を借りたい人
    - ……etc
    同じ“ビル”を指していても全く同じ情報が全てのユーザに見えて良いわけで
    はありません。

    View full-size slide

  15. 14
    なぜ便利だったかの話
    ここでは簡単のために以下のユーザが存在していると仮定します
    - ビルの貸主
    - 他社のビルは閲覧できない
    - テナント
    - 全てのビルを閲覧できるが見えない項目がある
    - 管理者
    - 全て閲覧可能

    View full-size slide

  16. 15
    なぜ便利だったかの話
    このようなビルを考える

    View full-size slide

  17. 16
    なぜ便利だったかの話
    RESTでやっていた時……
    -> 全部分けて定義する?
    -> Optionalな型にして返す?

    View full-size slide

  18. 17
    なぜ便利だったかの話
    見ても良い条件を満たさない場合Errを返すGuardをユーザごとに作成

    View full-size slide

  19. 18
    なぜ便利だったかの話
    このように表現可能になります。

    View full-size slide

  20. 19
    なぜ便利だったかの話
    1. 一見してどのフィールドが誰に公開されているのかわかる
    2. 同一のロジックで処理が可能
    3. ctxと引数を受けることができるので柔軟なGuardの記述が可能

    View full-size slide

  21. 20
    Remote Enum
    レイヤーを跨ぐ構造体について依存を切るために詰め替えたりしますよね。
    でも何度も impl From<~> ……するの結構大変ですよね。
    特にenumのこれ

    View full-size slide

  22. 21
    Remote Enum
    remote-enumを使うと実に楽になります。

    View full-size slide

  23. 22
    できないこともある
    値のあるEnumについては使えません。

    View full-size slide

  24. 23
    値のあるEnumについてはどうするか
    パターン1: Unionを使う
    全て値を持っている場合、Unionが使えます。
    パターン2: 型を一部諦める
    今のところこれは良い!という手段は特になし。

    View full-size slide

  25. 大変だったことの話

    View full-size slide

  26. 25
    複雑なSQL操作でAcquireを使うと lifetime error になる
    これ

    View full-size slide

  27. 26
    どういう時に起きるか
    acquireを要求している関数を複数呼んでいる関数があり

    View full-size slide

  28. 27
    どういう時に起きるか
    それをLoaderで呼び出した場合に起きます

    View full-size slide

  29. 28
    どうやって解決したか
    Acquireを要求していた箇所を
    MySqlConnectionに変更するととりあ
    えずCompileは通るようになります。
    何がだめなのか……?

    View full-size slide

  30. 29
    ちょっと調べてみた
    cargo-expandを使って
    該当箇所をexpandすると……

    View full-size slide

  31. 30
    ちょっと調べてみた
    一部コメントアウトすると通る

    View full-size slide

  32. 31
    ちょっと調べてみた
    どうやらnotesを引いてるところで
    こけてるみたい……
    結論わかんない
    ということがわかりました!

    View full-size slide

  33. 33
    まとめ
    1. async_graphqlのGuardは便利だった。
    2. LifetimeのErrorは難しい。sqlxを使うなら気をつけよう。

    View full-size slide

  34. 34
    追記
    折角なので、sqlx + async_graphqlの環境を作っておきました。
    async_graphqlに興味が出た方はいじってみてください。
    (あとあのErrorがわかる方の解説もお待ちしてます)
    https://github.com/savacan/rust-gql-sample

    View full-size slide

  35. 35
    estie(エスティ)

    オフィス不動産を
    デジタル化する会社です

    View full-size slide