Browse Source

Allow for executing client to be set dynamically

Richard Blair 4 years ago
parent
commit
63a81f387f
3 changed files with 52 additions and 1 deletions
  1. 26 0
      docs/graphql.md
  2. 10 1
      lib/shopify_api/graphql.rb
  3. 16 0
      test/graphql_test.rb

+ 26 - 0
docs/graphql.md

@@ -147,6 +147,32 @@ during your boot process.
 The goal is to have all clients created at boot so there's no schema loading,
 parsing, or client instantiation done during runtime when your app serves a request.
 
+## Using a custom client
+`ShopifyAPI::GraphQL::HTTPClient` inherits from `::GraphQL::Client::HTTP` and instruments
+the headers, url and api version for you. However, you may find that you wish to add
+additional functionality to the client responsible for executing and parsing queries.
+For instance, you may wish to create a client which loads responses from a file for your
+tests, or you may want to implement a client which raises errors instead of passing them
+back through the results object.
+
+To set a custom client set `ShopifyAPI::GraphQL.client_klass` to your client:
+```ruby
+class RaisingHTTPClient < ShopifyAPI::GraphQL::HTTPClient
+  def execute(document:, operation_name: nil, variables: {}, context: {})
+    result = super
+    do_work(result)
+  end
+
+  private
+
+  def do_work(result)
+    result
+  end
+end
+
+ShopifyAPI::GraphQL.client_klass = RaisingHTTPClient
+```
+
 ## Migration guide
 Prior to shopify_api v9.0 the GraphQL client implementation was limited and almost
 unusable due to the client making dynamic introspection queries to Shopify's API.

+ 10 - 1
lib/shopify_api/graphql.rb

@@ -5,6 +5,7 @@ require 'shopify_api/graphql/http_client'
 module ShopifyAPI
   module GraphQL
     DEFAULT_SCHEMA_LOCATION_PATH = Pathname('shopify_graphql_schemas')
+    DEFAULT_CLIENT_KLASS = HTTPClient
 
     InvalidSchema = Class.new(StandardError)
     InvalidClient = Class.new(StandardError)
@@ -57,7 +58,7 @@ module ShopifyAPI
           end
 
           schema = ::GraphQL::Client.load_schema(schema_file.to_s)
-          client = ::GraphQL::Client.new(schema: schema, execute: HTTPClient.new(api_version)).tap do |c|
+          client = ::GraphQL::Client.new(schema: schema, execute: client_klass.new(api_version)).tap do |c|
             c.allow_dynamic_queries = true
           end
 
@@ -73,6 +74,14 @@ module ShopifyAPI
         @schema_location = Pathname(path)
       end
 
+      def client_klass
+        @client_klass || DEFAULT_CLIENT_KLASS
+      end
+
+      def client_klass=(client)
+        @client_klass = client
+      end
+
       private
 
       def initialize_client_cache

+ 16 - 0
test/graphql_test.rb

@@ -143,6 +143,22 @@ class GraphQLTest < Test::Unit::TestCase
     end
   end
 
+  test '#client creates client based off configured class' do
+    class SuperDuperClient < ShopifyAPI::GraphQL::HTTPClient
+    end
+
+    ShopifyAPI::GraphQL.client_klass = SuperDuperClient
+    version_fixtures('unstable') do |dir|
+      ShopifyAPI::Base.api_version = 'unstable'
+
+      ShopifyAPI::GraphQL.initialize_clients
+
+      assert_instance_of SuperDuperClient, ShopifyAPI::GraphQL.client('unstable').execute
+    end
+
+    ShopifyAPI::GraphQL.client_klass = nil
+  end
+
   private
 
   def version_fixtures(*versions)