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,
 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.
 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
 ## Migration guide
 Prior to shopify_api v9.0 the GraphQL client implementation was limited and almost
 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.
 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 ShopifyAPI
   module GraphQL
   module GraphQL
     DEFAULT_SCHEMA_LOCATION_PATH = Pathname('shopify_graphql_schemas')
     DEFAULT_SCHEMA_LOCATION_PATH = Pathname('shopify_graphql_schemas')
+    DEFAULT_EXECUTION_ADAPTER = HTTPClient
+    DEFAULT_GRAPHQL_CLIENT = ::GraphQL::Client
 
 
     InvalidSchema = Class.new(StandardError)
     InvalidSchema = Class.new(StandardError)
     InvalidClient = Class.new(StandardError)
     InvalidClient = Class.new(StandardError)
@@ -56,8 +58,8 @@ module ShopifyAPI
             end
             end
           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
             c.allow_dynamic_queries = true
           end
           end
 
 
@@ -73,6 +75,22 @@ module ShopifyAPI
         @schema_location = Pathname(path)
         @schema_location = Pathname(path)
       end
       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
       private
 
 
       def initialize_client_cache
       def initialize_client_cache

+ 32 - 0
test/graphql_test.rb

@@ -143,6 +143,38 @@ class GraphQLTest < Test::Unit::TestCase
     end
     end
   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
   private
 
 
   def version_fixtures(*versions)
   def version_fixtures(*versions)