shopify_api_bruv 0.2.7 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.env.template +0 -3
- data/CHANGELOG.md +9 -0
- data/Gemfile.lock +1 -1
- data/README.md +1 -1
- data/docs/README.md +12 -98
- data/docs/usage/auth/README.md +11 -0
- data/docs/usage/clients/README.md +4 -0
- data/docs/usage/clients/graphql/README.md +24 -0
- data/docs/usage/clients/rest/README.md +9 -0
- data/docs/usage/resources/README.md +4 -0
- data/docs/usage/resources/graphql/README.md +84 -0
- data/docs/usage/resources/rest/README.md +74 -0
- data/lib/shopify_api_bruv/clients/http_request.rb +23 -0
- data/lib/shopify_api_bruv/clients/http_response.rb +2 -2
- data/lib/shopify_api_bruv/errors/http_request_error.rb +8 -0
- data/lib/shopify_api_bruv/resources/base.rb +2 -2
- data/lib/shopify_api_bruv/resources/graphql/resource.rb +13 -9
- data/lib/shopify_api_bruv/resources/rest/{pagination_resource.rb → pagination.rb} +3 -3
- data/lib/shopify_api_bruv/resources/rest/resource.rb +7 -7
- data/lib/shopify_api_bruv/version.rb +1 -1
- metadata +10 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0c0d6c9a757b1c4164d65adcd704201932875e5451b7fc452206fce010847f16
|
4
|
+
data.tar.gz: 5139a1b215e2d4985857577edc2727e398edae28b068bc20744ec31b57052d81
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 82222f2e7665f99ea63e8c17a7c0445a01e61504ed37ac4c69aaac93704a576e55a813be22e8f4b89e45d85e66e87eea40e7f141f7b8f205f5380bddc89f7dfd
|
7
|
+
data.tar.gz: 19f07ef9290a43606159963d7eef46fc135376f90b9a58aad4e51209aca20950aa37dcea68bdf2bf5e269bffaf251bb0be17450fd771a42556f6057701af440f
|
data/.env.template
CHANGED
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
data/docs/README.md
CHANGED
@@ -1,101 +1,15 @@
|
|
1
|
-
#
|
1
|
+
# Getting started
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
SHOPIFY_API_BRUV_LOGGER_ENABLED="true" # Enables logger, remove or set to false to disable
|
7
|
-
SHOPIFY_API_BRUV_REQUEST_MAX_TRIES="3" # Max tries for resource class based requests
|
8
|
-
SHOPIFY_API_BRUV_REQUEST_SLEEP_TIMER="4" # Sleep timer for resource class based requests
|
9
|
-
SHOPIFY_API_BRUV_REQUEST_MINIMUM_CREDIT_LEFT="4" # Sleeps if credit left reaches this amount
|
10
|
-
```
|
11
|
-
|
12
|
-
## Auth
|
13
|
-
```ruby
|
14
|
-
# Initialize a config
|
15
|
-
config = ShopifyApiBruv::Auth::Config.new(
|
16
|
-
api_domain: "shop.myshopify.com",
|
17
|
-
api_version: "2023-10",
|
18
|
-
api_access_token: "ACCESS_TOKEN"
|
19
|
-
)
|
20
|
-
```
|
21
|
-
|
22
|
-
## Usage (GraphQL)
|
23
|
-
|
24
|
-
### Simple request
|
25
|
-
|
26
|
-
```ruby
|
27
|
-
# Initialize a graphql client and provide the config
|
28
|
-
client = ShopifyApiBruv::Clients::Graphql::Client.new(config:)
|
29
|
-
|
30
|
-
# Define a query
|
31
|
-
query = <<~GRAPHQL
|
32
|
-
query {
|
33
|
-
products(first: 250) {
|
34
|
-
edges {
|
35
|
-
node {
|
36
|
-
id
|
37
|
-
title
|
38
|
-
handle
|
39
|
-
}
|
40
|
-
}
|
41
|
-
}
|
42
|
-
}
|
43
|
-
GRAPHQL
|
44
|
-
|
45
|
-
# Make the request
|
46
|
-
client.request(query:)
|
47
|
-
```
|
48
|
-
|
49
|
-
### Using the resource class
|
3
|
+
- [Auth](./usage/auth/README.md)
|
4
|
+
- [Clients](./usage/clients/README.md)
|
5
|
+
- [Resources](./usage/resources/README.md)
|
50
6
|
|
51
|
-
|
52
|
-
class GetProducts < ShopifyApiBruv::Resources::Graphql::Resource
|
53
|
-
def query
|
54
|
-
<<~GRAPHQL
|
55
|
-
query {
|
56
|
-
products(first: 250) {
|
57
|
-
edges {
|
58
|
-
node {
|
59
|
-
id
|
60
|
-
title
|
61
|
-
handle
|
62
|
-
}
|
63
|
-
}
|
64
|
-
}
|
65
|
-
}
|
66
|
-
GRAPHQL
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
# Usage
|
71
|
-
GetProducts.request(config:)
|
72
|
-
```
|
73
|
-
|
74
|
-
## Usage (Rest)
|
75
|
-
|
76
|
-
### Simple request
|
77
|
-
|
78
|
-
```ruby
|
79
|
-
# Initialize a graphql client and provide the config
|
80
|
-
client = ShopifyApiBruv::Clients::Rest::Client.new(config:)
|
81
|
-
|
82
|
-
# Make the request
|
83
|
-
client.get(path: '/products')
|
84
|
-
```
|
85
|
-
|
86
|
-
### Using the resource class
|
87
|
-
|
88
|
-
```ruby
|
89
|
-
class GetProducts < ShopifyApiBruv::Resources::Rest::Resource
|
90
|
-
def initialize(config:)
|
91
|
-
super(
|
92
|
-
config:,
|
93
|
-
method: :get,
|
94
|
-
path: '/products'
|
95
|
-
)
|
96
|
-
end
|
97
|
-
end
|
7
|
+
## Environment variables
|
98
8
|
|
99
|
-
|
100
|
-
|
101
|
-
|
9
|
+
| Key | Default value | Type | Required |
|
10
|
+
| ------------------------------------------------------ | ------------- | ------- | -------- |
|
11
|
+
| `SHOPIFY_API_BRUV_LOGGER_ENABLED` | `false` | Boolean | No |
|
12
|
+
| `SHOPIFY_API_BRUV_RESOURCE_GRAPHQL_MAX_TRIES` | `3` | Integer | No |
|
13
|
+
| `SHOPIFY_API_BRUV_RESOURCE_GRAPHQL_SLEEP_TIMER` | `4` | Integer | No |
|
14
|
+
| `SHOPIFY_API_BRUV_RESOURCE_REST_SLEEP_TIMER` | `4` | Integer | No |
|
15
|
+
| `SHOPIFY_API_BRUV_RESOURCE_REST_CREDIT_LEFT_THRESHOLD` | `8` | Integer | No |
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# GraphQL
|
2
|
+
|
3
|
+
```ruby
|
4
|
+
# Initialize a graphql client
|
5
|
+
client = ShopifyApiBruv::Clients::Graphql::Client.new(config:)
|
6
|
+
|
7
|
+
# Define your query
|
8
|
+
query = <<~GRAPHQL
|
9
|
+
query {
|
10
|
+
products(first: 10) {
|
11
|
+
edges {
|
12
|
+
node {
|
13
|
+
id
|
14
|
+
title
|
15
|
+
handle
|
16
|
+
}
|
17
|
+
}
|
18
|
+
}
|
19
|
+
}
|
20
|
+
GRAPHQL
|
21
|
+
|
22
|
+
# Make the request
|
23
|
+
client.request(query:)
|
24
|
+
```
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# GraphQL
|
2
|
+
|
3
|
+
You can either use the resource class directly:
|
4
|
+
|
5
|
+
```ruby
|
6
|
+
resource = ShopifyApiBruv::Resources::Graphql::Resource.new(config:)
|
7
|
+
resource.query = <<~GRAPHQL
|
8
|
+
mutation productCreate($input: ProductInput!) {
|
9
|
+
productCreate(input: $input) {
|
10
|
+
product {
|
11
|
+
title
|
12
|
+
}
|
13
|
+
userErrors {
|
14
|
+
field
|
15
|
+
message
|
16
|
+
}
|
17
|
+
}
|
18
|
+
}
|
19
|
+
GRAPHQL
|
20
|
+
resource.variables = { input: { title: "Test Product" } }
|
21
|
+
resource.call
|
22
|
+
```
|
23
|
+
|
24
|
+
|
25
|
+
Or define it as a class inheriting from `ShopifyApiBruv::Resources::Graphql::Resource`
|
26
|
+
|
27
|
+
## Query
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
# frozen_string_literal: true
|
31
|
+
|
32
|
+
module Shopify
|
33
|
+
module Graphql
|
34
|
+
class GetProduct < ShopifyApiBruv::Resources::Graphql::Resource
|
35
|
+
QUERY = <<~GRAPHQL
|
36
|
+
query ($id: ID!) {
|
37
|
+
product(id: $id) {
|
38
|
+
id
|
39
|
+
title
|
40
|
+
}
|
41
|
+
}
|
42
|
+
GRAPHQL
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
```
|
47
|
+
|
48
|
+
Usage:
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
Shopify::Graphql::GetProduct.call(config:, variables: { id: "gid://shopify/Product/1234567890" })
|
52
|
+
```
|
53
|
+
|
54
|
+
## Mutation
|
55
|
+
|
56
|
+
```ruby
|
57
|
+
# frozen_string_literal: true
|
58
|
+
|
59
|
+
module Shopify
|
60
|
+
module Graphql
|
61
|
+
class CreateProduct < ShopifyApiBruv::Resources::Graphql::Resource
|
62
|
+
QUERY = <<~GRAPHQL
|
63
|
+
mutation productCreate($input: ProductInput!) {
|
64
|
+
productCreate(input: $input) {
|
65
|
+
product {
|
66
|
+
title
|
67
|
+
}
|
68
|
+
userErrors {
|
69
|
+
field
|
70
|
+
message
|
71
|
+
}
|
72
|
+
}
|
73
|
+
}
|
74
|
+
GRAPHQL
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
```
|
79
|
+
|
80
|
+
Usage:
|
81
|
+
|
82
|
+
```ruby
|
83
|
+
Shopify::Graphql::CreateProduct.call(config:, variables: { input: { title: "Test Product" } })
|
84
|
+
```
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# Rest
|
2
|
+
|
3
|
+
You can either use the resource class directly:
|
4
|
+
|
5
|
+
```ruby
|
6
|
+
resource = ShopifyApiBruv::Resources::Rest::Resource.new(
|
7
|
+
config:,
|
8
|
+
method: :get,
|
9
|
+
path: '/products',
|
10
|
+
query: { limit: 10 }
|
11
|
+
)
|
12
|
+
response = resource.call
|
13
|
+
|
14
|
+
# Built in pagination example
|
15
|
+
loop do
|
16
|
+
break if resource.pagination.nil? && !resource.pagination.next_page?
|
17
|
+
response = resource.pagination.fetch_next_page
|
18
|
+
end
|
19
|
+
```
|
20
|
+
|
21
|
+
Or define it as a class inheriting from `ShopifyApiBruv::Resources::Rest::Resource`
|
22
|
+
|
23
|
+
## Receive data
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
# frozen_string_literal: true
|
27
|
+
|
28
|
+
module Shopify
|
29
|
+
module Rest
|
30
|
+
class GetProduct < ShopifyApiBruv::Resources::Rest::Resource
|
31
|
+
def initialize(config:, id:)
|
32
|
+
super(
|
33
|
+
config:,
|
34
|
+
method: :get,
|
35
|
+
path: "/products/#{id}"
|
36
|
+
)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
```
|
42
|
+
|
43
|
+
Usage:
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
Shopify::Rest::GetProduct.call(config:, id: "1234567890")
|
47
|
+
```
|
48
|
+
|
49
|
+
## Populate data
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
# frozen_string_literal: true
|
53
|
+
|
54
|
+
module Shopify
|
55
|
+
module Rest
|
56
|
+
class CreateProduct < ShopifyApiBruv::Resources::Rest::Resource
|
57
|
+
def initialize(config:, body:)
|
58
|
+
super(
|
59
|
+
config:,
|
60
|
+
method: :post,
|
61
|
+
path: '/products',
|
62
|
+
body:
|
63
|
+
)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
```
|
69
|
+
|
70
|
+
Usage:
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
Shopify::Rest::CreateProduct.call(config:, body: { product: { title: "Test Product" } })
|
74
|
+
```
|
@@ -5,6 +5,13 @@ module ShopifyApiBruv
|
|
5
5
|
class HttpRequest
|
6
6
|
attr_reader :api, :method, :path, :body, :content_type, :query, :headers
|
7
7
|
|
8
|
+
VALID_METHODS = [
|
9
|
+
:get,
|
10
|
+
:delete,
|
11
|
+
:put,
|
12
|
+
:post
|
13
|
+
].freeze
|
14
|
+
|
8
15
|
def initialize(api:, method:, path:, body:, content_type:, query: nil, headers:)
|
9
16
|
@api = api
|
10
17
|
@method = method
|
@@ -14,11 +21,27 @@ module ShopifyApiBruv
|
|
14
21
|
@query = query
|
15
22
|
@headers = headers
|
16
23
|
|
24
|
+
validate
|
25
|
+
|
17
26
|
ShopifyApiBruv.logger(
|
18
27
|
method: :info,
|
19
28
|
message: "Shopify API Request (Method: #{method}):\nPath:\n#{path}\n\nBody:\n#{body}"
|
20
29
|
)
|
21
30
|
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def validate
|
35
|
+
raise Errors::HttpRequestError,
|
36
|
+
"Invalid method #{method}, valid methods are: #{VALID_METHODS}" unless VALID_METHODS.include?(method)
|
37
|
+
|
38
|
+
raise Errors::HttpRequestError,
|
39
|
+
'Content-Type missing' if !body.nil? && content_type.nil?
|
40
|
+
|
41
|
+
return unless [:put, :post].include?(method)
|
42
|
+
|
43
|
+
raise Errors::HttpRequestError, "Body is required for method #{method}" if body.nil?
|
44
|
+
end
|
22
45
|
end
|
23
46
|
end
|
24
47
|
end
|
@@ -10,12 +10,12 @@ module ShopifyApiBruv
|
|
10
10
|
@headers = headers
|
11
11
|
@body = body
|
12
12
|
|
13
|
+
validate
|
14
|
+
|
13
15
|
ShopifyApiBruv.logger(
|
14
16
|
method: :info,
|
15
17
|
message: "Shopify API Response (Code: #{code}):\nHeaders:\n#{headers}\n\nBody:\n#{body}"
|
16
18
|
)
|
17
|
-
|
18
|
-
validate
|
19
19
|
end
|
20
20
|
|
21
21
|
private
|
@@ -5,25 +5,29 @@ module ShopifyApiBruv
|
|
5
5
|
module Graphql
|
6
6
|
class Resource < Base
|
7
7
|
attr_reader :client
|
8
|
-
attr_accessor :query
|
8
|
+
attr_accessor :variables, :query
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
QUERY = nil
|
11
|
+
MAX_TRIES = ENV.fetch('SHOPIFY_API_BRUV_RESOURCE_GRAPHQL_MAX_TRIES', 3).to_i
|
12
|
+
SLEEP_TIMER = ENV.fetch('SHOPIFY_API_BRUV_RESOURCE_GRAPHQL_SLEEP_TIMER', 4).to_i
|
13
13
|
|
14
|
-
def initialize(config:)
|
14
|
+
def initialize(config:, variables: nil)
|
15
15
|
@client = Clients::Graphql::Client.new(config:)
|
16
|
+
@variables = variables
|
17
|
+
@query = self.class::QUERY unless self.class::QUERY.nil?
|
16
18
|
end
|
17
19
|
|
18
|
-
def
|
19
|
-
|
20
|
+
def call(tries: 0)
|
21
|
+
if query.nil?
|
22
|
+
raise Errors::ResourceError, "Please set attribute 'query' or define constant 'QUERY' in derived class"
|
23
|
+
end
|
20
24
|
|
21
25
|
response = client.request(query:, variables:)
|
22
26
|
body = response.body
|
23
27
|
|
24
28
|
handle_response_errors(body:, query:, variables:, tries:)
|
25
29
|
|
26
|
-
mutation_object_name = query.match(
|
30
|
+
mutation_object_name = query.match(/mutation\s+(\w+)\s*\(.*/)&.captures&.first
|
27
31
|
mutation_object_name.nil? ? body['data'] : body.dig('data', mutation_object_name)
|
28
32
|
end
|
29
33
|
|
@@ -37,7 +41,7 @@ module ShopifyApiBruv
|
|
37
41
|
if errors&.any? { |error| error['message'] == 'Throttled' }
|
38
42
|
sleep(SLEEP_TIMER)
|
39
43
|
|
40
|
-
|
44
|
+
call(tries: + 1)
|
41
45
|
end
|
42
46
|
|
43
47
|
raise Errors::ResourceError, errors unless errors.nil?
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module ShopifyApiBruv
|
4
4
|
module Resources
|
5
5
|
module Rest
|
6
|
-
class
|
6
|
+
class Pagination
|
7
7
|
attr_reader :resource, :page_info
|
8
8
|
|
9
9
|
def initialize(resource:, page_info:)
|
@@ -27,14 +27,14 @@ module ShopifyApiBruv
|
|
27
27
|
raise Errors::ResourceError, 'Next page cursor not found' unless next_page?
|
28
28
|
|
29
29
|
resource.query[:page_info] = page_info[:next]
|
30
|
-
resource.
|
30
|
+
resource.call
|
31
31
|
end
|
32
32
|
|
33
33
|
def fetch_previous_page
|
34
34
|
raise Errors::ResourceError, 'Previous page cursor not found' unless previous_page?
|
35
35
|
|
36
36
|
resource.query[:page_info] = page_info[:previous]
|
37
|
-
resource.
|
37
|
+
resource.call
|
38
38
|
end
|
39
39
|
end
|
40
40
|
end
|
@@ -5,10 +5,10 @@ module ShopifyApiBruv
|
|
5
5
|
module Rest
|
6
6
|
class Resource < Base
|
7
7
|
attr_reader :client, :method, :path, :body
|
8
|
-
attr_accessor :query, :
|
8
|
+
attr_accessor :query, :pagination
|
9
9
|
|
10
|
-
SLEEP_TIMER = ENV.fetch('
|
11
|
-
|
10
|
+
SLEEP_TIMER = ENV.fetch('SHOPIFY_API_BRUV_RESOURCE_REST_SLEEP_TIMER', 4).to_i
|
11
|
+
CREDIT_LEFT_THRESHOLD = ENV.fetch('SHOPIFY_API_BRUV_RESOURCE_REST_CREDIT_LEFT_THRESHOLD', 8).to_i
|
12
12
|
|
13
13
|
def initialize(config:, method:, path:, body: nil, query: nil)
|
14
14
|
@client = Clients::Rest::Client.new(config:)
|
@@ -20,13 +20,13 @@ module ShopifyApiBruv
|
|
20
20
|
validate_arguments
|
21
21
|
end
|
22
22
|
|
23
|
-
def
|
23
|
+
def call
|
24
24
|
response = client.public_send(method, path:, body:, query:)
|
25
25
|
|
26
26
|
handle_response_api_limits(headers: response.headers)
|
27
27
|
|
28
|
-
|
29
|
-
@
|
28
|
+
pagination = Pagination.new(resource: self, page_info: response.page_info)
|
29
|
+
@pagination = pagination if pagination.purpose?
|
30
30
|
|
31
31
|
response.body
|
32
32
|
end
|
@@ -45,7 +45,7 @@ module ShopifyApiBruv
|
|
45
45
|
limit = api_call_limit_header.pop.to_i - 1
|
46
46
|
used = api_call_limit_header.shift.to_i
|
47
47
|
|
48
|
-
if (limit - used) <=
|
48
|
+
if (limit - used) <= CREDIT_LEFT_THRESHOLD
|
49
49
|
sleep(SLEEP_TIMER)
|
50
50
|
end
|
51
51
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shopify_api_bruv
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Idjent
|
@@ -111,6 +111,13 @@ files:
|
|
111
111
|
- README.md
|
112
112
|
- Rakefile
|
113
113
|
- docs/README.md
|
114
|
+
- docs/usage/auth/README.md
|
115
|
+
- docs/usage/clients/README.md
|
116
|
+
- docs/usage/clients/graphql/README.md
|
117
|
+
- docs/usage/clients/rest/README.md
|
118
|
+
- docs/usage/resources/README.md
|
119
|
+
- docs/usage/resources/graphql/README.md
|
120
|
+
- docs/usage/resources/rest/README.md
|
114
121
|
- lib/shopify_api_bruv.rb
|
115
122
|
- lib/shopify_api_bruv/auth/config.rb
|
116
123
|
- lib/shopify_api_bruv/clients/graphql/client.rb
|
@@ -120,12 +127,13 @@ files:
|
|
120
127
|
- lib/shopify_api_bruv/clients/rest/client.rb
|
121
128
|
- lib/shopify_api_bruv/clients/rest/http_response.rb
|
122
129
|
- lib/shopify_api_bruv/errors/http_client_error.rb
|
130
|
+
- lib/shopify_api_bruv/errors/http_request_error.rb
|
123
131
|
- lib/shopify_api_bruv/errors/http_response_error.rb
|
124
132
|
- lib/shopify_api_bruv/errors/resource_error.rb
|
125
133
|
- lib/shopify_api_bruv/logger.rb
|
126
134
|
- lib/shopify_api_bruv/resources/base.rb
|
127
135
|
- lib/shopify_api_bruv/resources/graphql/resource.rb
|
128
|
-
- lib/shopify_api_bruv/resources/rest/
|
136
|
+
- lib/shopify_api_bruv/resources/rest/pagination.rb
|
129
137
|
- lib/shopify_api_bruv/resources/rest/resource.rb
|
130
138
|
- lib/shopify_api_bruv/version.rb
|
131
139
|
- sig/shopify_api_bruv.rbs
|