api-transformer 0.1.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 +7 -0
- data/.gitignore +14 -0
- data/.overcommit.yml +27 -0
- data/.rubocop.yml +9 -0
- data/.rubocop_todo.yml +15 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +358 -0
- data/Rakefile +9 -0
- data/api-transformer.gemspec +31 -0
- data/examples/ip_server.rb +19 -0
- data/lib/api/transformer.rb +1 -0
- data/lib/api_transformer/backend_request.rb +79 -0
- data/lib/api_transformer/backend_request_sender.rb +56 -0
- data/lib/api_transformer/backend_response.rb +62 -0
- data/lib/api_transformer/endpoint.rb +120 -0
- data/lib/api_transformer/errors.rb +4 -0
- data/lib/api_transformer/frontend_response.rb +52 -0
- data/lib/api_transformer/frontend_response_builder.rb +138 -0
- data/lib/api_transformer/params.rb +8 -0
- data/lib/api_transformer/rack/cookie_params.rb +38 -0
- data/lib/api_transformer/routes.rb +71 -0
- data/lib/api_transformer/version.rb +4 -0
- data/lib/api_transformer.rb +147 -0
- data/spec/server_spec.rb +746 -0
- data/spec/spec_helper.rb +3 -0
- metadata +199 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 87a3b324b1f0fd77ef0091e47311ef9e0029b92a
|
4
|
+
data.tar.gz: 7cf42588afe1e037df1ce743e4ac2c0e4c5a2398
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ddf7f252707a1340651a815251a1597a461495cee7be30a70521c01faea1d5c1394af59c753cb34422e96a3a91d61494fd22f515ed036cd27416fa123ac622a0
|
7
|
+
data.tar.gz: e670c237da02b04c635ad9b7ad76acec3612b8640afe0174257903802276d56d55852c5461324885634a41a8d5866b44190a35698f532a2f0fb89f68b1da5fcb
|
data/.gitignore
ADDED
data/.overcommit.yml
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# Use this file to configure the Overcommit hooks you wish to use. This will
|
2
|
+
# extend the default configuration defined in:
|
3
|
+
# https://github.com/causes/overcommit/blob/master/config/default.yml
|
4
|
+
#
|
5
|
+
# At the topmost level of this YAML file is a key representing type of hook
|
6
|
+
# being run (e.g. pre-commit, commit-msg, etc.). Within each type you can
|
7
|
+
# customize each hook, such as whether to only run it on certain files (via
|
8
|
+
# `include`), whether to only display output if it fails (via `quiet`), etc.
|
9
|
+
#
|
10
|
+
# For a complete list of hooks, see:
|
11
|
+
# https://github.com/causes/overcommit/tree/master/lib/overcommit/hook
|
12
|
+
#
|
13
|
+
# For a complete list of options that you can use to customize hooks, see:
|
14
|
+
# https://github.com/causes/overcommit#configuration
|
15
|
+
#
|
16
|
+
# Uncomment the following lines to make the configuration take effect.
|
17
|
+
|
18
|
+
PreCommit:
|
19
|
+
Rubocop:
|
20
|
+
on_warn: fail # Treat all warnings as failures
|
21
|
+
|
22
|
+
#PostCheckout:
|
23
|
+
# ALL: # Special hook name that customizes all hooks of this type
|
24
|
+
# quiet: true # Change all post-checkout hooks to only display output on failure
|
25
|
+
#
|
26
|
+
# IndexTags:
|
27
|
+
# enabled: true # Generate a tags file with `ctags` each time HEAD changes
|
data/.rubocop.yml
ADDED
data/.rubocop_todo.yml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# This configuration was generated by `rubocop --auto-gen-config`
|
2
|
+
# on 2014-09-12 14:27:20 -0700 using RuboCop version 0.24.1.
|
3
|
+
# The point is for the user to remove these configuration records
|
4
|
+
# one by one as the offenses are removed from the code base.
|
5
|
+
# Note that changes in the inspected code, or installation of new
|
6
|
+
# versions of RuboCop, may require this file to be generated again.
|
7
|
+
|
8
|
+
# Offense count: 2
|
9
|
+
Style/ClassVars:
|
10
|
+
Enabled: false
|
11
|
+
|
12
|
+
# Offense count: 1
|
13
|
+
# Configuration parameters: CountComments.
|
14
|
+
Metrics/ClassLength:
|
15
|
+
Max: 110
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Bruz Marzolf
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,358 @@
|
|
1
|
+
[](https://travis-ci.org/CXInc/api-transformer)
|
2
|
+
[](https://codeclimate.com/github/CXInc/api-transformer)
|
3
|
+
|
4
|
+
# api-transformer
|
5
|
+
|
6
|
+
**NOTE: this is currently a work in progress**
|
7
|
+
|
8
|
+
A Ruby web server DSL for exposing one or more back-end services through a different API.
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
Add this line to your application's Gemfile:
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
gem "api-transformer"
|
16
|
+
```
|
17
|
+
|
18
|
+
And then execute:
|
19
|
+
|
20
|
+
```bash
|
21
|
+
$ bundle
|
22
|
+
```
|
23
|
+
|
24
|
+
Or install it yourself as:
|
25
|
+
|
26
|
+
```bash
|
27
|
+
$ gem install api-transformer
|
28
|
+
```
|
29
|
+
|
30
|
+
## Usage
|
31
|
+
|
32
|
+
### Quick Start
|
33
|
+
|
34
|
+
Create a file ip_server.rb:
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
require 'api_transformer'
|
38
|
+
|
39
|
+
class IpServer < ApiTransformer::Server
|
40
|
+
base_url "http://ip.jsontest.com/"
|
41
|
+
|
42
|
+
get "/ip" do
|
43
|
+
request :ip do
|
44
|
+
path "/"
|
45
|
+
method :get
|
46
|
+
end
|
47
|
+
|
48
|
+
response do |data|
|
49
|
+
success do
|
50
|
+
status 200
|
51
|
+
attribute :your_ip, data[:ip][:ip]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
```
|
57
|
+
|
58
|
+
Run it:
|
59
|
+
|
60
|
+
```bash
|
61
|
+
$ ruby ip_server.rb -sv
|
62
|
+
```
|
63
|
+
|
64
|
+
Try it:
|
65
|
+
|
66
|
+
```bash
|
67
|
+
$ curl -i http://localhost:9000/ip
|
68
|
+
HTTP/1.1 200 OK
|
69
|
+
Server: Goliath
|
70
|
+
Date: Tue, 30 Sep 2014 23:19:34 GMT
|
71
|
+
|
72
|
+
{"your_ip":"74.125.228.96"}
|
73
|
+
```
|
74
|
+
|
75
|
+
Let's break this down:
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
base_url "http://ip.jsontest.com/"
|
79
|
+
```
|
80
|
+
|
81
|
+
Declare the base URL for back-end requests, which will each provide a path under this.
|
82
|
+
|
83
|
+
```ruby
|
84
|
+
get "/ip" do |params|
|
85
|
+
```
|
86
|
+
|
87
|
+
This defines a single endpoint that responds to GET requests at the path '/ip'.
|
88
|
+
|
89
|
+
request :ip do
|
90
|
+
path "/"
|
91
|
+
method :get
|
92
|
+
end
|
93
|
+
|
94
|
+
It makes a single GET request to the root path of the base_url (http://ip.jsontest.com/).
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
response do |data|
|
98
|
+
success do
|
99
|
+
status 200
|
100
|
+
attribute :your_ip, data[:ip][:ip]
|
101
|
+
end
|
102
|
+
end
|
103
|
+
```
|
104
|
+
|
105
|
+
Upon completion of the request to ip.jsontest.com with a 2XX response, it responds with a status of 200 and a JSON attribute of your_ip.
|
106
|
+
|
107
|
+
### Endpoints without any requests
|
108
|
+
|
109
|
+
Back-end requests are not required.
|
110
|
+
|
111
|
+
```ruby
|
112
|
+
get "/ping" do
|
113
|
+
response do
|
114
|
+
success { attribute :result, "pong" }
|
115
|
+
end
|
116
|
+
end
|
117
|
+
```
|
118
|
+
|
119
|
+
### Accepting parameters
|
120
|
+
|
121
|
+
Query params:
|
122
|
+
|
123
|
+
```ruby
|
124
|
+
get "/some_params" do
|
125
|
+
request :greeting do
|
126
|
+
path "/greeting"
|
127
|
+
method :get
|
128
|
+
|
129
|
+
query_param :greeting, "hello"
|
130
|
+
query_param :name, "Bob"
|
131
|
+
end
|
132
|
+
|
133
|
+
response do
|
134
|
+
success { attribute :result, "hello Bob" }
|
135
|
+
end
|
136
|
+
end
|
137
|
+
```
|
138
|
+
|
139
|
+
Form params:
|
140
|
+
|
141
|
+
```ruby
|
142
|
+
post "/some_params" do
|
143
|
+
request :greeting do
|
144
|
+
path "/greeting"
|
145
|
+
method :post
|
146
|
+
|
147
|
+
form_param :greeting, "hello"
|
148
|
+
form_param :name, "Bob"
|
149
|
+
end
|
150
|
+
|
151
|
+
response do
|
152
|
+
success { attribute :result, "hello Bob" }
|
153
|
+
end
|
154
|
+
end
|
155
|
+
```
|
156
|
+
|
157
|
+
JSON params:
|
158
|
+
|
159
|
+
```ruby
|
160
|
+
post "/some_params" do
|
161
|
+
request :greeting do
|
162
|
+
path "/greeting"
|
163
|
+
method :post
|
164
|
+
|
165
|
+
json_param :greeting, "hello"
|
166
|
+
json_param :name, "Bob"
|
167
|
+
end
|
168
|
+
|
169
|
+
response do
|
170
|
+
success { attribute :result, "hello Bob" }
|
171
|
+
end
|
172
|
+
end
|
173
|
+
```
|
174
|
+
|
175
|
+
JSON params are accepted as a JSON-encoded request body. In this case what would get sent to the back-end endpoint is {"greeting":"hello","name":"Bob"}.
|
176
|
+
|
177
|
+
Form and JSON params can't both be used on the same request.
|
178
|
+
|
179
|
+
### HTTP verbs
|
180
|
+
|
181
|
+
GET, POST, PUT and DELETE are provided:
|
182
|
+
|
183
|
+
```ruby
|
184
|
+
delete "/ping" do
|
185
|
+
response do
|
186
|
+
success { attribute :result, "I should probably delete something" }
|
187
|
+
end
|
188
|
+
end
|
189
|
+
```
|
190
|
+
|
191
|
+
### Pass-through of headers
|
192
|
+
|
193
|
+
```ruby
|
194
|
+
get "/user_agent" do |_, headers|
|
195
|
+
response do
|
196
|
+
success { attribute :user_agent, headers["User-Agent"] }
|
197
|
+
end
|
198
|
+
end
|
199
|
+
```
|
200
|
+
|
201
|
+
### JSON objects and arrays
|
202
|
+
|
203
|
+
Classes can be used to parse data and return JSON objects:
|
204
|
+
|
205
|
+
```ruby
|
206
|
+
class Bob
|
207
|
+
def initialize(last_name)
|
208
|
+
@last_name = last_name
|
209
|
+
end
|
210
|
+
|
211
|
+
def to_hash
|
212
|
+
{ first_name: "Bob", last_name: @last_name }
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
get "/object" do
|
217
|
+
response do
|
218
|
+
success { object :bob, Bob, "Saget" }
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
# => {"bob":{"first_name":"Bob","last_name":"Saget"}}
|
223
|
+
```
|
224
|
+
|
225
|
+
These can also be used to return arrays of data:
|
226
|
+
|
227
|
+
```ruby
|
228
|
+
get "/array" do
|
229
|
+
response do
|
230
|
+
success { array :bobs, Bob, %w(Ross Marley) }
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
# => {"bobs":[{"first_name":"Bob","last_name":"Ross"},{"first_name":"Bob","last_name":"Marley"}]}
|
235
|
+
```
|
236
|
+
|
237
|
+
### Use request data on subsequent requests
|
238
|
+
|
239
|
+
This is perhaps easiest to explain with an example:
|
240
|
+
|
241
|
+
```ruby
|
242
|
+
get "/multi" do
|
243
|
+
request :one do
|
244
|
+
path "/one"
|
245
|
+
method :get
|
246
|
+
end
|
247
|
+
|
248
|
+
request :two do |data|
|
249
|
+
path "/two"
|
250
|
+
method :get
|
251
|
+
|
252
|
+
query_param :name, data[:one][:name]
|
253
|
+
end
|
254
|
+
|
255
|
+
response do |data|
|
256
|
+
success { attribute :name, data[:two][:result] }
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
get "/one" do
|
261
|
+
response do
|
262
|
+
success { attribute :name, "Bob" }
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
get "/two" do |params|
|
267
|
+
response do
|
268
|
+
success { attribute :result, params[:name] }
|
269
|
+
end
|
270
|
+
end
|
271
|
+
```
|
272
|
+
|
273
|
+
Notably, on this line:
|
274
|
+
|
275
|
+
```ruby
|
276
|
+
request :two do |data|
|
277
|
+
```
|
278
|
+
|
279
|
+
`data` will contain the response data from the first request.
|
280
|
+
|
281
|
+
### Conditional requests
|
282
|
+
|
283
|
+
It can be useful to only send back-end requests under certain conditions:
|
284
|
+
|
285
|
+
```ruby
|
286
|
+
get "/conditional" do |params|
|
287
|
+
request :start_background_job, when: params[:make_it_so] do
|
288
|
+
path "/job"
|
289
|
+
method :post
|
290
|
+
end
|
291
|
+
|
292
|
+
response do
|
293
|
+
success { attribute :result, "OK" }
|
294
|
+
end
|
295
|
+
end
|
296
|
+
```
|
297
|
+
|
298
|
+
### Streaming
|
299
|
+
|
300
|
+
It can be done without a back-end request:
|
301
|
+
|
302
|
+
```ruby
|
303
|
+
get "/stream_no_backend" do
|
304
|
+
stream true
|
305
|
+
|
306
|
+
response do
|
307
|
+
success do
|
308
|
+
stream do
|
309
|
+
(1..9).each { |n| stream_write n }
|
310
|
+
end
|
311
|
+
end
|
312
|
+
end
|
313
|
+
end
|
314
|
+
```
|
315
|
+
|
316
|
+
Things to notice:
|
317
|
+
- Inside the endpoint block, `stream true` is needed
|
318
|
+
- Inside the success block, there's a `stream` block
|
319
|
+
- The `stream` block uses `stream_write` to write the response
|
320
|
+
|
321
|
+
This gets more useful when proxying to a back-end request that is going to return a lot of data:
|
322
|
+
|
323
|
+
```ruby
|
324
|
+
get "/stream_download" do
|
325
|
+
stream true
|
326
|
+
|
327
|
+
request :download do
|
328
|
+
path "/huge_download"
|
329
|
+
method :get
|
330
|
+
end
|
331
|
+
|
332
|
+
response do |data|
|
333
|
+
success do
|
334
|
+
stream do
|
335
|
+
data[:one].stream do |chunk|
|
336
|
+
stream_write chunk
|
337
|
+
end
|
338
|
+
end
|
339
|
+
end
|
340
|
+
end
|
341
|
+
end
|
342
|
+
```
|
343
|
+
|
344
|
+
The `stream do |chunk|` block will receive the data in small chunks as it comes off the socket, so that the entire response body doesn't go into memory.
|
345
|
+
|
346
|
+
## Testing
|
347
|
+
|
348
|
+
```bash
|
349
|
+
$ rake
|
350
|
+
```
|
351
|
+
|
352
|
+
## Contributing
|
353
|
+
|
354
|
+
1. Fork it ( https://github.com/CXInc/api-transformer/fork )
|
355
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
356
|
+
3. Commit your changes (`git commit -am "Add some feature"`)
|
357
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
358
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "api_transformer/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "api-transformer"
|
8
|
+
spec.version = ApiTransformer::VERSION
|
9
|
+
spec.authors = ["Bruz Marzolf"]
|
10
|
+
spec.email = ["bruz@bruzilla.com"]
|
11
|
+
spec.summary = "API transformation Ruby DSL and server"
|
12
|
+
spec.description = ""
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(/^bin\//) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(/^(test|spec|features)\//)
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "rack", "~> 1.5"
|
22
|
+
spec.add_dependency "goliath", "~> 1.0"
|
23
|
+
spec.add_dependency "em-http-request", "~> 1.1"
|
24
|
+
spec.add_dependency "json", "~> 1.8"
|
25
|
+
spec.add_dependency "hashie", "~> 3.3"
|
26
|
+
|
27
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
28
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
29
|
+
spec.add_development_dependency "pry", "~> 0.10"
|
30
|
+
spec.add_development_dependency "mocha", "~> 1.1"
|
31
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require_relative '../lib/api_transformer'
|
2
|
+
|
3
|
+
class IpServer < ApiTransformer::Server
|
4
|
+
base_url "http://ip.jsontest.com"
|
5
|
+
|
6
|
+
get "/ip" do
|
7
|
+
request :ip do
|
8
|
+
path "/"
|
9
|
+
method :get
|
10
|
+
end
|
11
|
+
|
12
|
+
response do |data|
|
13
|
+
success do
|
14
|
+
status 200
|
15
|
+
attribute :your_ip, data[:ip][:ip]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require_relative "../api_transformer"
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require "em-synchrony/em-http"
|
2
|
+
|
3
|
+
module ApiTransformer
|
4
|
+
# Process request blocks
|
5
|
+
class BackendRequest
|
6
|
+
attr_reader :name
|
7
|
+
attr_accessor :path, :method, :query_params, :form_params, :json_params,
|
8
|
+
:cookie_params
|
9
|
+
|
10
|
+
def initialize(name, base_url, frontend_headers)
|
11
|
+
@name = name
|
12
|
+
@base_url = base_url
|
13
|
+
@frontend_headers = frontend_headers
|
14
|
+
|
15
|
+
@query_params = {}
|
16
|
+
@form_params = {}
|
17
|
+
@json_params = {}
|
18
|
+
@cookie_params = {}
|
19
|
+
end
|
20
|
+
|
21
|
+
def send
|
22
|
+
url = @base_url + @path
|
23
|
+
|
24
|
+
EM::HttpRequest.new(url).send(
|
25
|
+
"a#{@method}",
|
26
|
+
query: @query_params,
|
27
|
+
body: body,
|
28
|
+
head: headers
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def body
|
35
|
+
case [@form_params.any?, @json_params.any?]
|
36
|
+
when [true, true]
|
37
|
+
fail RequestError, "A request cannot have both json and form parameters"
|
38
|
+
when [true, false]
|
39
|
+
@form_params
|
40
|
+
when [false, true]
|
41
|
+
@json_params.to_json
|
42
|
+
when [false, false]
|
43
|
+
nil
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def headers
|
48
|
+
ret = [stripped_frontend_headers, content_type, cookies].reduce(&:merge)
|
49
|
+
ret.delete("Host")
|
50
|
+
ret
|
51
|
+
end
|
52
|
+
|
53
|
+
def stripped_frontend_headers
|
54
|
+
@frontend_headers.reject { |key, _| key == "Content-Length" }
|
55
|
+
end
|
56
|
+
|
57
|
+
def content_type
|
58
|
+
if @json_params.any?
|
59
|
+
{ "Content-Type" => "application/json" }
|
60
|
+
elsif @form_params.any?
|
61
|
+
{ "Content-Type" => "application/x-www-form-urlencoded" }
|
62
|
+
else
|
63
|
+
{}
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def cookies
|
68
|
+
if @cookie_params.any?
|
69
|
+
cookie_string = @cookie_params
|
70
|
+
.map { |key, value| "#{key}=#{value};" }
|
71
|
+
.join(" ")
|
72
|
+
|
73
|
+
{ "Cookie" => cookie_string }
|
74
|
+
else
|
75
|
+
{}
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module ApiTransformer
|
2
|
+
# Processes the request block
|
3
|
+
class BackendRequestSender
|
4
|
+
def initialize(name, options, block, frontend_headers, helper_blocks)
|
5
|
+
@backend_request = BackendRequest.new(
|
6
|
+
name,
|
7
|
+
options[:base_url],
|
8
|
+
frontend_headers
|
9
|
+
)
|
10
|
+
|
11
|
+
@block = block
|
12
|
+
@helper_blocks = helper_blocks
|
13
|
+
end
|
14
|
+
|
15
|
+
def send(backend_responses)
|
16
|
+
@helper_blocks.each { |block| instance_eval(&block) }
|
17
|
+
instance_exec(backend_responses, &@block)
|
18
|
+
|
19
|
+
unless @backend_request.method
|
20
|
+
fail RequestError, "Missing method for backend request: #{request_name}"
|
21
|
+
end
|
22
|
+
|
23
|
+
@backend_request.send
|
24
|
+
end
|
25
|
+
|
26
|
+
def request_name
|
27
|
+
@backend_request.name
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def path(value)
|
33
|
+
@backend_request.path = value
|
34
|
+
end
|
35
|
+
|
36
|
+
def method(value)
|
37
|
+
@backend_request.method = value
|
38
|
+
end
|
39
|
+
|
40
|
+
def query_param(key, value)
|
41
|
+
@backend_request.query_params[key] = value
|
42
|
+
end
|
43
|
+
|
44
|
+
def form_param(key, value)
|
45
|
+
@backend_request.form_params[key] = value
|
46
|
+
end
|
47
|
+
|
48
|
+
def json_param(key, value)
|
49
|
+
@backend_request.json_params[key] = value
|
50
|
+
end
|
51
|
+
|
52
|
+
def cookie_param(key, value)
|
53
|
+
@backend_request.cookie_params[key] = value
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|