使用 ruby-graphql 实现依赖注入的最佳实践是什么?

What's the best practice to achieve dependency injection with ruby-graphql?

我想使用 graphql 的依赖注入-ruby.

module CustomerCredits
  module Types
    class QueryType < GraphQL::Schema::Object

      description 'The query root of this schema'

      field :filter_users, [Types::UserType], null: false do
        argument :parameters, InputTypes::UserFilterParameters, required: true
      end

      # resolvers

      def filter_users(arguments) 
        repo = UserRepository.new(complex_arguments) # I want to inject the dependency UserRepository
    
        repo.filtered_users(**arguments[:parameters])
      end

    end
  end
end

initialize中使用依赖注入是不可能的,因为QueryType是由graphql-ruby.

实例化的

正如您所提到的,通过初始化程序进行注入可能不是非常简单,因此如果您想全面了解依赖注入和控制反转,您可以利用像 Dry Auto Inject 这样的 IOC 容器库.我知道这可能是一个完整的解决方案,并且对于您的用例来说可能过于繁重(不确定),但由于您已经在 Ruby 中使用存储库,所以它可能不是。

根据 graphql-ruby 中的架构定义,我想到的解决此问题的一种方法是将您的数据库引用注入控制器 class,然后当您的控制器被命中时,您传递数据库作为上下文的一部分参考。

# app/controllers/graphql_controller.rb
result = MySchema.execute(
  params[:query],
  variables: params[:variables],
  context: { 
    current_user: current_user, 
    db: my_database_ref # inject database ref here
    },

)
render json: result

然后在您的查询类型定义中,您可以从上下文中提取数据库。

class QueryType < GraphQL::Schema::Object
  description "The query root of this schema"

  field :post, PostType, "Find a post by ID" do
    argument :id, ID
  end

  def post(id:)
    db = context[:db]  # pull db reference from context here
    db[:posts].where(id:).first
  end
end