使用 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
我想使用 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