api_adaptor 0.1.0 → 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/.rubocop.yml +3 -3
- data/.yardopts +10 -0
- data/CHANGELOG.md +29 -1
- data/CLAUDE.md +423 -0
- data/Gemfile.lock +12 -3
- data/README.md +85 -0
- data/Rakefile +7 -1
- data/lib/api_adaptor/base.rb +137 -0
- data/lib/api_adaptor/exceptions.rb +67 -4
- data/lib/api_adaptor/headers.rb +32 -0
- data/lib/api_adaptor/json_client.rb +172 -3
- data/lib/api_adaptor/list_response.rb +63 -21
- data/lib/api_adaptor/null_logger.rb +53 -39
- data/lib/api_adaptor/response.rb +107 -10
- data/lib/api_adaptor/variables.rb +37 -0
- data/lib/api_adaptor/version.rb +1 -1
- data/lib/api_adaptor.rb +31 -1
- metadata +45 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a7f99a36581d23c2d20acb77209e83094d0376abfebbe485961c716ad5a2996e
|
|
4
|
+
data.tar.gz: d247399af57052605021e37293944d92da841351f958d45ea7f00153b1a075c7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fe8f8c29cfad7facd7b38ec9d7d1ca7076fa603a881ee19cff99d937f6911857c8b5b288ba1e2d49c7c71ccfc6ad8dd5e206bc28133548711cc7b4b7242ac6d8
|
|
7
|
+
data.tar.gz: fc13ade3b00830ee758141678ed28928d8fb4111bb241b25ac2e281064056b4fb9835ccef407779e9465a2f74bd67b68133d552fa82f001d940cd7a34814687c
|
data/.rubocop.yml
CHANGED
|
@@ -3,6 +3,9 @@ AllCops:
|
|
|
3
3
|
NewCops: disable
|
|
4
4
|
SuggestExtensions: false
|
|
5
5
|
|
|
6
|
+
plugins:
|
|
7
|
+
- rubocop-yard
|
|
8
|
+
|
|
6
9
|
Style/StringLiterals:
|
|
7
10
|
Enabled: true
|
|
8
11
|
EnforcedStyle: double_quotes
|
|
@@ -16,6 +19,3 @@ Layout/LineLength:
|
|
|
16
19
|
|
|
17
20
|
Metrics:
|
|
18
21
|
Enabled: false
|
|
19
|
-
|
|
20
|
-
Style/Documentation:
|
|
21
|
-
Enabled: false
|
data/.yardopts
ADDED
data/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,32 @@
|
|
|
1
|
-
## [
|
|
1
|
+
## [1.0.0] - 2026-02-15
|
|
2
|
+
|
|
3
|
+
### Added
|
|
4
|
+
- YARD documentation for all public APIs (100% coverage)
|
|
5
|
+
- YARD documentation deployment to GitHub Pages
|
|
6
|
+
- CLAUDE.md development guide for AI assistants and contributors
|
|
7
|
+
- rubocop-yard plugin for documentation linting
|
|
8
|
+
- API Documentation section in README with links to hosted docs
|
|
9
|
+
- Development section in README with testing, coverage, and documentation commands
|
|
10
|
+
- Troubleshooting section in README for common issues
|
|
11
|
+
- Badges in README for CI status, gem version, and documentation
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
- README enhanced with wikidata_adaptor best practices
|
|
15
|
+
- Default Rake task now includes YARD documentation generation
|
|
16
|
+
- RuboCop now enforces documentation standards via rubocop-yard
|
|
17
|
+
- GitHub Actions updated to use consistent SHA pinning across all workflows
|
|
18
|
+
- All development dependencies updated to latest compatible versions
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
- Standardized GitHub Actions versions across all workflows
|
|
22
|
+
- Updated ruby/setup-ruby to v1.288.0 in all workflows
|
|
23
|
+
- Updated rubygems/release-gem to v1.1.2 in release workflow
|
|
24
|
+
- Updated actions/configure-pages to v5.0.0 in pages workflow
|
|
25
|
+
- Updated actions/upload-pages-artifact to v4.0.0 in pages workflow
|
|
26
|
+
- Updated actions/deploy-pages to v4.0.5 in pages workflow
|
|
27
|
+
- Fixed invalid date format in CHANGELOG (2025-31-01 → 2025-01-31)
|
|
28
|
+
|
|
29
|
+
## [0.1.0] - 2025-01-31
|
|
2
30
|
|
|
3
31
|
- Improvements to 307, 308 redirect behaviour
|
|
4
32
|
- Greater configuration over redirect behaviour
|
data/CLAUDE.md
ADDED
|
@@ -0,0 +1,423 @@
|
|
|
1
|
+
# CLAUDE.md - Developer Guide for api_adaptor
|
|
2
|
+
|
|
3
|
+
This guide is for AI assistants and human contributors working on api_adaptor. It provides context about the project's architecture, conventions, and development workflow.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
**api_adaptor** is a Ruby gem that provides a basic HTTP client adaptor for JSON APIs. It handles common patterns like request/response parsing, redirects, error handling, and pagination, allowing developers to quickly build API clients without repetitive boilerplate.
|
|
8
|
+
|
|
9
|
+
### Key Features
|
|
10
|
+
|
|
11
|
+
- JSON request/response handling with automatic parsing
|
|
12
|
+
- Configurable redirect handling (cross-origin, non-GET requests)
|
|
13
|
+
- Bearer token and basic authentication support
|
|
14
|
+
- Pagination support via `ListResponse`
|
|
15
|
+
- Cache-Control header parsing
|
|
16
|
+
- Comprehensive exception hierarchy for HTTP errors
|
|
17
|
+
- Thread-safe connection pooling via rest-client
|
|
18
|
+
|
|
19
|
+
### Architecture
|
|
20
|
+
|
|
21
|
+
- **JSONClient**: Core HTTP client with redirect handling and authentication
|
|
22
|
+
- **Base**: Abstract base class for building API-specific clients
|
|
23
|
+
- **Response/ListResponse**: Wrapper classes for parsed responses
|
|
24
|
+
- **Headers**: Manages request headers including User-Agent
|
|
25
|
+
- **Variables**: Environment variable configuration for app metadata
|
|
26
|
+
- **Exceptions**: HTTP error hierarchy
|
|
27
|
+
|
|
28
|
+
## Commands
|
|
29
|
+
|
|
30
|
+
### Development
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
bundle install # Install dependencies
|
|
34
|
+
bundle exec rspec # Run tests
|
|
35
|
+
bundle exec rubocop # Run linter
|
|
36
|
+
bundle exec rake # Run tests + linter + generate docs (default)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Documentation
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
bundle exec yard # Generate YARD documentation to doc/
|
|
43
|
+
bundle exec yard server # Preview docs at http://localhost:8808
|
|
44
|
+
bundle exec yard stats # View documentation coverage
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Coverage
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
bundle exec rspec # Generates coverage report
|
|
51
|
+
open coverage/index.html # View coverage report
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Release
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
# Manual release (not recommended - use GitHub Actions)
|
|
58
|
+
bundle exec rake release # Build gem, create git tag, push to RubyGems
|
|
59
|
+
|
|
60
|
+
# Automated release (recommended)
|
|
61
|
+
git tag v1.0.0 # Create version tag
|
|
62
|
+
git push origin v1.0.0 # Push tag to trigger release workflow
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Project Structure
|
|
66
|
+
|
|
67
|
+
### Core Files
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
lib/
|
|
71
|
+
├── api_adaptor.rb # Main entry point, loads all components
|
|
72
|
+
├── api_adaptor/
|
|
73
|
+
│ ├── version.rb # VERSION constant
|
|
74
|
+
│ ├── json_client.rb # HTTP client with JSON parsing
|
|
75
|
+
│ ├── base.rb # Base class for API clients
|
|
76
|
+
│ ├── response.rb # Response wrapper with cache control
|
|
77
|
+
│ ├── list_response.rb # Paginated response wrapper
|
|
78
|
+
│ ├── exceptions.rb # HTTP exception hierarchy
|
|
79
|
+
│ ├── headers.rb # Header management
|
|
80
|
+
│ └── variables.rb # Environment variable config
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Configuration
|
|
84
|
+
|
|
85
|
+
- `api_adaptor.gemspec` - Gem specification and dependencies
|
|
86
|
+
- `Rakefile` - Rake tasks (test, lint, docs)
|
|
87
|
+
- `.rubocop.yml` - RuboCop linting configuration
|
|
88
|
+
- `.yardopts` - YARD documentation configuration
|
|
89
|
+
- `.rspec` - RSpec test configuration
|
|
90
|
+
|
|
91
|
+
### Tests
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
spec/
|
|
95
|
+
├── spec_helper.rb # Test configuration with SimpleCov
|
|
96
|
+
├── api_adaptor/
|
|
97
|
+
│ ├── base_spec.rb # Base class tests
|
|
98
|
+
│ ├── exceptions_spec.rb # Exception handling tests
|
|
99
|
+
│ ├── headers_spec.rb # Header tests
|
|
100
|
+
│ ├── json_client_spec.rb # Core client tests
|
|
101
|
+
│ ├── list_response_spec.rb # Pagination tests
|
|
102
|
+
│ ├── response_spec.rb # Response wrapper tests
|
|
103
|
+
│ └── variables_spec.rb # Environment variable tests
|
|
104
|
+
└── fixtures/ # Test fixtures including foo.json
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### CI/CD
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
.github/workflows/
|
|
111
|
+
├── ci.yml # Main CI (RSpec tests)
|
|
112
|
+
├── quality-checks.yml # RuboCop linting
|
|
113
|
+
├── release.yml # Automated gem release
|
|
114
|
+
├── pages.yml # Deploy fixtures to GitHub Pages
|
|
115
|
+
├── docs.yml # Deploy YARD docs to GitHub Pages
|
|
116
|
+
└── codeql.yml # Security scanning
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Testing Conventions
|
|
120
|
+
|
|
121
|
+
### Test Structure
|
|
122
|
+
|
|
123
|
+
- Use RSpec with descriptive contexts
|
|
124
|
+
- Mock HTTP requests with WebMock
|
|
125
|
+
- Use Timecop for time-sensitive tests
|
|
126
|
+
- Aim for ≥80% line coverage, ≥75% branch coverage
|
|
127
|
+
|
|
128
|
+
### Test Patterns
|
|
129
|
+
|
|
130
|
+
```ruby
|
|
131
|
+
# Good: Descriptive context and it blocks
|
|
132
|
+
describe JSONClient do
|
|
133
|
+
describe "#get_json" do
|
|
134
|
+
context "when request succeeds" do
|
|
135
|
+
it "returns parsed JSON response" do
|
|
136
|
+
# ...
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
context "when request fails" do
|
|
141
|
+
it "raises appropriate exception" do
|
|
142
|
+
# ...
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
# Good: Use WebMock for HTTP mocking
|
|
149
|
+
stub_request(:get, "https://example.com/api")
|
|
150
|
+
.to_return(status: 200, body: '{"key": "value"}')
|
|
151
|
+
|
|
152
|
+
# Good: Use Timecop for time tests
|
|
153
|
+
Timecop.freeze(Time.utc(2024, 1, 1, 12, 0, 0)) do
|
|
154
|
+
# ...
|
|
155
|
+
end
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Running Tests
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
bundle exec rspec # Run all tests
|
|
162
|
+
bundle exec rspec spec/api_adaptor/json_client_spec.rb # Run specific file
|
|
163
|
+
bundle exec rspec spec/api_adaptor/json_client_spec.rb:42 # Run specific line
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Environment Variables
|
|
167
|
+
|
|
168
|
+
The gem reads app metadata from environment variables for User-Agent headers:
|
|
169
|
+
|
|
170
|
+
- `APP_NAME` - Application name (default: "Ruby ApiAdaptor App")
|
|
171
|
+
- `APP_VERSION` - Application version (default: "Version not stated")
|
|
172
|
+
- `APP_CONTACT` - Contact email/URL for API providers
|
|
173
|
+
|
|
174
|
+
### Example .env
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
APP_NAME=MyApiClient
|
|
178
|
+
APP_VERSION=2.1.0
|
|
179
|
+
APP_CONTACT=dev@example.com
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
These are accessed via `ApiAdaptor::Variables` methods.
|
|
183
|
+
|
|
184
|
+
## Git Standards
|
|
185
|
+
|
|
186
|
+
Never commit to main branch,
|
|
187
|
+
Always create a new branch with a sensible descriptive name and expect a Pull Request process.
|
|
188
|
+
|
|
189
|
+
You'll need to provide a good PR description that sums up any collected change.
|
|
190
|
+
|
|
191
|
+
## Commit Standards
|
|
192
|
+
|
|
193
|
+
Follows [GDS Git conventions](https://gds-way.digital.cabinet-office.gov.uk/standards/source-code/working-with-git.html#commits), informed by [chris.beams.io/posts/git-commit](https://chris.beams.io/posts/git-commit), [thoughtbot](https://thoughtbot.com/blog/5-useful-tips-for-a-better-commit-message), [mislav.net](https://mislav.net/2014/02/hidden-documentation/), and [Joel Chippindale's "Telling Stories Through Your Commits"](https://blog.mocoso.co.uk/posts/talks/telling-stories-through-your-commits/).
|
|
194
|
+
|
|
195
|
+
### Formatting
|
|
196
|
+
|
|
197
|
+
- **[Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/)** — subject line format: `<type>[optional scope]: <description>`
|
|
198
|
+
- **Types**: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`
|
|
199
|
+
- **Scope** — optional parenthetical context, e.g. `feat(labels):` or `fix(integration):`
|
|
200
|
+
- **Breaking changes** — indicated with `!` before the colon, e.g. `feat!:`, or a `BREAKING CHANGE:` footer
|
|
201
|
+
- **Subject line** — max 50 characters, no trailing period, imperative mood ("Add feature" not "Added feature")
|
|
202
|
+
- **Body** — separated from subject by a blank line, wrapped at 72 characters
|
|
203
|
+
- **Links supplement, not replace** — issue/PR links may go stale, so the message must stand on its own
|
|
204
|
+
|
|
205
|
+
### Content
|
|
206
|
+
|
|
207
|
+
- **Answer three questions**: Why is this change necessary? How does it address the issue? What side effects does it have?
|
|
208
|
+
- **Explain the "why"** — the code shows _how_; the commit message must capture _why_. Rationale and context are hard to reconstruct later
|
|
209
|
+
- **Note alternatives considered** — if you chose approach A over B, say so and why
|
|
210
|
+
|
|
211
|
+
### Structure
|
|
212
|
+
|
|
213
|
+
- **Atomic commits** — each commit is a self-contained, logical unit of work; avoid needing "and" in your subject line
|
|
214
|
+
- **Tell a story** — commits should be logically ordered so the history reads as a coherent narrative, not a jumbled log
|
|
215
|
+
- **Clean up before sharing** — revise commit history on feature branches before opening a PR
|
|
216
|
+
|
|
217
|
+
## Development Workflow
|
|
218
|
+
|
|
219
|
+
### TDD Approach (Recommended)
|
|
220
|
+
|
|
221
|
+
1. **Write failing test** - Define expected behavior
|
|
222
|
+
2. **Implement feature** - Write minimal code to pass test
|
|
223
|
+
3. **Refactor** - Improve code while keeping tests green
|
|
224
|
+
4. **Document** - Add YARD comments to public APIs
|
|
225
|
+
5. **Lint** - Run `bundle exec rubocop` and fix issues
|
|
226
|
+
6. **Commit** - Use conventional commit message
|
|
227
|
+
|
|
228
|
+
### Feature Development Cycle
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
# 1. Create feature branch
|
|
232
|
+
git checkout -b feature/add-retry-logic
|
|
233
|
+
|
|
234
|
+
# 2. Write test
|
|
235
|
+
# Edit spec/api_adaptor/json_client_spec.rb
|
|
236
|
+
|
|
237
|
+
# 3. Run test (should fail)
|
|
238
|
+
bundle exec rspec spec/api_adaptor/json_client_spec.rb
|
|
239
|
+
|
|
240
|
+
# 4. Implement feature
|
|
241
|
+
# Edit lib/api_adaptor/json_client.rb
|
|
242
|
+
|
|
243
|
+
# 5. Run test (should pass)
|
|
244
|
+
bundle exec rspec spec/api_adaptor/json_client_spec.rb
|
|
245
|
+
|
|
246
|
+
# 6. Run full test suite
|
|
247
|
+
bundle exec rake
|
|
248
|
+
|
|
249
|
+
# 7. Commit
|
|
250
|
+
git add .
|
|
251
|
+
git commit -m "feat(client): add retry logic for transient failures"
|
|
252
|
+
|
|
253
|
+
# 8. Push and create PR
|
|
254
|
+
git push origin feature/add-retry-logic
|
|
255
|
+
gh pr create
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### Code Review Checklist
|
|
259
|
+
|
|
260
|
+
- [ ] Tests pass (`bundle exec rspec`)
|
|
261
|
+
- [ ] Linter passes (`bundle exec rubocop`)
|
|
262
|
+
- [ ] Coverage maintained (≥80% line, ≥75% branch)
|
|
263
|
+
- [ ] YARD documentation added for public APIs
|
|
264
|
+
- [ ] CHANGELOG.md updated (if applicable)
|
|
265
|
+
- [ ] Conventional commit message used
|
|
266
|
+
|
|
267
|
+
## Release Process
|
|
268
|
+
|
|
269
|
+
### Version Numbering
|
|
270
|
+
|
|
271
|
+
Follow [Semantic Versioning](https://semver.org/):
|
|
272
|
+
|
|
273
|
+
- **MAJOR**: Breaking API changes (1.0.0 → 2.0.0)
|
|
274
|
+
- **MINOR**: New features, backward-compatible (1.0.0 → 1.1.0)
|
|
275
|
+
- **PATCH**: Bug fixes, backward-compatible (1.0.0 → 1.0.1)
|
|
276
|
+
|
|
277
|
+
### Release Checklist
|
|
278
|
+
|
|
279
|
+
1. **Update version** - Edit `lib/api_adaptor/version.rb`
|
|
280
|
+
2. **Update CHANGELOG** - Add entry with date in `CHANGELOG.md`
|
|
281
|
+
3. **Run full test suite** - `bundle exec rake` (includes tests, lint, docs)
|
|
282
|
+
4. **Commit changes** - `chore(release): prepare v1.0.0`
|
|
283
|
+
5. **Create git tag** - `git tag v1.0.0`
|
|
284
|
+
6. **Push tag** - `git push origin v1.0.0`
|
|
285
|
+
7. **GitHub Actions triggers** - Release workflow builds and publishes gem to RubyGems
|
|
286
|
+
8. **Verify release** - Check https://rubygems.org/gems/api_adaptor
|
|
287
|
+
|
|
288
|
+
### Automated Release
|
|
289
|
+
|
|
290
|
+
The `.github/workflows/release.yml` workflow handles:
|
|
291
|
+
|
|
292
|
+
- Building the gem
|
|
293
|
+
- Running tests
|
|
294
|
+
- Publishing to RubyGems (using `RUBYGEMS_API_KEY` secret)
|
|
295
|
+
- Creating GitHub release
|
|
296
|
+
|
|
297
|
+
## Documentation Standards
|
|
298
|
+
|
|
299
|
+
### YARD Comments
|
|
300
|
+
|
|
301
|
+
All public APIs must have YARD documentation:
|
|
302
|
+
|
|
303
|
+
```ruby
|
|
304
|
+
# Initializes a new JSON client
|
|
305
|
+
#
|
|
306
|
+
# @param options [Hash] Configuration options
|
|
307
|
+
# @option options [String] :bearer_token Bearer token for authentication
|
|
308
|
+
# @option options [Hash] :basic_auth Basic auth credentials (:user, :password)
|
|
309
|
+
# @option options [Integer] :timeout Request timeout in seconds (default: 4)
|
|
310
|
+
# @option options [Integer] :max_redirects Maximum redirects to follow (default: 3)
|
|
311
|
+
# @option options [Boolean] :allow_cross_origin_redirects Allow cross-origin redirects (default: true)
|
|
312
|
+
# @option options [Logger] :logger Custom logger instance
|
|
313
|
+
#
|
|
314
|
+
# @return [JSONClient] A new instance of JSONClient
|
|
315
|
+
#
|
|
316
|
+
# @example Basic usage
|
|
317
|
+
# client = JSONClient.new(bearer_token: "abc123")
|
|
318
|
+
#
|
|
319
|
+
# @example With custom timeout
|
|
320
|
+
# client = JSONClient.new(timeout: 10)
|
|
321
|
+
def initialize(options = {})
|
|
322
|
+
# ...
|
|
323
|
+
end
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
### Documentation Commands
|
|
327
|
+
|
|
328
|
+
```bash
|
|
329
|
+
bundle exec yard stats --list-undoc # Find undocumented methods
|
|
330
|
+
bundle exec yard server # Preview docs locally
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
## Code Quality Standards
|
|
334
|
+
|
|
335
|
+
### Coverage Targets
|
|
336
|
+
|
|
337
|
+
- **Line Coverage**: ≥80% (current: 92.3%)
|
|
338
|
+
- **Branch Coverage**: ≥75% (current: 81.65%)
|
|
339
|
+
|
|
340
|
+
### RuboCop Configuration
|
|
341
|
+
|
|
342
|
+
- Follows standard Ruby style guide
|
|
343
|
+
- Custom cops enabled: `rubocop-yard` for documentation enforcement
|
|
344
|
+
- Configuration in `.rubocop.yml`
|
|
345
|
+
|
|
346
|
+
### Security
|
|
347
|
+
|
|
348
|
+
- Input validation at API boundaries
|
|
349
|
+
- Safe redirect handling with cross-origin protection
|
|
350
|
+
- No credential logging
|
|
351
|
+
- CodeQL security scanning enabled
|
|
352
|
+
|
|
353
|
+
## Common Tasks
|
|
354
|
+
|
|
355
|
+
### Adding a New Exception
|
|
356
|
+
|
|
357
|
+
1. Define exception in `lib/api_adaptor/exceptions.rb`
|
|
358
|
+
2. Add YARD documentation
|
|
359
|
+
3. Add test in `spec/api_adaptor/exceptions_spec.rb`
|
|
360
|
+
4. Update `json_client.rb` to raise exception where appropriate
|
|
361
|
+
|
|
362
|
+
### Adding a New Configuration Option
|
|
363
|
+
|
|
364
|
+
1. Add parameter to `JSONClient#initialize`
|
|
365
|
+
2. Document with YARD `@option` tag
|
|
366
|
+
3. Add instance variable and accessor
|
|
367
|
+
4. Add tests for new behavior
|
|
368
|
+
5. Update README with example
|
|
369
|
+
|
|
370
|
+
### Debugging HTTP Requests
|
|
371
|
+
|
|
372
|
+
```ruby
|
|
373
|
+
# Enable request/response logging
|
|
374
|
+
client = JSONClient.new(logger: Logger.new($stdout))
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
## Troubleshooting
|
|
378
|
+
|
|
379
|
+
### Tests Failing
|
|
380
|
+
|
|
381
|
+
```bash
|
|
382
|
+
# Run specific test
|
|
383
|
+
bundle exec rspec spec/api_adaptor/json_client_spec.rb:42
|
|
384
|
+
|
|
385
|
+
# Run with verbose output
|
|
386
|
+
bundle exec rspec --format documentation
|
|
387
|
+
|
|
388
|
+
# Check coverage
|
|
389
|
+
open coverage/index.html
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
### RuboCop Errors
|
|
393
|
+
|
|
394
|
+
```bash
|
|
395
|
+
# Auto-fix safe violations
|
|
396
|
+
bundle exec rubocop --auto-correct
|
|
397
|
+
|
|
398
|
+
# Fix all violations (less safe)
|
|
399
|
+
bundle exec rubocop --auto-correct-all
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
### YARD Documentation Issues
|
|
403
|
+
|
|
404
|
+
```bash
|
|
405
|
+
# Check for undocumented methods
|
|
406
|
+
bundle exec yard stats --list-undoc
|
|
407
|
+
|
|
408
|
+
# Validate YARD syntax
|
|
409
|
+
bundle exec yard --no-output
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
## Additional Resources
|
|
413
|
+
|
|
414
|
+
- **RubyGems**: https://rubygems.org/gems/api_adaptor
|
|
415
|
+
- **GitHub**: https://github.com/huwd/api_adaptor
|
|
416
|
+
- **YARD Docs**: https://huwd.github.io/api_adaptor/
|
|
417
|
+
- **Issues**: https://github.com/huwd/api_adaptor/issues
|
|
418
|
+
|
|
419
|
+
## Contact
|
|
420
|
+
|
|
421
|
+
- **Maintainer**: Huw Diprose
|
|
422
|
+
- **Email**: mail@huwdiprose.co.uk
|
|
423
|
+
- **License**: MIT
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
api_adaptor (
|
|
4
|
+
api_adaptor (1.0.0)
|
|
5
5
|
addressable (~> 2.8)
|
|
6
6
|
base64 (~> 0.3)
|
|
7
7
|
bigdecimal (>= 3.3, < 5.0)
|
|
@@ -27,7 +27,7 @@ GEM
|
|
|
27
27
|
http-accept (1.7.0)
|
|
28
28
|
http-cookie (1.0.5)
|
|
29
29
|
domain_name (~> 0.5)
|
|
30
|
-
json (2.18.
|
|
30
|
+
json (2.18.1)
|
|
31
31
|
language_server-protocol (3.17.0.5)
|
|
32
32
|
link_header (0.0.8)
|
|
33
33
|
lint_roller (1.1.0)
|
|
@@ -45,6 +45,7 @@ GEM
|
|
|
45
45
|
racc (1.8.1)
|
|
46
46
|
rainbow (3.1.1)
|
|
47
47
|
rake (13.3.1)
|
|
48
|
+
redcarpet (3.6.1)
|
|
48
49
|
regexp_parser (2.11.3)
|
|
49
50
|
rest-client (2.1.0)
|
|
50
51
|
http-accept (>= 1.7.0, < 2.0)
|
|
@@ -65,7 +66,7 @@ GEM
|
|
|
65
66
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
66
67
|
rspec-support (~> 3.13.0)
|
|
67
68
|
rspec-support (3.13.6)
|
|
68
|
-
rubocop (1.84.
|
|
69
|
+
rubocop (1.84.2)
|
|
69
70
|
json (~> 2.3)
|
|
70
71
|
language_server-protocol (~> 3.17.0.2)
|
|
71
72
|
lint_roller (~> 1.1.0)
|
|
@@ -79,6 +80,10 @@ GEM
|
|
|
79
80
|
rubocop-ast (1.49.0)
|
|
80
81
|
parser (>= 3.3.7.2)
|
|
81
82
|
prism (~> 1.7)
|
|
83
|
+
rubocop-yard (1.1.0)
|
|
84
|
+
lint_roller
|
|
85
|
+
rubocop (~> 1.72)
|
|
86
|
+
yard
|
|
82
87
|
ruby-progressbar (1.13.0)
|
|
83
88
|
simplecov (0.22.0)
|
|
84
89
|
docile (~> 1.1)
|
|
@@ -94,6 +99,7 @@ GEM
|
|
|
94
99
|
addressable (>= 2.8.0)
|
|
95
100
|
crack (>= 0.3.2)
|
|
96
101
|
hashdiff (>= 0.4.0, < 2.0.0)
|
|
102
|
+
yard (0.9.38)
|
|
97
103
|
|
|
98
104
|
PLATFORMS
|
|
99
105
|
x86_64-linux
|
|
@@ -101,11 +107,14 @@ PLATFORMS
|
|
|
101
107
|
DEPENDENCIES
|
|
102
108
|
api_adaptor!
|
|
103
109
|
rake (~> 13.0)
|
|
110
|
+
redcarpet (~> 3.6)
|
|
104
111
|
rspec (~> 3.0)
|
|
105
112
|
rubocop (~> 1.21)
|
|
113
|
+
rubocop-yard
|
|
106
114
|
simplecov (~> 0.22)
|
|
107
115
|
timecop (~> 0.9)
|
|
108
116
|
webmock (~> 3.18)
|
|
117
|
+
yard (~> 0.9)
|
|
109
118
|
|
|
110
119
|
BUNDLED WITH
|
|
111
120
|
2.4.13
|
data/README.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# ApiAdaptor
|
|
2
2
|
|
|
3
|
+
[](https://github.com/huwd/api_adaptor/actions/workflows/quality-checks.yml)
|
|
4
|
+
[](https://badge.fury.io/rb/api_adaptor)
|
|
5
|
+
[](https://huwd.github.io/api_adaptor/)
|
|
6
|
+
|
|
3
7
|
A basic adaptor to send HTTP requests and parse the responses.
|
|
4
8
|
Intended to bootstrap the quick writing of Adaptors for specific APIs, without having to write the same old JSON request and processing time and time again.
|
|
5
9
|
|
|
@@ -17,6 +21,17 @@ If bundler is not being used to manage dependencies, install the gem by executin
|
|
|
17
21
|
gem install api_adaptor
|
|
18
22
|
```
|
|
19
23
|
|
|
24
|
+
## API Documentation
|
|
25
|
+
|
|
26
|
+
Full API documentation is available at [https://huwd.github.io/api_adaptor/](https://huwd.github.io/api_adaptor/)
|
|
27
|
+
|
|
28
|
+
Generate documentation locally:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
bundle exec yard # Generate docs to doc/
|
|
32
|
+
bundle exec yard server # Preview at http://localhost:8808
|
|
33
|
+
```
|
|
34
|
+
|
|
20
35
|
## Releasing
|
|
21
36
|
|
|
22
37
|
Publishing is handled by GitHub Actions when you push a version tag.
|
|
@@ -196,6 +211,76 @@ User agent would read
|
|
|
196
211
|
test_app/1.0.0 (contact@example.com)
|
|
197
212
|
```
|
|
198
213
|
|
|
214
|
+
## Development
|
|
215
|
+
|
|
216
|
+
After checking out the repo, run `bundle install` to install dependencies.
|
|
217
|
+
|
|
218
|
+
### Running Tests
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
bundle exec rspec # Run tests only
|
|
222
|
+
bundle exec rubocop # Run linter only
|
|
223
|
+
bundle exec rake # Run tests, linter, and build docs
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### Code Coverage
|
|
227
|
+
|
|
228
|
+
SimpleCov tracks test coverage. View the report at `coverage/index.html` after running tests.
|
|
229
|
+
|
|
230
|
+
Current coverage: 92.3% line, 81.65% branch
|
|
231
|
+
|
|
232
|
+
### Documentation
|
|
233
|
+
|
|
234
|
+
Generate YARD documentation:
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
bundle exec yard # Generate docs to doc/
|
|
238
|
+
bundle exec yard server # Preview at http://localhost:8808
|
|
239
|
+
bundle exec yard stats # View documentation coverage
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Quality Standards
|
|
243
|
+
|
|
244
|
+
- **Tests:** RSpec with WebMock for HTTP mocking
|
|
245
|
+
- **Linting:** RuboCop with rubocop-yard for documentation
|
|
246
|
+
- **Coverage:** SimpleCov (minimum 80% line, 75% branch)
|
|
247
|
+
- **Documentation:** YARD for all public APIs
|
|
248
|
+
|
|
249
|
+
## Troubleshooting
|
|
250
|
+
|
|
251
|
+
### Redirects Not Following
|
|
252
|
+
|
|
253
|
+
By default, only GET/HEAD requests follow redirects. For POST/PUT/PATCH/DELETE:
|
|
254
|
+
|
|
255
|
+
```ruby
|
|
256
|
+
client = MyApi.new("https://example.com", follow_non_get_redirects: true)
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### Timeout Errors
|
|
260
|
+
|
|
261
|
+
Default timeout is 4 seconds. Configure longer timeouts:
|
|
262
|
+
|
|
263
|
+
```ruby
|
|
264
|
+
client = MyApi.new("https://example.com", timeout: 10)
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### Cross-Origin Redirect Security
|
|
268
|
+
|
|
269
|
+
By default, auth headers are stripped on cross-origin redirects. To allow (use with caution):
|
|
270
|
+
|
|
271
|
+
```ruby
|
|
272
|
+
client = MyApi.new(
|
|
273
|
+
"https://example.com",
|
|
274
|
+
forward_auth_on_cross_origin_redirects: true # Security risk!
|
|
275
|
+
)
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
Or disable cross-origin redirects entirely:
|
|
279
|
+
|
|
280
|
+
```ruby
|
|
281
|
+
client = MyApi.new("https://example.com", allow_cross_origin_redirects: false)
|
|
282
|
+
```
|
|
283
|
+
|
|
199
284
|
## Contributing
|
|
200
285
|
|
|
201
286
|
Bug reports and pull requests are welcome on GitHub at <https://github.com/huwd/api_adaptor>. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/huwd/api_adaptor/blob/main/CODE_OF_CONDUCT.md).
|
data/Rakefile
CHANGED