shwld
Invalid Date

graphql-rubyの個人的知見まとめ

最近は仕事でも個人開発でもgraphql-rubyを使っています。

使っているうちにここ、こうしたほうがいいんじゃないかとか試行錯誤した結果のオレオレプラクティスをまとめました。

追記するかも。

graphql-rubyのloads

graphql-rubyにはという、loadsを書いておくといい感じにオブジェクトを取ってきてくれるやつがある

ruby
argument :post_id, ID, required: true, loads: Types::Post

でも自分はloadsを使うのをやめた。

理由としては

  • 全テーブルで一意のIDがないといけない
  • mutationにはloadsがあるが、query側にloadsがないっぽいのでmutationとqueryでインタフェースを合わせづらい

あたり

graphql-batchI

とりあえず、これは使っておけ!

最初は何も考えず なカラムは RecordLoaderで読み込んでおくくらいでもいいので取り敢えず導入しておきたい。

graphql-rubyを使う場合は、などを極力使わず、graphql-batchでネストしたデータを取得する癖をつけていくといい気がする。

authorization

権限制御はを使う

graphql-rubyを使う場合には、 したりはあまりしなくて良くて、取り敢えず全レコードからとかしておいて、そいつをauthorizationで権限処理するのが良さそう。

Queryの場合はこんな感じ

ruby
class Types::Objects::ContentType < Types::BaseObject
  def self.authorized?(object, context)
    # ユーザーの権限をpunditでチェックしてNGならこのコンテンツは取得できない
    super and ContentPolicy.new(context[:current_user], object).show?
  end

  field :id, ID, null: false
end

class Types::Objects::QueryType < Types::BaseObject
  field :content, Types::Objects::ContentType, null: true do
    argument :id, ID, required: true
  end

  def content(id:)
    # この時点では権限に関わらず全レコードから取ってくる
    Loaders::RecordLoader.for(Content).load(id)
  end
end

ちなみにな関連はしたいので、親を取ってきて権限チェックして、その子供として取得する

ruby
class Types::Objects::UserType < Types::BaseObject
  field :contents, Types::Objects::ContentType.connection_type, null: false
  def contents
    Loaders::AssociationLoader.for(User, :contents).load(object)
  end
end
graphql
query {
  user(id: ID!) {
    contents {
      nodes {
        id
      }
    }
  }
}

Mutationはこんな感じ

ruby
class Mutations::EditContent < Mutations::BaseMutation
  null true

  def authorized?(id:, **args)
    @content = Content.find_by(id: id)
    ContentPolicy.new(context[:current_user], @content).edit?
  end
end

graphql-rubyのpro版を使うとpunditとかをいい感じに扱えるみたいだが、個人的にはloadsも使わなくていいのでpro版あってもこっちのほうが好みなんじゃないかって気がしている(pro使ったことないので比較してないけど)

GraphiQL

めちゃめちゃ便利なツールだがRSpec書くのもそんなに大変じゃないのでRSpec書いていきたい。という気持ち

Rails自体のあれこれ

annotate

ctran/annotate_models

Annotate Rails classes with schema and routes info - ctran/annotate_models

https://github.com/ctran/annotate_models
ctran/annotate_models
ruby
# == Schema Information
#
# Table name: users
#
#  id                     :uuid             not null, primary key
#  email(Eメール)            :string           default(""), not null
class User < ApplicationRecord
...

こういうコメントが付くやつですね。

ruby
create_table :users, id: :uuid do |t|
  t.string :email, null: false, default: '', comment: 'Eメール'
end

マイグレーション時にを渡してあげると英語が苦手な場合でもなんとか他の開発者に伝わります。

また、以下のような指定を追加すると、Model以外のファイルでもカラムコメントがすぐに見れて便利です。

ruby
'additional_file_patterns' => ['db/fixtures/**/*%PLURALIZED_MODEL_NAME%.rb', 'app/graphql/types/objects/%MODEL_NAME%_type.rb', 'app/graphql/mutations/*_%MODEL_NAME%.rb'],
shwld/graphql-ruby-on-rails-with-spa

This is boilerplate. Contribute to shwld/graphql-ruby-on-rails-with-spa development by creating an account on GitHub.

https://github.com/shwld/graphql-ruby-on-rails-with-spa/blob/master/lib/tasks/auto_annotate_models.rake
shwld/graphql-ruby-on-rails-with-spa

書いた人

shwld
shwldLV: 106
ATK32620
DEF30929
SPD38392
HIT95
AVD19
CRI20

他の投稿を見る

もっと見る