Browse Source

Merge branch 'master' into default_session_to_base_api_version

Paulo Margarido 4 years ago
parent
commit
16abaeed2e
3 changed files with 97 additions and 2 deletions
  1. 45 0
      docs/graphql.md
  2. 20 2
      lib/shopify_api/graphql.rb
  3. 32 0
      test/graphql_test.rb

+ 45 - 0
docs/graphql.md

@@ -147,6 +147,51 @@ 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 GraphQL Client
+By default `ShopifyAPI::GraphQL` wraps the Github GraphQL Client library. However, this client
+may not suitable for various reasons. If you wish to expand on the interface of the client or
+improve the required functions for your use case you can implement a client of your own.
+
+To use a custom GraphQL Client:
+```
+class CustomGraphQLClient < ::GraphQL::Client
+end
+
+ShopifyAPI::GraphQL.graphql_client = CustomGraphQLClient
+```
+
+
+## Using a custom query execution adapter
+Github's GraphQL Client uses an adapter pattern so that you can define how you interact
+with GraphQL API's. Shopify provides a minimal implementation in `ShopifyAPI::GraphQL::HTTPClient`.
+If you need to add additional functionality pre, during or post query execution you can
+consider implementing these within a custom query execution adapter, inheriting from
+`ShopifyAPI::GraphQL::HTTPClient` which provides the necessary implementation for
+headers, url, and api versions
+
+
+To set a custom query executiona dapter set `ShopifyAPI::GraphQL.execution_adapter` 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.execution_adapter = RaisingHTTPClient
+```
+
+Note, the execution adapter has `client` in the name. This is to remain consistent with
+the naming conventions within the Github GraphQL Client library.
+
 ## 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.

+ 20 - 2
lib/shopify_api/graphql.rb

@@ -5,6 +5,8 @@ require 'shopify_api/graphql/http_client'
 module ShopifyAPI
   module GraphQL
     DEFAULT_SCHEMA_LOCATION_PATH = Pathname('shopify_graphql_schemas')
+    DEFAULT_EXECUTION_ADAPTER = HTTPClient
+    DEFAULT_GRAPHQL_CLIENT = ::GraphQL::Client
 
     InvalidSchema = Class.new(StandardError)
     InvalidClient = Class.new(StandardError)
@@ -56,8 +58,8 @@ module ShopifyAPI
             end
           end
 
-          schema = ::GraphQL::Client.load_schema(schema_file.to_s)
-          client = ::GraphQL::Client.new(schema: schema, execute: HTTPClient.new(api_version)).tap do |c|
+          schema = graphql_client.load_schema(schema_file.to_s)
+          client = graphql_client.new(schema: schema, execute: execution_adapter.new(api_version)).tap do |c|
             c.allow_dynamic_queries = true
           end
 
@@ -73,6 +75,22 @@ module ShopifyAPI
         @schema_location = Pathname(path)
       end
 
+      def execution_adapter
+        @execution_adapter || DEFAULT_EXECUTION_ADAPTER
+      end
+
+      def execution_adapter=(executor)
+        @execution_adapter = executor
+      end
+
+      def graphql_client
+        @graphql_client || DEFAULT_GRAPHQL_CLIENT
+      end
+
+      def graphql_client=(client)
+        @graphql_client = client
+      end
+
       private
 
       def initialize_client_cache

+ 32 - 0
test/graphql_test.rb

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