graphql.rb 2.9 KB

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