GraphQL Ruby でCustom Scalarを使ってみる (Rails)

December 31, 2022

確認環境

$ bundle exec ruby --version
ruby 2.7.5p203 (2021-11-24 revision f69aeb8314) [x86_64-darwin19]
$ bundle exec rails --version
Rails 6.0.4.6
$ bundle info graphql
  * graphql (2.0.13)
	Summary: A GraphQL language and runtime for Ruby
	Homepage: https://github.com/rmosolgo/graphql-ruby
	Path: /Users/xxxxx/.rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/graphql-2.0.13

検証コードを実装

app/graphql/types/url.rb

class Types::Url < Types::BaseScalar
  def self.coerce_input(input_value, context)
    Rails.logger.fatal('coerce input')
    Rails.logger.fatal(input_value)
    url = URI.parse(input_value)
    if url.is_a?(URI::HTTP) || url.is_a?(URI::HTTPS)
      return url
    end

    raise GraphQL::CoercionError, "#{input_value.inspect} is not a valid URL"
  end

  def self.coerce_result(ruby_value, context)
    Rails.logger.fatal('coerce result')
    Rails.logger.fatal(ruby_value)
    ruby_value.to_s
  end
end

Query を実装

app/graphql/types/query_type.rb

module Types
  class QueryType < Types::BaseObject
    field :original_url, Types::Url, null: false
    def original_url
      'http://localhost:3000/hoge'
    end
  end
end

実行

query {
  originalUrl
}

結果

{
  "data": {
    "originalUrl": "http://localhost:3000/hoge"
  }
}

アプリケーションログ

coerce result
http://localhost:3000/hoge

coerce_result メソッドが実行されていることが分かります。

Mutation を実装

app/graphql/types/mutation_type.rb

module Types
  class MutationType < Types::BaseObject
    field :create_url, mutation: Mutations::CreateUrl
  end
end

app/graphql/mutations/create_url.rb

module Mutations
  class CreateUrl < BaseMutation
    field :result, Boolean, null: false

    # define arguments
    argument :url, Types::Url, required: true

    # define resolve method
    def resolve(**args)
      {
        result: true
      }
    end
  end
end

実行

mutation hoge($input: CreateUrlInput!) {
  createUrl(input: $input) {
    result
  }
}

変数

{
  "input": {
   	"url": "https://example.com"
  }
}

結果

{
  "data": {
    "createUrl": {
      "result": true
    }
  }
}

アプリケーションログ

coerce input
https://example.com

coerce_input メソッドが実行されていることが分かります。

エラーが出るケース

実行

mutation hoge($input: CreateUrlInput!) {
  createUrl(input: $input) {
    result
  }
}

変数

{
  "input": {
   	"url": "hoge"
  }
}

結果

{
  "errors": [
    {
      "message": "Variable $input of type CreateUrlInput! was provided invalid value for url (\"hoge\" is not a valid URL)",
      # 省略
    }
  ]
}

参考


SHARE

Profile picture

Written by tamesuu