There's a lot of open issues
Grahql client to query with your own raw string, with the small helper method query or with service class inclusion.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 0.10
~> 3.8
~> 0.75
~> 2.0
~> 0.21.2

Runtime

~> 0.16
 Project Readme

GraphqlConnector

Gem Version CI Maintainability Test Coverage

An easy connector to call your graphql server. Currently there is no schema check in the code, but i will add it.

Installation

Add this line to your application's Gemfile:

gem 'graphql_connector'

And then execute:

$ bundle

Or install it yourself as:

$ gem install graphql_connector

Usage

You need to configure the graphql_connector first:

GraphqlConnector.configure do |config|
  config.add_server(name: 'Foo', uri: 'http://foo.com/api/graphql', headers: {}, connector: {}, httparty_adapter_options: {})
end
  • name (mandatory): Add a namespace under which the API is reachable. In the above example 'Foo' means that GraphqlConnector::Foo provides API functionality for the configured add_server

  • uri (mandatory): Add uri of grapqhl API server that accepts POST requests.

  • connector (optionally): Add a Authentication Token class in the following format:

connector: { base: AuthTokenAgent.instance, method: 'get_authorization_header' }

base is an instance of Authentication Token class and method represents the function where it gets the token.

class AuthTokenAgent
   [...]
   def get_authorization_header
      [...]
      { 'Authorization' => 'Token HERE' }
   end
end

⚠️ The function under method must be a public one in your connector class.
⚠️ When you set a connector, it will override the setting in the headers for Authorization.

  • httparty_adapter_options (optionally): Add any connection_adapter options that httparty supports in a hash format e.g. { timeout: 4 }

For each graphql server you wish to query use add_server.

Afterwards you will have the following options to fetch and/or mutate data with one or many graphql servers:

See the following sub sections for details

raw_query

You can call your graphql_endpoint via:

GraphqlConnector::<name>.raw_query('query { products { id name } }')

GraphqlConnector::<name>.raw_query('query { products($id: [ID!]) { products(id: $id) { id name } } }', variables: { id: 1 })

GraphqlConnector::<name>.raw_query('mutation { createProduct(name: "Coca-Cola") { id name } }')

Or if you want to override/set any httparty_adapter_options it is also possible to pass them in:

GraphqlConnector::<name>.raw_query('query { products { id name } }', httparty_adapter_options: { timeout: 3, verify: true })

GraphqlConnector::<name>.raw_query('query { products($id: [ID!]) { products(id: $id) { id name } } }', variables: { id: 1 }, httparty_adapter_options: { timeout: 3, verify: true })

GraphqlConnector::<name>.raw_query('mutation { createProduct(name: "Coca-Cola") { id name } }', httparty_adapter_options: { timeout: 3, verify: true })

Note that <name> has to be replaced by any of the ones added via add_server

See also here for example usage


query

You can also use the more comfortable query:

GraphqlConnector::<name>.query('products', { id:  [1,2] } , ['id','name'])

Or if you want to override/set any httparty adapter_options, it is also possible to pass them in:

GraphqlConnector::<name>.query('products', { id:  [1,2] } , ['id','name'], httparty_adapter_options: { timeout: 3 })
Variable Required DataType Example
model Yes String 'product'
condition Yes (but can be empty) Hash(key, value) { id: 1 }
selected_fields Yes Array of Strings/Hashes ['id', 'name', productCategory: ['id']]
httparty_adapter_options No Hash { timeout: 3 }

See also here for example usage

selected_fields

The syntax for the associations looks like the following:

['<attribute_name>', <association_name>: ['<attribute_name_of_the_association>']]

Example:

['id', 'name', productCategory: ['id', 'name']]

mutation

Works in the same way as query

See also here for example usage

Service class inclusion

This approach can be used to graphqlize any kind of ruby (service) class so that it has re-usable graphql query and mutation class methods.

  • First add extend GraphqlConnector::<server>::Query in the the class(es) that should be graphqlized

  • Then you can aliases as many graphql server types via add_query and/or add_raw_query and/or add_mutation:

add_query products_by: :products, params: [:id], returns: [:id, :name]

add_raw_query products_raw_by: 'query { products(($id: [ID!]) products { id name } }', params: [:id]

add_mutation create: :createProduct, params: [:name], returns: [:id, :name]
  • ❕ If not needed omit params

Or if you want to override/set any httparty adapter_options, it is also possible to pass them in:

add_query products_by: :products, params: [:id], returns: [:id, :name], httparty_adapter_options: { timeout: 3 }

add_raw_query products_raw_by: 'query { products(($id: [ID!]) products { id name } }', params: [:id], httparty_adapter_options: { verify: true }

add_mutation create: :createProduct, params: [:name], returns: [:id, :name], httparty_adapter_options: { timeout: 5, verify: false }

See also here and also here for complete example usage:

GraphqlConnector.configure do |config|
  config.add_server(name: 'Foo', uri: 'http://foo.com/api/graphql', headers: {})
end

# product.rb
class Product
  extend GraphqlConnector::Foo::Query

  add_query all: :products,
            returns: [:id, :name]

  add_query by_id: :products,
            params: :id,
            returns: [:name, product_category: [:id, :name]],
            httparty_adapter_options: { timeout: 3 }

  add_query by_names: :products,
            params: :names,
            returns: [:id, :name, product_category: [:id, :name]]

  add_query by: :products,
            params: [:id, :name],
            returns: [:name]

  add_query by_category_id: :products,
            params: :product_category,
            returns: [product_category: [:id, :name]]

  add_mutation create: :createProduct,
               params: [:name, :catgetoryId],
               returns: [:id, :name],
               httparty_adapter_options: { verify: false }
end

Product.all
=> [OpenStruct<id=1, name='Demo Product', ...]

Product.by_id(id: 1)
=> [OpenStruct<name='Demo Product', product_category=<ProductCategory<id=10, name='Demo Category'>>]

Product.by_names(names: ['Demo Product', 'Non Demo Product'])
=> [OpenStruct<id=1, name='Demo Product', product_category=<ProductCategory<id=10, name='Demo Category'>>, Product<id=2, name='Demo Product' ...]

Product.by(id: 1, name: 'Demo Product')
=> OpenStruct<name='Demo Product'>

Product.by_category_id(product_category: { id: 10})
=> OpenStruct<product_category=<ProductCategory<id=10, name='Demo Category'>>

Product.create(name: 'Another Product', catgetoryId: 10)
=> OpenStruct<id=10, name='Another Product'>

Also custom class methods can used to call any kind of query and do further selection instead:

class Product
  extend GraphqlConnector::Foo::Query

  add_query all: :products, returns: [:name]

  def self.by_id(id:)
    all.select { |products| products.id == id }.first
  end
end

Product.by_id(id: 1)
=> OpenStruct<id=1, name='Demo Product'>>

⚠️ Ensure that your custom class method never has the same name as an <alias> of add_query, add_raw_query or add_mutation. Otherwise the associated grapqhl query will not be performed because of Ruby Open Class principle

Example for raw_query:

class Product
  extend GraphqlConnector::Foo::Query

  add_raw_query all: ' query { products { id name } } '
  add_raw_query by: ' query products($id: !ID, $name: !String) '\
                '{ products(id: $id, name: $name) { id name } }',
                params: [:id, :name]

end

Product.all
=> [ { id: '1', name: 'Demo Product' }, ...]

Product.by(id: '1', name: 'Demo Product')
=> { id: '1', name: 'Demo Product' }

❗ There is no add_raw_mutation since add_raw_query does already cover such a case

Development

After checking out the repo, run

bundle install

Then, run

bundle exec rspec spec

to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/garllon/graphql_connector. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.

License

The gem is available as open source under the terms of the MIT License.

Code of Conduct

Everyone interacting in the GraphqlConnector project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.