crapi 0.1.3 → 1.0.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/.circleci/config.yml +63 -0
- data/.rubocop.yml +53 -70
- data/.ruby-version +1 -1
- data/Gemfile.lock +66 -42
- data/README.md +29 -27
- data/crapi.gemspec +15 -15
- data/docs/{Crapi → CrAPI}/ArgumentError.html +15 -16
- data/docs/{Crapi → CrAPI}/BadHttpResponseError.html +15 -16
- data/docs/{Crapi → CrAPI}/Client.html +144 -174
- data/docs/{Crapi → CrAPI}/Error.html +14 -15
- data/docs/{Crapi → CrAPI}/Proxy.html +65 -89
- data/docs/CrAPI.html +157 -0
- data/docs/Net/HTTP.html +18 -23
- data/docs/_index.html +19 -19
- data/docs/class_list.html +3 -3
- data/docs/css/style.css +7 -9
- data/docs/file.README.html +68 -87
- data/docs/file_list.html +2 -2
- data/docs/frames.html +2 -2
- data/docs/index.html +68 -87
- data/docs/js/app.js +69 -3
- data/docs/method_list.html +34 -34
- data/docs/top-level-namespace.html +8 -8
- data/lib/crapi/client.rb +224 -228
- data/lib/crapi/errors.rb +7 -7
- data/lib/crapi/proxy.rb +82 -82
- data/lib/crapi/version.rb +10 -10
- data/lib/crapi.rb +3 -1
- data/spec/crapi_client_spec.rb +121 -0
- data/spec/crapi_errors_spec.rb +17 -0
- data/spec/crapi_proxy_spec.rb +121 -0
- data/spec/crapi_spec.rb +5 -0
- data/spec/spec_helper.rb +19 -0
- metadata +66 -52
- data/.travis.yml +0 -5
- data/docs/Crapi.html +0 -153
data/docs/file.README.html
CHANGED
@@ -6,15 +6,15 @@
|
|
6
6
|
<title>
|
7
7
|
File: README
|
8
8
|
|
9
|
-
— Documentation by YARD 0.9.
|
9
|
+
— Documentation by YARD 0.9.28
|
10
10
|
|
11
11
|
</title>
|
12
12
|
|
13
|
-
<link rel="stylesheet" href="css/style.css" type="text/css"
|
13
|
+
<link rel="stylesheet" href="css/style.css" type="text/css" />
|
14
14
|
|
15
|
-
<link rel="stylesheet" href="css/common.css" type="text/css"
|
15
|
+
<link rel="stylesheet" href="css/common.css" type="text/css" />
|
16
16
|
|
17
|
-
<script type="text/javascript"
|
17
|
+
<script type="text/javascript">
|
18
18
|
pathId = "README";
|
19
19
|
relpath = '';
|
20
20
|
</script>
|
@@ -57,29 +57,22 @@
|
|
57
57
|
<div class="clear"></div>
|
58
58
|
</div>
|
59
59
|
|
60
|
-
<div id="content"><div id='filecontents'>
|
61
|
-
<
|
60
|
+
<div id="content"><div id='filecontents'><p><a href="https://rubygems.org/gems/crapi"><img src="https://img.shields.io/github/v/release/nestor-custodio/crapi?color=green&label=gem%20version" alt="Gem Version" /></a>
|
61
|
+
<a href="https://tldrlegal.com/license/mit-license"><img src="https://img.shields.io/github/license/nestor-custodio/crapi" alt="MIT License" /></a></p>
|
62
62
|
|
63
|
-
<
|
64
|
-
there, but no other API wrapper gem (that I could find) provided the kind
|
65
|
-
of functionality you get from the Crapi::Proxy class, which is really the
|
66
|
-
biggest benefit here.</p>
|
63
|
+
<h1 id="crapi">CrAPI</h1>
|
67
64
|
|
68
|
-
<p
|
69
|
-
handily provides a base path for you (becaue some APIs and services have a
|
70
|
-
path that is always part of every request), <strong>Crapi::Proxy</strong>
|
71
|
-
lets you add to the root client's base path or default set of headers
|
72
|
-
without having to create any new connections.</p>
|
65
|
+
<p>CrAPI is yet another <u>Cr</u>ud <u>API</u> client wrapper. Yes, there is no shortage of these out there, but no other API wrapper gem (that I could find) provided the kind of functionality you get from the CrAPI::Proxy class, which is really the biggest benefit here.</p>
|
73
66
|
|
74
|
-
<p>
|
75
|
-
<u>API</u> client, and (honestly) “… It could be better.”™️</p>
|
67
|
+
<p><strong>CrAPI::Client</strong> will connect to the target system and handily provides a base path for you (because some APIs and services have a path that is always part of every request), <strong>CrAPI::Proxy</strong> lets you add to the root client’s base path or default set of headers without having to create any new connections.</p>
|
76
68
|
|
77
|
-
<h2 id="
|
69
|
+
<h2 id="installation">Installation</h2>
|
78
70
|
|
79
|
-
<p>Add this line to your application
|
71
|
+
<p>Add this line to your application’s Gemfile:</p>
|
80
72
|
|
81
|
-
<
|
82
|
-
|
73
|
+
<p><code>ruby
|
74
|
+
gem 'crapi'
|
75
|
+
</code></p>
|
83
76
|
|
84
77
|
<p>And then execute:</p>
|
85
78
|
|
@@ -91,99 +84,87 @@ without having to create any new connections.</p>
|
|
91
84
|
<pre class="code ruby"><code class="ruby">$ gem install crapi
|
92
85
|
</code></pre>
|
93
86
|
|
94
|
-
<h2 id="
|
87
|
+
<h2 id="using-the-crapi-tools">Using The CrAPI Tools</h2>
|
88
|
+
|
89
|
+
<h3 id="client-usage">Client Usage</h3>
|
90
|
+
|
91
|
+
<p>```ruby
|
92
|
+
# Connect to an API.</p>
|
93
|
+
|
94
|
+
<p>api = CrAPI::Client.new(‘https://jsonplaceholder.typicode.com/’)</p>
|
95
|
+
|
96
|
+
<h1 id="issue-requests-against-the-api">Issue requests against the API.</h1>
|
95
97
|
|
96
|
-
<
|
98
|
+
<p>api.get(‘users/1’) # GETs /users/1; returns a Hash.</p>
|
97
99
|
|
98
|
-
<
|
99
|
-
</span>
|
100
|
-
<span class='id identifier rubyid_api'>api</span> <span class='op'>=</span> <span class='const'><span class='object_link'><a href="Crapi.html" title="Crapi (module)">Crapi</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Crapi/Client.html" title="Crapi::Client (class)">Client</a></span></span><span class='period'>.</span><span class='id identifier rubyid_new'><span class='object_link'><a href="Crapi/Client.html#initialize-instance_method" title="Crapi::Client#initialize (method)">new</a></span></span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>https://jsonplaceholder.typicode.com/</span><span class='tstring_end'>'</span></span><span class='rparen'>)</span>
|
100
|
+
<p>api.get(‘posts’, query: { userId: 2 }) # GETs /posts?userId=2; returns an Array.</p>
|
101
101
|
|
102
|
+
<p>mew_comment = { user: ‘megapwner’, text: ‘FRIST!!1!’ }
|
103
|
+
api.post(‘comments’, payload: new_comment) # POSTs to /comments; returns a Hash.
|
104
|
+
```</p>
|
102
105
|
|
103
|
-
<
|
104
|
-
</span>
|
105
|
-
<span class='id identifier rubyid_api'>api</span><span class='period'>.</span><span class='id identifier rubyid_get'>get</span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>users/1</span><span class='tstring_end'>'</span></span><span class='rparen'>)</span> <span class='comment'>## GETs /users/1; returns a Hash.
|
106
|
-
</span>
|
107
|
-
<span class='id identifier rubyid_api'>api</span><span class='period'>.</span><span class='id identifier rubyid_get'>get</span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>posts</span><span class='tstring_end'>'</span></span><span class='comma'>,</span> <span class='label'>query:</span> <span class='lbrace'>{</span> <span class='label'>userId:</span> <span class='int'>2</span> <span class='rbrace'>}</span><span class='rparen'>)</span> <span class='comment'>## GETs /posts?userId=2; returns an Array.
|
108
|
-
</span>
|
109
|
-
<span class='id identifier rubyid_mew_comment'>mew_comment</span> <span class='op'>=</span> <span class='lbrace'>{</span> <span class='label'>user:</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>megapwner</span><span class='tstring_end'>'</span></span><span class='comma'>,</span> <span class='label'>text:</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>FRIST!!1!</span><span class='tstring_end'>'</span></span> <span class='rbrace'>}</span>
|
110
|
-
<span class='id identifier rubyid_api'>api</span><span class='period'>.</span><span class='id identifier rubyid_post'>post</span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>comments</span><span class='tstring_end'>'</span></span><span class='comma'>,</span> <span class='label'>payload:</span> <span class='id identifier rubyid_new_comment'>new_comment</span><span class='rparen'>)</span> <span class='comment'>## POSTs to /comments; returns a Hash.
|
111
|
-
</span></code></pre>
|
112
|
-
<hr>
|
106
|
+
<hr />
|
113
107
|
|
114
|
-
<h3 id="
|
108
|
+
<h3 id="proxy-usage">Proxy Usage</h3>
|
115
109
|
|
116
|
-
<
|
117
|
-
|
118
|
-
<span class='id identifier rubyid_api'>api</span> <span class='op'>=</span> <span class='const'><span class='object_link'><a href="Crapi.html" title="Crapi (module)">Crapi</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Crapi/Client.html" title="Crapi::Client (class)">Client</a></span></span><span class='period'>.</span><span class='id identifier rubyid_new'><span class='object_link'><a href="Crapi/Client.html#initialize-instance_method" title="Crapi::Client#initialize (method)">new</a></span></span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>https://versioned.fake-api.com/api/</span><span class='tstring_end'>'</span></span><span class='rparen'>)</span>
|
110
|
+
<p>```ruby
|
111
|
+
# Connect to an API.</p>
|
119
112
|
|
113
|
+
<p>api = CrAPI::Client.new(‘https://versioned.fake-api.com/api/’)</p>
|
120
114
|
|
121
|
-
<
|
122
|
-
</span>
|
123
|
-
<span class='id identifier rubyid_v1'>v1</span> <span class='op'>=</span> <span class='id identifier rubyid_api'>api</span><span class='period'>.</span><span class='id identifier rubyid_new_proxy'>new_proxy</span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>/v1</span><span class='tstring_end'>'</span></span><span class='rparen'>)</span>
|
115
|
+
<h1 id="back-in-the-v1-days-versioning-of-this-api-was-via-the-url-">Back in the v1 days, versioning of this API was via the URL …</h1>
|
124
116
|
|
125
|
-
<
|
126
|
-
</span><span class='id identifier rubyid_v1'>v1</span><span class='period'>.</span><span class='id identifier rubyid_post'>post</span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>data</span><span class='tstring_end'>'</span></span><span class='comma'>,</span> <span class='label'>payload:</span> <span class='id identifier rubyid_values'>values</span><span class='rparen'>)</span> <span class='comment'>## POSTs *values* to /api/v1/data.
|
127
|
-
</span>
|
117
|
+
<p>v1 = api.new_proxy(‘/v1’)</p>
|
128
118
|
|
129
|
-
<
|
130
|
-
</
|
131
|
-
<span class='id identifier rubyid_v2'>v2</span> <span class='op'>=</span> <span class='id identifier rubyid_api'>api</span><span class='period'>.</span><span class='id identifier rubyid_new_proxy'>new_proxy</span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>/</span><span class='tstring_end'>'</span></span><span class='comma'>,</span> <span class='label'>headers:</span> <span class='lbrace'>{</span> <span class='label'>Accept:</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>application/vnd.fake-api.v2+json</span><span class='tstring_end'>'</span></span> <span class='rbrace'>}</span><span class='rparen'>)</span>
|
119
|
+
<p>v1.get(‘data’) # GETs /api/v1/data; pretty straight-forward.
|
120
|
+
v1.post(‘data’, payload: values) # POSTs <em>values</em> to /api/v1/data.</p>
|
132
121
|
|
133
|
-
<
|
134
|
-
</span>
|
122
|
+
<h1 id="for-api-v2-they-switched-to-an-accept-header-approach-">For API v2, they switched to an Accept header approach …</h1>
|
135
123
|
|
136
|
-
<
|
137
|
-
</span>
|
138
|
-
<span class='id identifier rubyid_v3'>v3</span> <span class='op'>=</span> <span class='id identifier rubyid_api'>api</span><span class='period'>.</span><span class='id identifier rubyid_new_proxy'>new_proxy</span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>/</span><span class='tstring_end'>'</span></span><span class='comma'>,</span> <span class='label'>headers:</span> <span class='lbrace'>{</span> <span class='label'>Accept:</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>application/vnd.fake-api.v3+json</span><span class='tstring_end'>'</span></span> <span class='rbrace'>}</span><span class='rparen'>)</span>
|
124
|
+
<p>v2 = api.new_proxy(‘/’, headers: { Accept: ‘application/vnd.fake-api.v2+json’ })</p>
|
139
125
|
|
140
|
-
<
|
141
|
-
</span>
|
126
|
+
<p>v2.get(‘data’) # GETs /api/data with the v2 header.</p>
|
142
127
|
|
143
|
-
<
|
144
|
-
</span><span class='comment'>## v1, v2, and v3 API calls ad hoc without having to juggle paths/headers yourself.
|
145
|
-
</span></code></pre>
|
146
|
-
<hr>
|
128
|
+
<h1 id="api-v3-keeps-the-accept-header-approach-">API v3 keeps the Accept header approach …</h1>
|
147
129
|
|
148
|
-
<p
|
149
|
-
repo docs for the full Crapi documentation.</a></p>
|
130
|
+
<p>v3 = api.new_proxy(‘/’, headers: { Accept: ‘application/vnd.fake-api.v3+json’ })</p>
|
150
131
|
|
151
|
-
<
|
132
|
+
<p>v3.get(‘data’) # GETs /api/data with the v3 header.</p>
|
133
|
+
|
134
|
+
<h1 id="note-that-only-one-connection-to-the-client-is-made-and-you-can-easily-make">Note that only one connection to the client is made and you can easily make</h1>
|
135
|
+
<p># v1, v2, and v3 API calls ad hoc without having to juggle paths/headers yourself.
|
136
|
+
```</p>
|
137
|
+
|
138
|
+
<hr />
|
139
|
+
|
140
|
+
<p><a href="http://nestor-custodio.github.io/crapi/CrAPI.html">Consult the repo docs for the full CrAPI documentation.</a></p>
|
141
|
+
|
142
|
+
<h2 id="feature-roadmap--future-development">Feature Roadmap / Future Development</h2>
|
152
143
|
|
153
144
|
<p>Additional features/options coming in the future:</p>
|
154
|
-
<ul><li>
|
155
|
-
<p>Cleaner handling of non-body-returning calls.</p>
|
156
|
-
</li><li>
|
157
|
-
<p>More resilient serializing of non-String paylods when using custom
|
158
|
-
Content-Type headers.</p>
|
159
|
-
</li></ul>
|
160
145
|
|
161
|
-
<
|
146
|
+
<ul>
|
147
|
+
<li>Cleaner handling of non-body-returning calls.</li>
|
148
|
+
<li>More resilient serializing of non-String paylods when using custom Content-Type headers.</li>
|
149
|
+
</ul>
|
150
|
+
|
151
|
+
<h2 id="contribution--development">Contribution / Development</h2>
|
162
152
|
|
163
|
-
<p>Bug reports and pull requests are welcome
|
164
|
-
href="https://github.com/nestor-custodio/crapi">github.com/nestor-custodio/crapi</a>.</p>
|
153
|
+
<p>Bug reports and pull requests are welcome at: <a href="https://github.com/nestor-custodio/crapi">https://github.com/nestor-custodio/crapi</a></p>
|
165
154
|
|
166
|
-
<p>After checking out the repo, run <code>bin/setup</code> to install
|
167
|
-
dependencies. Then, run <code>rake spec</code> to run the tests. You can
|
168
|
-
also run <code>bin/console</code> for an interactive prompt that will allow
|
169
|
-
you to experiment.</p>
|
155
|
+
<p>After checking out the repo, run <code>bin/setup</code> to install dependencies. Then, run <code>bundle exec rspec</code> to run the tests. You can also run <code>bin/console</code> for an interactive prompt that will allow you to experiment.</p>
|
170
156
|
|
171
|
-
<p>Linting is courtesy of <a
|
172
|
-
href="https://github.com/bbatsov/rubocop">Rubocop</a> and documentation is
|
173
|
-
built using <a href="https://yardoc.org/">Yard</a>. Neither is included in
|
174
|
-
the Gemspec; you'll need to install these locally (<code>gem install
|
175
|
-
rubocop yard</code>) to take advantage.</p>
|
157
|
+
<p>Linting is courtesy of <a href="https://docs.rubocop.org/">Rubocop</a> (<code>bundle exec rubocop</code>) and documentation is built using <a href="https://yardoc.org/">Yard</a> (<code>bundle exec yard</code>). Please ensure you have a clean bill of health from Rubocop and that any new features and/or changes to behaviour are reflected in the documentation before submitting a pull request.</p>
|
176
158
|
|
177
|
-
<h2 id="
|
159
|
+
<h2 id="license">License</h2>
|
178
160
|
|
179
|
-
<p>
|
180
|
-
href="https://opensource.org/licenses/MIT">MIT License</a>.</p>
|
161
|
+
<p>CrAPI is available as open source under the terms of the <a href="https://tldrlegal.com/license/mit-license">MIT License</a>.</p>
|
181
162
|
</div></div>
|
182
163
|
|
183
164
|
<div id="footer">
|
184
|
-
Generated on
|
185
|
-
<a href="
|
186
|
-
0.9.
|
165
|
+
Generated on Mon Jan 2 15:16:45 2023 by
|
166
|
+
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
167
|
+
0.9.28 (ruby-3.0.4).
|
187
168
|
</div>
|
188
169
|
|
189
170
|
</div>
|
data/docs/file_list.html
CHANGED
@@ -4,9 +4,9 @@
|
|
4
4
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
5
5
|
<meta charset="utf-8" />
|
6
6
|
|
7
|
-
<link rel="stylesheet" href="css/full_list.css" type="text/css" media="screen"
|
7
|
+
<link rel="stylesheet" href="css/full_list.css" type="text/css" media="screen" />
|
8
8
|
|
9
|
-
<link rel="stylesheet" href="css/common.css" type="text/css" media="screen"
|
9
|
+
<link rel="stylesheet" href="css/common.css" type="text/css" media="screen" />
|
10
10
|
|
11
11
|
|
12
12
|
|
data/docs/frames.html
CHANGED
@@ -2,9 +2,9 @@
|
|
2
2
|
<html>
|
3
3
|
<head>
|
4
4
|
<meta charset="utf-8">
|
5
|
-
<title>Documentation by YARD 0.9.
|
5
|
+
<title>Documentation by YARD 0.9.28</title>
|
6
6
|
</head>
|
7
|
-
<script type="text/javascript"
|
7
|
+
<script type="text/javascript">
|
8
8
|
var match = unescape(window.location.hash).match(/^#!(.+)/);
|
9
9
|
var name = match ? match[1] : 'index.html';
|
10
10
|
name = name.replace(/^(\w+):\/\//, '').replace(/^\/\//, '');
|
data/docs/index.html
CHANGED
@@ -6,15 +6,15 @@
|
|
6
6
|
<title>
|
7
7
|
File: README
|
8
8
|
|
9
|
-
— Documentation by YARD 0.9.
|
9
|
+
— Documentation by YARD 0.9.28
|
10
10
|
|
11
11
|
</title>
|
12
12
|
|
13
|
-
<link rel="stylesheet" href="css/style.css" type="text/css"
|
13
|
+
<link rel="stylesheet" href="css/style.css" type="text/css" />
|
14
14
|
|
15
|
-
<link rel="stylesheet" href="css/common.css" type="text/css"
|
15
|
+
<link rel="stylesheet" href="css/common.css" type="text/css" />
|
16
16
|
|
17
|
-
<script type="text/javascript"
|
17
|
+
<script type="text/javascript">
|
18
18
|
pathId = "README";
|
19
19
|
relpath = '';
|
20
20
|
</script>
|
@@ -57,29 +57,22 @@
|
|
57
57
|
<div class="clear"></div>
|
58
58
|
</div>
|
59
59
|
|
60
|
-
<div id="content"><div id='filecontents'>
|
61
|
-
<
|
60
|
+
<div id="content"><div id='filecontents'><p><a href="https://rubygems.org/gems/crapi"><img src="https://img.shields.io/github/v/release/nestor-custodio/crapi?color=green&label=gem%20version" alt="Gem Version" /></a>
|
61
|
+
<a href="https://tldrlegal.com/license/mit-license"><img src="https://img.shields.io/github/license/nestor-custodio/crapi" alt="MIT License" /></a></p>
|
62
62
|
|
63
|
-
<
|
64
|
-
there, but no other API wrapper gem (that I could find) provided the kind
|
65
|
-
of functionality you get from the Crapi::Proxy class, which is really the
|
66
|
-
biggest benefit here.</p>
|
63
|
+
<h1 id="crapi">CrAPI</h1>
|
67
64
|
|
68
|
-
<p
|
69
|
-
handily provides a base path for you (becaue some APIs and services have a
|
70
|
-
path that is always part of every request), <strong>Crapi::Proxy</strong>
|
71
|
-
lets you add to the root client's base path or default set of headers
|
72
|
-
without having to create any new connections.</p>
|
65
|
+
<p>CrAPI is yet another <u>Cr</u>ud <u>API</u> client wrapper. Yes, there is no shortage of these out there, but no other API wrapper gem (that I could find) provided the kind of functionality you get from the CrAPI::Proxy class, which is really the biggest benefit here.</p>
|
73
66
|
|
74
|
-
<p>
|
75
|
-
<u>API</u> client, and (honestly) “… It could be better.”™️</p>
|
67
|
+
<p><strong>CrAPI::Client</strong> will connect to the target system and handily provides a base path for you (because some APIs and services have a path that is always part of every request), <strong>CrAPI::Proxy</strong> lets you add to the root client’s base path or default set of headers without having to create any new connections.</p>
|
76
68
|
|
77
|
-
<h2 id="
|
69
|
+
<h2 id="installation">Installation</h2>
|
78
70
|
|
79
|
-
<p>Add this line to your application
|
71
|
+
<p>Add this line to your application’s Gemfile:</p>
|
80
72
|
|
81
|
-
<
|
82
|
-
|
73
|
+
<p><code>ruby
|
74
|
+
gem 'crapi'
|
75
|
+
</code></p>
|
83
76
|
|
84
77
|
<p>And then execute:</p>
|
85
78
|
|
@@ -91,99 +84,87 @@ without having to create any new connections.</p>
|
|
91
84
|
<pre class="code ruby"><code class="ruby">$ gem install crapi
|
92
85
|
</code></pre>
|
93
86
|
|
94
|
-
<h2 id="
|
87
|
+
<h2 id="using-the-crapi-tools">Using The CrAPI Tools</h2>
|
88
|
+
|
89
|
+
<h3 id="client-usage">Client Usage</h3>
|
90
|
+
|
91
|
+
<p>```ruby
|
92
|
+
# Connect to an API.</p>
|
93
|
+
|
94
|
+
<p>api = CrAPI::Client.new(‘https://jsonplaceholder.typicode.com/’)</p>
|
95
|
+
|
96
|
+
<h1 id="issue-requests-against-the-api">Issue requests against the API.</h1>
|
95
97
|
|
96
|
-
<
|
98
|
+
<p>api.get(‘users/1’) # GETs /users/1; returns a Hash.</p>
|
97
99
|
|
98
|
-
<
|
99
|
-
</span>
|
100
|
-
<span class='id identifier rubyid_api'>api</span> <span class='op'>=</span> <span class='const'><span class='object_link'><a href="Crapi.html" title="Crapi (module)">Crapi</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Crapi/Client.html" title="Crapi::Client (class)">Client</a></span></span><span class='period'>.</span><span class='id identifier rubyid_new'><span class='object_link'><a href="Crapi/Client.html#initialize-instance_method" title="Crapi::Client#initialize (method)">new</a></span></span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>https://jsonplaceholder.typicode.com/</span><span class='tstring_end'>'</span></span><span class='rparen'>)</span>
|
100
|
+
<p>api.get(‘posts’, query: { userId: 2 }) # GETs /posts?userId=2; returns an Array.</p>
|
101
101
|
|
102
|
+
<p>mew_comment = { user: ‘megapwner’, text: ‘FRIST!!1!’ }
|
103
|
+
api.post(‘comments’, payload: new_comment) # POSTs to /comments; returns a Hash.
|
104
|
+
```</p>
|
102
105
|
|
103
|
-
<
|
104
|
-
</span>
|
105
|
-
<span class='id identifier rubyid_api'>api</span><span class='period'>.</span><span class='id identifier rubyid_get'>get</span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>users/1</span><span class='tstring_end'>'</span></span><span class='rparen'>)</span> <span class='comment'>## GETs /users/1; returns a Hash.
|
106
|
-
</span>
|
107
|
-
<span class='id identifier rubyid_api'>api</span><span class='period'>.</span><span class='id identifier rubyid_get'>get</span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>posts</span><span class='tstring_end'>'</span></span><span class='comma'>,</span> <span class='label'>query:</span> <span class='lbrace'>{</span> <span class='label'>userId:</span> <span class='int'>2</span> <span class='rbrace'>}</span><span class='rparen'>)</span> <span class='comment'>## GETs /posts?userId=2; returns an Array.
|
108
|
-
</span>
|
109
|
-
<span class='id identifier rubyid_mew_comment'>mew_comment</span> <span class='op'>=</span> <span class='lbrace'>{</span> <span class='label'>user:</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>megapwner</span><span class='tstring_end'>'</span></span><span class='comma'>,</span> <span class='label'>text:</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>FRIST!!1!</span><span class='tstring_end'>'</span></span> <span class='rbrace'>}</span>
|
110
|
-
<span class='id identifier rubyid_api'>api</span><span class='period'>.</span><span class='id identifier rubyid_post'>post</span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>comments</span><span class='tstring_end'>'</span></span><span class='comma'>,</span> <span class='label'>payload:</span> <span class='id identifier rubyid_new_comment'>new_comment</span><span class='rparen'>)</span> <span class='comment'>## POSTs to /comments; returns a Hash.
|
111
|
-
</span></code></pre>
|
112
|
-
<hr>
|
106
|
+
<hr />
|
113
107
|
|
114
|
-
<h3 id="
|
108
|
+
<h3 id="proxy-usage">Proxy Usage</h3>
|
115
109
|
|
116
|
-
<
|
117
|
-
|
118
|
-
<span class='id identifier rubyid_api'>api</span> <span class='op'>=</span> <span class='const'><span class='object_link'><a href="Crapi.html" title="Crapi (module)">Crapi</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Crapi/Client.html" title="Crapi::Client (class)">Client</a></span></span><span class='period'>.</span><span class='id identifier rubyid_new'><span class='object_link'><a href="Crapi/Client.html#initialize-instance_method" title="Crapi::Client#initialize (method)">new</a></span></span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>https://versioned.fake-api.com/api/</span><span class='tstring_end'>'</span></span><span class='rparen'>)</span>
|
110
|
+
<p>```ruby
|
111
|
+
# Connect to an API.</p>
|
119
112
|
|
113
|
+
<p>api = CrAPI::Client.new(‘https://versioned.fake-api.com/api/’)</p>
|
120
114
|
|
121
|
-
<
|
122
|
-
</span>
|
123
|
-
<span class='id identifier rubyid_v1'>v1</span> <span class='op'>=</span> <span class='id identifier rubyid_api'>api</span><span class='period'>.</span><span class='id identifier rubyid_new_proxy'>new_proxy</span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>/v1</span><span class='tstring_end'>'</span></span><span class='rparen'>)</span>
|
115
|
+
<h1 id="back-in-the-v1-days-versioning-of-this-api-was-via-the-url-">Back in the v1 days, versioning of this API was via the URL …</h1>
|
124
116
|
|
125
|
-
<
|
126
|
-
</span><span class='id identifier rubyid_v1'>v1</span><span class='period'>.</span><span class='id identifier rubyid_post'>post</span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>data</span><span class='tstring_end'>'</span></span><span class='comma'>,</span> <span class='label'>payload:</span> <span class='id identifier rubyid_values'>values</span><span class='rparen'>)</span> <span class='comment'>## POSTs *values* to /api/v1/data.
|
127
|
-
</span>
|
117
|
+
<p>v1 = api.new_proxy(‘/v1’)</p>
|
128
118
|
|
129
|
-
<
|
130
|
-
</
|
131
|
-
<span class='id identifier rubyid_v2'>v2</span> <span class='op'>=</span> <span class='id identifier rubyid_api'>api</span><span class='period'>.</span><span class='id identifier rubyid_new_proxy'>new_proxy</span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>/</span><span class='tstring_end'>'</span></span><span class='comma'>,</span> <span class='label'>headers:</span> <span class='lbrace'>{</span> <span class='label'>Accept:</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>application/vnd.fake-api.v2+json</span><span class='tstring_end'>'</span></span> <span class='rbrace'>}</span><span class='rparen'>)</span>
|
119
|
+
<p>v1.get(‘data’) # GETs /api/v1/data; pretty straight-forward.
|
120
|
+
v1.post(‘data’, payload: values) # POSTs <em>values</em> to /api/v1/data.</p>
|
132
121
|
|
133
|
-
<
|
134
|
-
</span>
|
122
|
+
<h1 id="for-api-v2-they-switched-to-an-accept-header-approach-">For API v2, they switched to an Accept header approach …</h1>
|
135
123
|
|
136
|
-
<
|
137
|
-
</span>
|
138
|
-
<span class='id identifier rubyid_v3'>v3</span> <span class='op'>=</span> <span class='id identifier rubyid_api'>api</span><span class='period'>.</span><span class='id identifier rubyid_new_proxy'>new_proxy</span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>/</span><span class='tstring_end'>'</span></span><span class='comma'>,</span> <span class='label'>headers:</span> <span class='lbrace'>{</span> <span class='label'>Accept:</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>application/vnd.fake-api.v3+json</span><span class='tstring_end'>'</span></span> <span class='rbrace'>}</span><span class='rparen'>)</span>
|
124
|
+
<p>v2 = api.new_proxy(‘/’, headers: { Accept: ‘application/vnd.fake-api.v2+json’ })</p>
|
139
125
|
|
140
|
-
<
|
141
|
-
</span>
|
126
|
+
<p>v2.get(‘data’) # GETs /api/data with the v2 header.</p>
|
142
127
|
|
143
|
-
<
|
144
|
-
</span><span class='comment'>## v1, v2, and v3 API calls ad hoc without having to juggle paths/headers yourself.
|
145
|
-
</span></code></pre>
|
146
|
-
<hr>
|
128
|
+
<h1 id="api-v3-keeps-the-accept-header-approach-">API v3 keeps the Accept header approach …</h1>
|
147
129
|
|
148
|
-
<p
|
149
|
-
repo docs for the full Crapi documentation.</a></p>
|
130
|
+
<p>v3 = api.new_proxy(‘/’, headers: { Accept: ‘application/vnd.fake-api.v3+json’ })</p>
|
150
131
|
|
151
|
-
<
|
132
|
+
<p>v3.get(‘data’) # GETs /api/data with the v3 header.</p>
|
133
|
+
|
134
|
+
<h1 id="note-that-only-one-connection-to-the-client-is-made-and-you-can-easily-make">Note that only one connection to the client is made and you can easily make</h1>
|
135
|
+
<p># v1, v2, and v3 API calls ad hoc without having to juggle paths/headers yourself.
|
136
|
+
```</p>
|
137
|
+
|
138
|
+
<hr />
|
139
|
+
|
140
|
+
<p><a href="http://nestor-custodio.github.io/crapi/CrAPI.html">Consult the repo docs for the full CrAPI documentation.</a></p>
|
141
|
+
|
142
|
+
<h2 id="feature-roadmap--future-development">Feature Roadmap / Future Development</h2>
|
152
143
|
|
153
144
|
<p>Additional features/options coming in the future:</p>
|
154
|
-
<ul><li>
|
155
|
-
<p>Cleaner handling of non-body-returning calls.</p>
|
156
|
-
</li><li>
|
157
|
-
<p>More resilient serializing of non-String paylods when using custom
|
158
|
-
Content-Type headers.</p>
|
159
|
-
</li></ul>
|
160
145
|
|
161
|
-
<
|
146
|
+
<ul>
|
147
|
+
<li>Cleaner handling of non-body-returning calls.</li>
|
148
|
+
<li>More resilient serializing of non-String paylods when using custom Content-Type headers.</li>
|
149
|
+
</ul>
|
150
|
+
|
151
|
+
<h2 id="contribution--development">Contribution / Development</h2>
|
162
152
|
|
163
|
-
<p>Bug reports and pull requests are welcome
|
164
|
-
href="https://github.com/nestor-custodio/crapi">github.com/nestor-custodio/crapi</a>.</p>
|
153
|
+
<p>Bug reports and pull requests are welcome at: <a href="https://github.com/nestor-custodio/crapi">https://github.com/nestor-custodio/crapi</a></p>
|
165
154
|
|
166
|
-
<p>After checking out the repo, run <code>bin/setup</code> to install
|
167
|
-
dependencies. Then, run <code>rake spec</code> to run the tests. You can
|
168
|
-
also run <code>bin/console</code> for an interactive prompt that will allow
|
169
|
-
you to experiment.</p>
|
155
|
+
<p>After checking out the repo, run <code>bin/setup</code> to install dependencies. Then, run <code>bundle exec rspec</code> to run the tests. You can also run <code>bin/console</code> for an interactive prompt that will allow you to experiment.</p>
|
170
156
|
|
171
|
-
<p>Linting is courtesy of <a
|
172
|
-
href="https://github.com/bbatsov/rubocop">Rubocop</a> and documentation is
|
173
|
-
built using <a href="https://yardoc.org/">Yard</a>. Neither is included in
|
174
|
-
the Gemspec; you'll need to install these locally (<code>gem install
|
175
|
-
rubocop yard</code>) to take advantage.</p>
|
157
|
+
<p>Linting is courtesy of <a href="https://docs.rubocop.org/">Rubocop</a> (<code>bundle exec rubocop</code>) and documentation is built using <a href="https://yardoc.org/">Yard</a> (<code>bundle exec yard</code>). Please ensure you have a clean bill of health from Rubocop and that any new features and/or changes to behaviour are reflected in the documentation before submitting a pull request.</p>
|
176
158
|
|
177
|
-
<h2 id="
|
159
|
+
<h2 id="license">License</h2>
|
178
160
|
|
179
|
-
<p>
|
180
|
-
href="https://opensource.org/licenses/MIT">MIT License</a>.</p>
|
161
|
+
<p>CrAPI is available as open source under the terms of the <a href="https://tldrlegal.com/license/mit-license">MIT License</a>.</p>
|
181
162
|
</div></div>
|
182
163
|
|
183
164
|
<div id="footer">
|
184
|
-
Generated on
|
185
|
-
<a href="
|
186
|
-
0.9.
|
165
|
+
Generated on Mon Jan 2 15:16:45 2023 by
|
166
|
+
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
167
|
+
0.9.28 (ruby-3.0.4).
|
187
168
|
</div>
|
188
169
|
|
189
170
|
</div>
|
data/docs/js/app.js
CHANGED
@@ -120,6 +120,49 @@ function summaryToggle() {
|
|
120
120
|
} else { localStorage.summaryCollapsed = "expand"; }
|
121
121
|
}
|
122
122
|
|
123
|
+
function constantSummaryToggle() {
|
124
|
+
$('.constants_summary_toggle').click(function(e) {
|
125
|
+
e.preventDefault();
|
126
|
+
localStorage.summaryCollapsed = $(this).text();
|
127
|
+
$('.constants_summary_toggle').each(function() {
|
128
|
+
$(this).text($(this).text() == "collapse" ? "expand" : "collapse");
|
129
|
+
var next = $(this).parent().parent().nextAll('dl.constants').first();
|
130
|
+
if (next.hasClass('compact')) {
|
131
|
+
next.toggle();
|
132
|
+
next.nextAll('dl.constants').first().toggle();
|
133
|
+
}
|
134
|
+
else if (next.hasClass('constants')) {
|
135
|
+
var list = $('<dl class="constants compact" />');
|
136
|
+
list.html(next.html());
|
137
|
+
list.find('dt').each(function() {
|
138
|
+
$(this).addClass('summary_signature');
|
139
|
+
$(this).text( $(this).text().split('=')[0]);
|
140
|
+
if ($(this).has(".deprecated").length) {
|
141
|
+
$(this).addClass('deprecated');
|
142
|
+
};
|
143
|
+
});
|
144
|
+
// Add the value of the constant as "Tooltip" to the summary object
|
145
|
+
list.find('pre.code').each(function() {
|
146
|
+
console.log($(this).parent());
|
147
|
+
var dt_element = $(this).parent().prev();
|
148
|
+
var tooltip = $(this).text();
|
149
|
+
if (dt_element.hasClass("deprecated")) {
|
150
|
+
tooltip = 'Deprecated. ' + tooltip;
|
151
|
+
};
|
152
|
+
dt_element.attr('title', tooltip);
|
153
|
+
});
|
154
|
+
list.find('.docstring, .tags, dd').remove();
|
155
|
+
next.before(list);
|
156
|
+
next.toggle();
|
157
|
+
}
|
158
|
+
});
|
159
|
+
return false;
|
160
|
+
});
|
161
|
+
if (localStorage.summaryCollapsed == "collapse") {
|
162
|
+
$('.constants_summary_toggle').first().click();
|
163
|
+
} else { localStorage.summaryCollapsed = "expand"; }
|
164
|
+
}
|
165
|
+
|
123
166
|
function generateTOC() {
|
124
167
|
if ($('#filecontents').length === 0) return;
|
125
168
|
var _toc = $('<ol class="top"></ol>');
|
@@ -128,6 +171,7 @@ function generateTOC() {
|
|
128
171
|
var counter = 0;
|
129
172
|
var tags = ['h2', 'h3', 'h4', 'h5', 'h6'];
|
130
173
|
var i;
|
174
|
+
var curli;
|
131
175
|
if ($('#filecontents h1').length > 1) tags.unshift('h1');
|
132
176
|
for (i = 0; i < tags.length; i++) { tags[i] = '#filecontents ' + tags[i]; }
|
133
177
|
var lastTag = parseInt(tags[0][1], 10);
|
@@ -147,15 +191,25 @@ function generateTOC() {
|
|
147
191
|
}
|
148
192
|
if (thisTag > lastTag) {
|
149
193
|
for (i = 0; i < thisTag - lastTag; i++) {
|
150
|
-
|
194
|
+
if ( typeof(curli) == "undefined" ) {
|
195
|
+
curli = $('<li/>');
|
196
|
+
toc.append(curli);
|
197
|
+
}
|
198
|
+
toc = $('<ol/>');
|
199
|
+
curli.append(toc);
|
200
|
+
curli = undefined;
|
151
201
|
}
|
152
202
|
}
|
153
203
|
if (thisTag < lastTag) {
|
154
|
-
for (i = 0; i < lastTag - thisTag; i++)
|
204
|
+
for (i = 0; i < lastTag - thisTag; i++) {
|
205
|
+
toc = toc.parent();
|
206
|
+
toc = toc.parent();
|
207
|
+
}
|
155
208
|
}
|
156
209
|
var title = $(this).attr('toc-title');
|
157
210
|
if (typeof(title) == "undefined") title = $(this).text();
|
158
|
-
|
211
|
+
curli =$('<li><a href="#' + this.id + '">' + title + '</a></li>');
|
212
|
+
toc.append(curli);
|
159
213
|
lastTag = thisTag;
|
160
214
|
});
|
161
215
|
if (!show) return;
|
@@ -232,6 +286,16 @@ function mainFocus() {
|
|
232
286
|
setTimeout(function() { $('#main').focus(); }, 10);
|
233
287
|
}
|
234
288
|
|
289
|
+
function navigationChange() {
|
290
|
+
// This works around the broken anchor navigation with the YARD template.
|
291
|
+
window.onpopstate = function() {
|
292
|
+
var hash = window.location.hash;
|
293
|
+
if (hash !== '' && $(hash)[0]) {
|
294
|
+
$(hash)[0].scrollIntoView();
|
295
|
+
}
|
296
|
+
};
|
297
|
+
}
|
298
|
+
|
235
299
|
$(document).ready(function() {
|
236
300
|
navResizer();
|
237
301
|
navExpander();
|
@@ -241,8 +305,10 @@ $(document).ready(function() {
|
|
241
305
|
searchFrameButtons();
|
242
306
|
linkSummaries();
|
243
307
|
summaryToggle();
|
308
|
+
constantSummaryToggle();
|
244
309
|
generateTOC();
|
245
310
|
mainFocus();
|
311
|
+
navigationChange();
|
246
312
|
});
|
247
313
|
|
248
314
|
})();
|