purple-client 0.1.7.3 → 0.1.7.5
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/README.md +122 -1
- data/lib/purple/path.rb +2 -2
- data/lib/purple/response.rb +1 -0
- data/lib/purple/responses/body.rb +4 -0
- data/lib/purple/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b5222522b4a3c4376e2a10f9ea7e4deece8f209d4f3fe4ac22dc9e12fe4445c7
|
4
|
+
data.tar.gz: e29a6b0c293f9dec1b84d322a46f8a00219c44890138e05b3ec507ae186eefb6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d9b273ed8a541e201b06221cb26696b9c6035bdbf06ae3d71dd37fad084b9e04a9a4b4af107284e32b98bf4076ee9ee26d67a41b34e83060b20530b2baf67ae3
|
7
|
+
data.tar.gz: 2c02a529e6df950dac3b480a0d736e3de51d822e5de6307ba9e6e8d675c8fe59623449475c664bc62300e2eb13e79e05cbd2d85bd2505eee9301f66d84239629
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Purple
|
1
|
+
# Purple Client
|
2
2
|
|
3
3
|
Purple::Client is a small DSL that helps you describe HTTP APIs. You define a domain, paths, and response structures, and the library generates handy methods for interacting with your service.
|
4
4
|
|
@@ -59,6 +59,36 @@ end
|
|
59
59
|
JobsClient.job(123)
|
60
60
|
```
|
61
61
|
|
62
|
+
### Simple POST request
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
class Amocrm::Client < Purple::Client
|
66
|
+
domain 'https://www.amocrm.ru'
|
67
|
+
|
68
|
+
path :oauth2 do
|
69
|
+
path :access_token, method: :post do
|
70
|
+
root_method :access_token
|
71
|
+
|
72
|
+
params do |client_id:, client_secret:, redirect_uri:, code:, grant_type: :authorization_code|
|
73
|
+
{ client_id:, client_secret:, redirect_uri:, code:, grant_type: }
|
74
|
+
end
|
75
|
+
|
76
|
+
response :ok do
|
77
|
+
body(
|
78
|
+
token_type: String,
|
79
|
+
expires_in: Integer,
|
80
|
+
server_time: Integer,
|
81
|
+
access_token: String,
|
82
|
+
refresh_token: String
|
83
|
+
)
|
84
|
+
end
|
85
|
+
|
86
|
+
response :bad_request
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
```
|
91
|
+
|
62
92
|
### Using authorization
|
63
93
|
|
64
94
|
```ruby
|
@@ -121,6 +151,36 @@ end
|
|
121
151
|
PostsClient.user_posts(user_id: 7)
|
122
152
|
```
|
123
153
|
|
154
|
+
### Paths nested under parameters
|
155
|
+
|
156
|
+
When a path segment is marked with `is_param: true`, any paths nested
|
157
|
+
inside it will not have a `root_method` generated. Instead of calling a
|
158
|
+
root method, you need to chain the segment methods manually.
|
159
|
+
|
160
|
+
```ruby
|
161
|
+
class BrowserClient < Purple::Client
|
162
|
+
domain 'https://api.example.com'
|
163
|
+
|
164
|
+
path :browser do
|
165
|
+
path :id, is_param: true do
|
166
|
+
path :web, method: :post do
|
167
|
+
response :ok do
|
168
|
+
end
|
169
|
+
|
170
|
+
response :bad_request do
|
171
|
+
body do |res|
|
172
|
+
puts res
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
# root_method :web will not work here
|
181
|
+
BrowserClient.browser.id('123').web
|
182
|
+
```
|
183
|
+
|
124
184
|
### Callbacks with additional arguments
|
125
185
|
|
126
186
|
```ruby
|
@@ -197,6 +257,30 @@ end
|
|
197
257
|
CalendarClient.schedule
|
198
258
|
```
|
199
259
|
|
260
|
+
### Allow blank fields
|
261
|
+
|
262
|
+
Some APIs return keys that are present but contain `null` or empty string values.
|
263
|
+
You can mark those fields with `allow_blank` so blank values do not raise
|
264
|
+
validation errors.
|
265
|
+
|
266
|
+
```ruby
|
267
|
+
class ProfilesClient < Purple::Client
|
268
|
+
domain 'https://api.example.com'
|
269
|
+
|
270
|
+
path :profile do
|
271
|
+
response :ok do
|
272
|
+
body(
|
273
|
+
middle_name: { type: String, allow_blank: true },
|
274
|
+
)
|
275
|
+
end
|
276
|
+
root_method :profile
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
# The `middle_name` attribute may be blank or omitted in the response
|
281
|
+
ProfilesClient.profile
|
282
|
+
```
|
283
|
+
|
200
284
|
### Array responses
|
201
285
|
|
202
286
|
When an endpoint returns an array of objects, you can use `:array_of` to
|
@@ -226,6 +310,43 @@ end
|
|
226
310
|
MerchantsClient.merchants
|
227
311
|
```
|
228
312
|
|
313
|
+
### Response body processing
|
314
|
+
|
315
|
+
After the body structure is validated, you can supply a block to `body`
|
316
|
+
to transform or handle the parsed response. This is useful for mapping
|
317
|
+
error payloads to simpler return values or for normalizing data.
|
318
|
+
|
319
|
+
```ruby
|
320
|
+
class MessagesClient < Purple::Client
|
321
|
+
domain 'https://api.example.com'
|
322
|
+
|
323
|
+
path :messages do
|
324
|
+
response :unprocessable_entity do
|
325
|
+
structure = {
|
326
|
+
status: Integer,
|
327
|
+
type: String,
|
328
|
+
title: String,
|
329
|
+
detail: String
|
330
|
+
}
|
331
|
+
|
332
|
+
body(**structure) do |res|
|
333
|
+
case res.type
|
334
|
+
when 'errors/invalid_recipient'
|
335
|
+
:not_found
|
336
|
+
else
|
337
|
+
res
|
338
|
+
end
|
339
|
+
end
|
340
|
+
end
|
341
|
+
root_method :send_message
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
# Returns :not_found when the recipient is invalid, otherwise returns the
|
346
|
+
# parsed response body.
|
347
|
+
MessagesClient.send_message
|
348
|
+
```
|
349
|
+
|
229
350
|
## Development
|
230
351
|
|
231
352
|
After checking out the repo, run `bin/setup` to install dependencies. Then run
|
data/lib/purple/path.rb
CHANGED
@@ -27,7 +27,7 @@ module Purple
|
|
27
27
|
@param_value = args.first
|
28
28
|
end
|
29
29
|
|
30
|
-
def method_missing(method_name, *args, &)
|
30
|
+
def method_missing(method_name, *args, **kw_args, &)
|
31
31
|
if children.any? { |child| child.name == method_name }
|
32
32
|
child = children.find { |child| child.name == method_name }
|
33
33
|
|
@@ -38,7 +38,7 @@ module Purple
|
|
38
38
|
if child.children.any?
|
39
39
|
child
|
40
40
|
else
|
41
|
-
callback_arguments = additional_callback_arguments.map do |arg|
|
41
|
+
callback_arguments = client.additional_callback_arguments.map do |arg|
|
42
42
|
kw_args.delete(arg)
|
43
43
|
end
|
44
44
|
|
data/lib/purple/response.rb
CHANGED
@@ -82,6 +82,10 @@ class Purple::Responses::Body
|
|
82
82
|
end
|
83
83
|
elsif value.is_a?(Array)
|
84
84
|
object[key].each do |item|
|
85
|
+
if value[0].is_a?(Symbol)
|
86
|
+
raise "Body structure definition error in key '#{key}' of structure #{substructure}."
|
87
|
+
end
|
88
|
+
|
85
89
|
check_structure!(item, value[0])
|
86
90
|
end
|
87
91
|
else
|
data/lib/purple/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: purple-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.7.
|
4
|
+
version: 0.1.7.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pavel Kalashnikov
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-08-
|
11
|
+
date: 2025-08-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dry-initializer
|