fetch-api 0.1.0 → 0.2.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/README.md +26 -10
- data/lib/fetch/client.rb +24 -4
- data/lib/fetch/form_data.rb +60 -0
- data/lib/fetch/url_search_params.rb +71 -0
- data/lib/fetch/version.rb +1 -1
- data/lib/fetch.rb +0 -1
- metadata +17 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ae66c4ee1f7d2b11e55480e6456be9eb78f5b1f6a2da0a22fb0cef1b4388328b
|
|
4
|
+
data.tar.gz: 2995e13999494f718966a8dc3f293342593a17f88a0c003b702243ae710492e2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 81683853c7d4e62b19dd0e4472b343958d656c361251239e160c44504b5671ba3b32078626433fd63f0be5a5a6290564cdc232f1db0a2c8dbbf462320b2102d8
|
|
7
|
+
data.tar.gz: ca6a9131aa1a4a3c504e74521b3c8244e89a66cc4f5e2e9bb27a7974352c910a7a869cd1ab96b531ccf694f3565e5ba93ae8de21d374006ac533ddb0f289241e
|
data/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Fetch API
|
|
1
|
+
# Fetch API for Ruby
|
|
2
2
|
|
|
3
3
|
Ruby's Net::HTTP is very powerful, but has a complicated API. OpenURI is easy to use, but has limited functionality. Third-party HTTP clients each have different APIs, and it can sometimes be difficult to learn how to use them.
|
|
4
4
|
|
|
@@ -30,9 +30,11 @@ require 'fetch-api'
|
|
|
30
30
|
res = Fetch::API.fetch('https://example.com')
|
|
31
31
|
|
|
32
32
|
# res is a Rack::Response object
|
|
33
|
-
puts res.body
|
|
33
|
+
puts res.body.first
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
+
or
|
|
37
|
+
|
|
36
38
|
``` ruby
|
|
37
39
|
require 'fetch-api'
|
|
38
40
|
|
|
@@ -41,6 +43,13 @@ include Fetch::API
|
|
|
41
43
|
res = fetch('https://example.com')
|
|
42
44
|
```
|
|
43
45
|
|
|
46
|
+
Supported options are as follows:
|
|
47
|
+
|
|
48
|
+
- `method`: HTTP method (default: `'GET'`)
|
|
49
|
+
- `headers`: Request headers (default: `{}`)
|
|
50
|
+
- `body`: Request body (default: `nil`)
|
|
51
|
+
- `redirect`: Follow redirects (one of `follow`, `error`, `manual`, default: `follow`)
|
|
52
|
+
|
|
44
53
|
### Post JSON
|
|
45
54
|
|
|
46
55
|
``` ruby
|
|
@@ -57,23 +66,30 @@ res = fetch('http://example.com', **{
|
|
|
57
66
|
})
|
|
58
67
|
```
|
|
59
68
|
|
|
60
|
-
### Post
|
|
69
|
+
### Post application/x-www-form-urlencoded
|
|
61
70
|
|
|
62
71
|
``` ruby
|
|
63
72
|
res = fetch('http://example.com', **{
|
|
64
73
|
method: 'POST',
|
|
65
74
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
},
|
|
69
|
-
|
|
70
|
-
body: Rack::Multipart.build_multipart(
|
|
71
|
-
file: Rack::Multipart::UploadedFile.new(io: StringIO.new('foo'), filename: 'foo.txt')
|
|
75
|
+
body: Fetch::URLSearchParams.new(
|
|
76
|
+
name: 'Alice'
|
|
72
77
|
)
|
|
73
78
|
})
|
|
74
79
|
```
|
|
75
80
|
|
|
76
|
-
|
|
81
|
+
### Post multipart/form-data
|
|
82
|
+
|
|
83
|
+
``` ruby
|
|
84
|
+
res = fetch('http://example.com', **{
|
|
85
|
+
method: 'POST',
|
|
86
|
+
|
|
87
|
+
body: Fetch::FormData.build(
|
|
88
|
+
name: 'Alice',
|
|
89
|
+
file: File.open('path/to/file.txt')
|
|
90
|
+
)
|
|
91
|
+
})
|
|
92
|
+
```
|
|
77
93
|
|
|
78
94
|
## Development
|
|
79
95
|
|
data/lib/fetch/client.rb
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
require_relative '../fetch'
|
|
2
|
+
require_relative 'form_data'
|
|
3
|
+
require_relative 'url_search_params'
|
|
2
4
|
|
|
5
|
+
require 'marcel'
|
|
3
6
|
require 'net/http'
|
|
4
|
-
require 'net/https'
|
|
5
7
|
require 'rack/response'
|
|
6
8
|
require 'singleton'
|
|
7
9
|
require 'uri'
|
|
@@ -18,7 +20,25 @@ module Fetch
|
|
|
18
20
|
req[k] = v
|
|
19
21
|
end
|
|
20
22
|
|
|
21
|
-
|
|
23
|
+
case body
|
|
24
|
+
when FormData
|
|
25
|
+
req.set_form body.entries.map {|k, v|
|
|
26
|
+
if v.is_a?(File)
|
|
27
|
+
[k, v, {
|
|
28
|
+
filename: File.basename(v.path),
|
|
29
|
+
content_type: Marcel::MimeType.for(v) || 'application/octet-stream'
|
|
30
|
+
}]
|
|
31
|
+
else
|
|
32
|
+
[k, v]
|
|
33
|
+
end
|
|
34
|
+
}, 'multipart/form-data'
|
|
35
|
+
when URLSearchParams
|
|
36
|
+
req['Content-Type'] ||= 'application/x-www-form-urlencoded'
|
|
37
|
+
|
|
38
|
+
req.body = body.to_s
|
|
39
|
+
else
|
|
40
|
+
req.body = body
|
|
41
|
+
end
|
|
22
42
|
|
|
23
43
|
http = Net::HTTP.new(uri.hostname, uri.port)
|
|
24
44
|
http.use_ssl = uri.scheme == 'https'
|
|
@@ -29,9 +49,9 @@ module Fetch
|
|
|
29
49
|
when Net::HTTPRedirection
|
|
30
50
|
case redirect
|
|
31
51
|
when 'follow'
|
|
32
|
-
fetch(res['
|
|
52
|
+
fetch(res['Location'], method:, headers:, body:, redirect:)
|
|
33
53
|
when 'error'
|
|
34
|
-
raise RedirectError, "redirected to #{res['
|
|
54
|
+
raise RedirectError, "redirected to #{res['Location']}"
|
|
35
55
|
when 'manual'
|
|
36
56
|
to_rack_response(res)
|
|
37
57
|
else
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
module Fetch
|
|
2
|
+
class FormData
|
|
3
|
+
include Enumerable
|
|
4
|
+
|
|
5
|
+
def self.build(enumerable)
|
|
6
|
+
data = FormData.new
|
|
7
|
+
|
|
8
|
+
enumerable.each do |k, v|
|
|
9
|
+
data.append k, v
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
data
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def initialize
|
|
16
|
+
@entries = []
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
attr_reader :entries
|
|
20
|
+
|
|
21
|
+
def append(key, value)
|
|
22
|
+
@entries.push [key.to_s, value]
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def delete(key)
|
|
26
|
+
@entries.reject! {|k,| k == key.to_s }
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def get(key)
|
|
30
|
+
@entries.assoc(key.to_s)&.last
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def get_all(key)
|
|
34
|
+
@entries.select {|k,| k == key.to_s }.map(&:last)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def has(key)
|
|
38
|
+
@entries.any? {|k,| k == key.to_s }
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def keys
|
|
42
|
+
@entries.map(&:first)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def set(key, value)
|
|
46
|
+
delete key
|
|
47
|
+
append key, value
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def values
|
|
51
|
+
@entries.map(&:last)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def each(&block)
|
|
55
|
+
return enum_for(:each) unless block_given?
|
|
56
|
+
|
|
57
|
+
@entries.each(&block)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
require 'uri'
|
|
2
|
+
|
|
3
|
+
module Fetch
|
|
4
|
+
class URLSearchParams
|
|
5
|
+
include Enumerable
|
|
6
|
+
|
|
7
|
+
def initialize(options = [])
|
|
8
|
+
@entries = []
|
|
9
|
+
|
|
10
|
+
case options
|
|
11
|
+
when String
|
|
12
|
+
initialize(URI.decode_www_form(options.delete_prefix('?')))
|
|
13
|
+
when Enumerable
|
|
14
|
+
options.each do |k, v|
|
|
15
|
+
append k, v
|
|
16
|
+
end
|
|
17
|
+
else
|
|
18
|
+
raise ArgumentError
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
attr_reader :entries
|
|
23
|
+
|
|
24
|
+
def append(key, value)
|
|
25
|
+
@entries.push [key.to_s, value]
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def delete(key)
|
|
29
|
+
@entries.reject! {|k,| k == key.to_s }
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def get(key)
|
|
33
|
+
@entries.assoc(key.to_s)&.last
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def get_all(key)
|
|
37
|
+
@entries.select {|k,| k == key.to_s }.map(&:last)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def has(key)
|
|
41
|
+
@entries.any? {|k,| k == key.to_s }
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def keys
|
|
45
|
+
@entries.map(&:first)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def set(key, value)
|
|
49
|
+
delete key
|
|
50
|
+
append key, value
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def sort
|
|
54
|
+
@entries.sort_by!(&:first)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def to_s
|
|
58
|
+
URI.encode_www_form(@entries)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def values
|
|
62
|
+
@entries.map(&:last)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def each(&block)
|
|
66
|
+
return enum_for(:each) unless block_given?
|
|
67
|
+
|
|
68
|
+
@entries.each(&block)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
data/lib/fetch/version.rb
CHANGED
data/lib/fetch.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: fetch-api
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Keita Urashima
|
|
@@ -10,6 +10,20 @@ bindir: exe
|
|
|
10
10
|
cert_chain: []
|
|
11
11
|
date: 2024-07-06 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: marcel
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '0'
|
|
13
27
|
- !ruby/object:Gem::Dependency
|
|
14
28
|
name: net-http
|
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -79,6 +93,8 @@ files:
|
|
|
79
93
|
- lib/fetch.rb
|
|
80
94
|
- lib/fetch/api.rb
|
|
81
95
|
- lib/fetch/client.rb
|
|
96
|
+
- lib/fetch/form_data.rb
|
|
97
|
+
- lib/fetch/url_search_params.rb
|
|
82
98
|
- lib/fetch/version.rb
|
|
83
99
|
- sig/fetch.rbs
|
|
84
100
|
homepage: https://github.com/ursm/fetch-api
|