Skip to content

Commit

Permalink
Merge pull request #1348 from Shopify/liz/config-to-disable-rest
Browse files Browse the repository at this point in the history
Add config option to disable the REST client
  • Loading branch information
lizkenyon authored Dec 2, 2024
2 parents 240be28 + c8a8c09 commit c6f95f0
Show file tree
Hide file tree
Showing 8 changed files with 110 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Note: For changes to the API, see https://shopify.dev/changelog?filter=api
- [#1347](https://github.com/Shopify/shopify-api-ruby/pull/1347) Extend webhook registration to support filters
- [#1344](https://github.com/Shopify/shopify-api-ruby/pull/1344) Allow ShopifyAPI::Webhooks::Registry to update a webhook when fields or metafield_namespaces are changed.
- [#1343](https://github.com/Shopify/shopify-api-ruby/pull/1343) Make ShopifyAPI::Context::scope parameter optional. `scope` defaults to empty list `[]`.
- [#1348](https://github.com/Shopify/shopify-api-ruby/pull/1348) Add config option that will disable the REST API client and REST resources. New apps should use the GraphQL Admin API

## 14.6.0

Expand Down
2 changes: 2 additions & 0 deletions docs/usage/rest.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# Make a REST API call
> [!WARNING]
> The Admin REST API has been deprecated. New apps should use the GraphQL Admin API. For more information see [All in on GraphQL](https://www.shopify.com/ca/partners/blog/all-in-on-graphql). New apps will be created with the config option `rest_disabled: true`. This will raise a `ShopifyAPI::Errors::DisabledResourceError` if you try to use the REST API.
Once OAuth is complete, we can use `ShopifyAPI`'s REST library to make authenticated API calls to the Shopify Admin API.
#### Required Session
Expand Down
5 changes: 5 additions & 0 deletions lib/shopify_api/clients/rest/admin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ class Admin < HttpClient

sig { params(session: T.nilable(Auth::Session), api_version: T.nilable(String)).void }
def initialize(session: nil, api_version: nil)
if Context.rest_disabled
raise Errors::DisabledResourceError,
"The Admin REST API has been deprecated. Please use the GraphQL Admin API. For more information see https://www.shopify.com/ca/partners/blog/all-in-on-graphql"
end

@api_version = T.let(api_version || Context.api_version, String)
if api_version
if api_version == Context.api_version
Expand Down
11 changes: 10 additions & 1 deletion lib/shopify_api/context.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class Context
@user_agent_prefix = T.let(nil, T.nilable(String))
@old_api_secret_key = T.let(nil, T.nilable(String))
@response_as_struct = T.let(false, T.nilable(T::Boolean))
@rest_disabled = T.let(false, T.nilable(T::Boolean))

@rest_resource_loader = T.let(nil, T.nilable(Zeitwerk::Loader))

Expand All @@ -45,6 +46,7 @@ class << self
old_api_secret_key: T.nilable(String),
api_host: T.nilable(String),
response_as_struct: T.nilable(T::Boolean),
rest_disabled: T.nilable(T::Boolean),
).void
end
def setup(
Expand All @@ -62,7 +64,8 @@ def setup(
user_agent_prefix: nil,
old_api_secret_key: nil,
api_host: nil,
response_as_struct: false
response_as_struct: false,
rest_disabled: false
)
unless ShopifyAPI::AdminVersions::SUPPORTED_ADMIN_VERSIONS.include?(api_version)
raise Errors::UnsupportedVersionError,
Expand All @@ -82,6 +85,7 @@ def setup(
@user_agent_prefix = user_agent_prefix
@old_api_secret_key = old_api_secret_key
@response_as_struct = response_as_struct
@rest_disabled = rest_disabled
@log_level = if valid_log_level?(log_level)
log_level.to_sym
else
Expand Down Expand Up @@ -178,6 +182,11 @@ def host_name
T.must(URI(T.must(host)).host)
end

sig { returns(T::Boolean) }
def rest_disabled
T.must(@rest_disabled)
end

private

sig { params(log_level: T.any(Symbol, String)).returns(T::Boolean) }
Expand Down
8 changes: 8 additions & 0 deletions lib/shopify_api/errors/disabled_resource_error.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# typed: strict
# frozen_string_literal: true

module ShopifyAPI
module Errors
class DisabledResourceError < StandardError; end
end
end
23 changes: 23 additions & 0 deletions test/clients/base_rest_resource_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,29 @@ def setup
ShopifyAPI::Context.load_rest_resources(api_version: ShopifyAPI::Context.api_version)
end

def test_rest_disabled
ShopifyAPI::Context.setup(
api_key: "test-key",
api_secret_key: "test-secret-key",
api_version: "2023-01",
is_private: true,
is_embedded: false,
rest_disabled: true,
)
assert_raises(ShopifyAPI::Errors::DisabledResourceError) do
TestHelpers::FakeResource.find(id: 1, session: @session)
end

ShopifyAPI::Context.setup(
api_key: "test-key",
api_secret_key: "test-secret-key",
api_version: "2023-01",
is_private: true,
is_embedded: false,
rest_disabled: false,
)
end

def test_finds_resource_by_id
body = { fake_resource: { id: 1, attribute: "attribute" } }.to_json

Expand Down
38 changes: 38 additions & 0 deletions test/clients/rest/admin_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,44 @@ def test_api_version_can_be_overrriden
run_test(:post)
end

def test_raises_error_when_rest_is_disabled
ShopifyAPI::Context.setup(
api_key: "test-key",
api_secret_key: "test-secret-key",
api_version: "2023-01",
is_private: true,
is_embedded: false,
rest_disabled: true,
)
session = ShopifyAPI::Auth::Session.new(
shop: "test-shop.myshopify.com",
access_token: SecureRandom.alphanumeric(10),
)

assert_raises(ShopifyAPI::Errors::DisabledResourceError,
"REST API access has been disabled via Context.rest_disabled") do
ShopifyAPI::Clients::Rest::Admin.new(session: session)
end
end

def test_client_works_normally_when_rest_is_not_disabled
ShopifyAPI::Context.setup(
api_key: "test-key",
api_secret_key: "test-secret-key",
api_version: "2023-01",
is_private: true,
is_embedded: false,
rest_disabled: false,
)
session = ShopifyAPI::Auth::Session.new(
shop: "test-shop.myshopify.com",
access_token: SecureRandom.alphanumeric(10),
)

client = ShopifyAPI::Clients::Rest::Admin.new(session: session)
refute_nil(client)
end

private

def run_test(http_method, path = "/some-path", expected_path = "some-path.json")
Expand Down
23 changes: 23 additions & 0 deletions test/context_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,29 @@ def test_scope_config_can_be_optional_and_defaults_to_empty
assert_equal(ShopifyAPI::Auth::AuthScopes.new, ShopifyAPI::Context.scope)
end

def test_rest_disabled_defaults_to_false
ShopifyAPI::Context.setup(
api_key: "test-key",
api_secret_key: "test-secret-key",
api_version: "2023-01",
is_private: true,
is_embedded: false,
)
refute(ShopifyAPI::Context.rest_disabled)
end

def test_rest_disabled_can_be_set_in_setup
ShopifyAPI::Context.setup(
api_key: "test-key",
api_secret_key: "test-secret-key",
api_version: "2023-01",
is_private: true,
is_embedded: false,
rest_disabled: true,
)
assert(ShopifyAPI::Context.rest_disabled)
end

def teardown
ShopifyAPI::Context.deactivate_session
end
Expand Down

0 comments on commit c6f95f0

Please sign in to comment.