graphql.rb 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. # frozen_string_literal: true
  2. require 'graphql/client'
  3. require 'shopify_api/graphql/http_client'
  4. module ShopifyAPI
  5. module GraphQL
  6. DEFAULT_SCHEMA_LOCATION_PATH = Pathname('shopify_graphql_schemas')
  7. InvalidSchema = Class.new(StandardError)
  8. InvalidClient = Class.new(StandardError)
  9. class << self
  10. delegate :parse, :query, to: :client
  11. def client(api_version = ShopifyAPI::Base.api_version.handle)
  12. initialize_client_cache
  13. cached_client = @_client_cache[api_version]
  14. if cached_client
  15. cached_client
  16. else
  17. schema_file = schema_location.join("#{api_version}.json")
  18. if !schema_file.exist?
  19. raise InvalidClient, <<~MSG
  20. Client for API version #{api_version} does not exist because no schema file exists at `#{schema_file}`.
  21. To dump the schema file, use the `rake shopify_api:graphql:dump` task.
  22. MSG
  23. else
  24. puts '[WARNING] Client was not pre-initialized. Ensure `ShopifyAPI::GraphQL.initialize_clients` is called during app initialization.'
  25. initialize_clients
  26. @_client_cache[api_version]
  27. end
  28. end
  29. end
  30. def clear_clients
  31. @_client_cache = {}
  32. end
  33. def initialize_clients(raise_on_invalid_schema: true)
  34. initialize_client_cache
  35. Dir.glob(schema_location.join("*.json")).each do |schema_file|
  36. schema_file = Pathname(schema_file)
  37. matches = schema_file.basename.to_s.match(/^#{ShopifyAPI::ApiVersion::HANDLE_FORMAT}\.json$/)
  38. if matches
  39. api_version = ShopifyAPI::ApiVersion.new(handle: matches[1])
  40. else
  41. if raise_on_invalid_schema
  42. raise InvalidSchema, "Invalid schema file name `#{schema_file}`. Does not match format of: `<version>.json`."
  43. else
  44. next
  45. end
  46. end
  47. schema = ::GraphQL::Client.load_schema(schema_file.to_s)
  48. client = ::GraphQL::Client.new(schema: schema, execute: HTTPClient.new(api_version)).tap do |c|
  49. c.allow_dynamic_queries = true
  50. end
  51. @_client_cache[api_version.handle] = client
  52. end
  53. end
  54. def schema_location
  55. @schema_location || DEFAULT_SCHEMA_LOCATION_PATH
  56. end
  57. def schema_location=(path)
  58. @schema_location = Pathname(path)
  59. end
  60. private
  61. def initialize_client_cache
  62. @_client_cache ||= {}
  63. end
  64. end
  65. end
  66. end