easyship 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +5 -0
- data/README.md +100 -2
- data/lib/easyship/client.rb +28 -9
- data/lib/easyship/configuration.rb +2 -1
- data/lib/easyship/version.rb +1 -1
- metadata +6 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7b584f647a6c1e9cd0379a94b3fc479c8f82691ab1ff8a36d797dae1c24e9c89
|
|
4
|
+
data.tar.gz: 5f288ce157f0b0b1c5e19f6c8a0a7851bf2bf1c5acb1c22b6660656ceed10204
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 22a0cbabb4582b714d56827fdd6f29bee92958900b2204ba3fce15a62ed85139e327dcfaa39dcf3f935cdeab0440424fa00bf044f003282ac9212837c97a83a2
|
|
7
|
+
data.tar.gz: fd30c1f4d75e89f2cc01ea8b97040cd19717af6f5e7d6bdb26a661507de197882be0f10f9cfaae2f49ed92d65e8aa5c8cd9f6ee3b24e4ef747da158012a94abc
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [v0.4.0](https://github.com/mmarusyk/easyship/tree/v0.4.0) - 2026-01-24
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- Support for custom headers by @mmarusyk in https://github.com/mmarusyk/easyship/pull/14
|
|
7
|
+
|
|
3
8
|
## [v0.3.0](https://github.com/mmarusyk/easyship/tree/v0.3.0) - 2025-11-29
|
|
4
9
|
|
|
5
10
|
### Added
|
data/README.md
CHANGED
|
@@ -58,10 +58,10 @@ Easyship.configure do |config|
|
|
|
58
58
|
end
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
-
Configuration supports the next keys: `url`, `api_key`, `per_page`, `requests_per_second`, `requests_per_minute`.
|
|
61
|
+
Configuration supports the next keys: `url`, `api_key`, `per_page`, `requests_per_second`, `requests_per_minute`, `headers`.
|
|
62
62
|
|
|
63
63
|
### Making Requests
|
|
64
|
-
`Easyship::Client` supports the next methods: `get`, `post`, `put`, `delete`.
|
|
64
|
+
`Easyship::Client` supports the next methods: `get`, `post`, `put`, `patch`, `delete`.
|
|
65
65
|
```ruby
|
|
66
66
|
Easyship::Client.instance.get('/2023-01/account')
|
|
67
67
|
```
|
|
@@ -174,6 +174,104 @@ Easyship::Client.instance.get('/2023-01/shipments', {
|
|
|
174
174
|
end
|
|
175
175
|
```
|
|
176
176
|
|
|
177
|
+
### Custom Headers
|
|
178
|
+
|
|
179
|
+
You can pass custom headers both globally (via configuration) and per-request.
|
|
180
|
+
|
|
181
|
+
**Global Headers (via Configuration):**
|
|
182
|
+
|
|
183
|
+
```ruby
|
|
184
|
+
Easyship.configure do |config|
|
|
185
|
+
config.url = 'api_url'
|
|
186
|
+
config.api_key = 'your_easyship_api_key'
|
|
187
|
+
config.headers = {
|
|
188
|
+
'X-Custom-Header' => 'custom-value'
|
|
189
|
+
}
|
|
190
|
+
end
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
**Per-Request Headers:**
|
|
194
|
+
|
|
195
|
+
```ruby
|
|
196
|
+
# Override or add headers for a specific request
|
|
197
|
+
Easyship::Client.instance.get('/2023-01/account', {}, headers: {
|
|
198
|
+
'X-Request-ID' => 'unique-request-id'
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
# POST with custom headers
|
|
202
|
+
Easyship::Client.instance.post('/2023-01/shipment', payload, headers: {
|
|
203
|
+
'X-Idempotency-Key' => 'unique-key'
|
|
204
|
+
})
|
|
205
|
+
|
|
206
|
+
# PUT with custom headers
|
|
207
|
+
Easyship::Client.instance.put('/2023-01/shipment/123', payload, headers: {
|
|
208
|
+
'X-Custom-Header' => 'value'
|
|
209
|
+
})
|
|
210
|
+
|
|
211
|
+
# PATCH with custom headers
|
|
212
|
+
Easyship::Client.instance.patch('/2023-01/shipment/123', payload, headers: {
|
|
213
|
+
'X-Custom-Header' => 'value'
|
|
214
|
+
})
|
|
215
|
+
|
|
216
|
+
# DELETE with custom headers
|
|
217
|
+
Easyship::Client.instance.delete('/2023-01/shipment/123', {}, headers: {
|
|
218
|
+
'X-Custom-Header' => 'value'
|
|
219
|
+
})
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
**Note:** Per-request headers will override global headers if the same header key is used.
|
|
223
|
+
|
|
224
|
+
### Using Idempotency Keys
|
|
225
|
+
|
|
226
|
+
Idempotency keys are essential for safely retrying requests without accidentally performing the same operation twice. This is particularly important for POST requests that create resources (like shipments, orders, or payments).
|
|
227
|
+
|
|
228
|
+
**Example - Creating a Shipment with Idempotency:**
|
|
229
|
+
|
|
230
|
+
```ruby
|
|
231
|
+
# Generate a unique key (e.g., UUID, database record ID, or any unique identifier)
|
|
232
|
+
idempotency_key = SecureRandom.uuid
|
|
233
|
+
|
|
234
|
+
payload = {
|
|
235
|
+
origin_country_alpha2: "SG",
|
|
236
|
+
destination_country_alpha2: "US",
|
|
237
|
+
tax_paid_by: "Recipient",
|
|
238
|
+
is_insured: false,
|
|
239
|
+
items: [
|
|
240
|
+
{
|
|
241
|
+
description: "Product",
|
|
242
|
+
actual_weight: 1.2,
|
|
243
|
+
height: 10,
|
|
244
|
+
width: 15,
|
|
245
|
+
length: 20,
|
|
246
|
+
declared_currency: "USD",
|
|
247
|
+
declared_customs_value: 50
|
|
248
|
+
}
|
|
249
|
+
]
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
begin
|
|
253
|
+
response = Easyship::Client.instance.post(
|
|
254
|
+
'/2023-01/shipments',
|
|
255
|
+
payload,
|
|
256
|
+
headers: { 'X-Idempotency-Key' => idempotency_key }
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
# If this request fails due to network issues and you retry with the same key,
|
|
260
|
+
# the API will return the same shipment without creating a duplicate
|
|
261
|
+
rescue Easyship::Errors::EasyshipError => e
|
|
262
|
+
# Safe to retry with the same idempotency_key
|
|
263
|
+
retry
|
|
264
|
+
end
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
**Best Practices:**
|
|
268
|
+
|
|
269
|
+
- Use unique, random keys (UUIDs are recommended)
|
|
270
|
+
- Store the idempotency key with your order/shipment record in your database
|
|
271
|
+
- Reuse the same key when retrying a failed request
|
|
272
|
+
- Don't reuse keys across different operations or resources
|
|
273
|
+
- Keys typically expire after 24 hours (check API documentation)
|
|
274
|
+
|
|
177
275
|
## Development
|
|
178
276
|
|
|
179
277
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. Then, eun `rake rubocop` to run the rubocop. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/lib/easyship/client.rb
CHANGED
|
@@ -16,46 +16,65 @@ module Easyship
|
|
|
16
16
|
@api_key = Easyship.configuration.api_key
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
def get(path, params = {}, &block)
|
|
19
|
+
def get(path, params = {}, headers: {}, &block)
|
|
20
20
|
if block
|
|
21
21
|
Easyship::Pagination::Cursor.new(self, path, params).all(&block)
|
|
22
22
|
else
|
|
23
|
-
response = connection.get(path, params)
|
|
23
|
+
response = connection(headers).get(path, params)
|
|
24
24
|
|
|
25
25
|
handle_response(response)
|
|
26
26
|
end
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
def post(path, params = {})
|
|
30
|
-
response = connection.post(path, params.to_json)
|
|
29
|
+
def post(path, params = {}, headers: {})
|
|
30
|
+
response = connection(headers).post(path, params.to_json)
|
|
31
31
|
|
|
32
32
|
handle_response(response)
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
-
def put(path, params = {})
|
|
36
|
-
response = connection.put(path, params.to_json)
|
|
35
|
+
def put(path, params = {}, headers: {})
|
|
36
|
+
response = connection(headers).put(path, params.to_json)
|
|
37
37
|
|
|
38
38
|
handle_response(response)
|
|
39
39
|
end
|
|
40
40
|
|
|
41
|
-
def delete(path, params = {})
|
|
42
|
-
response = connection.delete(path, params)
|
|
41
|
+
def delete(path, params = {}, headers: {})
|
|
42
|
+
response = connection(headers).delete(path, params)
|
|
43
|
+
|
|
44
|
+
handle_response(response)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def patch(path, params = {}, headers: {})
|
|
48
|
+
response = connection(headers).patch(path, params.to_json)
|
|
43
49
|
|
|
44
50
|
handle_response(response)
|
|
45
51
|
end
|
|
46
52
|
|
|
47
53
|
private
|
|
48
54
|
|
|
49
|
-
def connection
|
|
55
|
+
def connection(custom_headers = {})
|
|
50
56
|
Faraday.new(url: @url) do |faraday|
|
|
51
57
|
faraday.request :url_encoded
|
|
52
58
|
faraday.adapter Faraday.default_adapter
|
|
53
59
|
faraday.headers['Authorization'] = "Bearer #{@api_key}"
|
|
54
60
|
faraday.headers['Content-Type'] = 'application/json'
|
|
61
|
+
merge_headers(faraday, custom_headers)
|
|
55
62
|
faraday.use Easyship::Middleware::ErrorHandlerMiddleware
|
|
56
63
|
end
|
|
57
64
|
end
|
|
58
65
|
|
|
66
|
+
def merge_headers(faraday, custom_headers)
|
|
67
|
+
# Merge global configuration headers
|
|
68
|
+
Easyship.configuration.headers.each do |key, value|
|
|
69
|
+
faraday.headers[key] = value
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Merge request-specific headers (override globals)
|
|
73
|
+
custom_headers.each do |key, value|
|
|
74
|
+
faraday.headers[key] = value
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
59
78
|
def handle_response(response)
|
|
60
79
|
Easyship::Handlers::ResponseBodyHandler.handle_response(response)
|
|
61
80
|
end
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module Easyship
|
|
4
4
|
# Represents the configuration settings for the Easyship client.
|
|
5
5
|
class Configuration
|
|
6
|
-
attr_accessor :url, :api_key, :per_page, :requests_per_second, :requests_per_minute
|
|
6
|
+
attr_accessor :url, :api_key, :per_page, :requests_per_second, :requests_per_minute, :headers
|
|
7
7
|
|
|
8
8
|
def initialize
|
|
9
9
|
@url = nil
|
|
@@ -11,6 +11,7 @@ module Easyship
|
|
|
11
11
|
@per_page = 100 # Maximum possible number of items per page
|
|
12
12
|
@requests_per_second = nil
|
|
13
13
|
@requests_per_minute = nil
|
|
14
|
+
@headers = {}
|
|
14
15
|
end
|
|
15
16
|
end
|
|
16
17
|
end
|
data/lib/easyship/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: easyship
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Michael Marusyk
|
|
8
|
+
autorequire:
|
|
8
9
|
bindir: exe
|
|
9
10
|
cert_chain: []
|
|
10
|
-
date:
|
|
11
|
+
date: 2026-01-24 00:00:00.000000000 Z
|
|
11
12
|
dependencies:
|
|
12
13
|
- !ruby/object:Gem::Dependency
|
|
13
14
|
name: faraday
|
|
@@ -69,6 +70,7 @@ metadata:
|
|
|
69
70
|
allowed_push_host: https://rubygems.org
|
|
70
71
|
source_code_uri: https://github.com/mmarusyk/easyship
|
|
71
72
|
changelog_uri: https://github.com/mmarusyk/easyship/blob/main/CHANGELOG.md
|
|
73
|
+
post_install_message:
|
|
72
74
|
rdoc_options: []
|
|
73
75
|
require_paths:
|
|
74
76
|
- lib
|
|
@@ -83,7 +85,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
83
85
|
- !ruby/object:Gem::Version
|
|
84
86
|
version: '0'
|
|
85
87
|
requirements: []
|
|
86
|
-
rubygems_version: 3.
|
|
88
|
+
rubygems_version: 3.5.22
|
|
89
|
+
signing_key:
|
|
87
90
|
specification_version: 4
|
|
88
91
|
summary: A Ruby client for integrating with Easyship's API for shipping and logistics
|
|
89
92
|
management.
|