reqcord 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.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +628 -0
  3. metadata +45 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a786e42c21b820aeb729b9b401a4dc61fe61e6946e27d5f615186cbffe1b554c
4
+ data.tar.gz: b6fa31a65a90c88c20b51329b34cef327436890700b43fe07f43369056a18e3b
5
+ SHA512:
6
+ metadata.gz: 0d4bc1a375c768e8f025f555887c341a39eb980841f6f49eb7de5ca1f5f78a82dff51ad5b554d91b434da042d73d2abe446f159d41ad4e7a54e646f5b64f428d
7
+ data.tar.gz: 80b569646f903b92d778af3dd00f140817b8f308213074022b8b9bc050307bf0f83ed076cfc5a2f7598c5bc9b6cde43c3f5b08c540a116c79d4cac09f83103c4
data/README.md ADDED
@@ -0,0 +1,628 @@
1
+ # Reqcord
2
+
3
+ **Turn your Rails integration tests into living API documentation.**
4
+
5
+ Reqcord observes real HTTP requests and responses executed by your Rails test suite and converts them into static, readable API documentation.
6
+
7
+ Instead of maintaining API documentation separately from your tests, Reqcord uses the requests your application already executes as the source of truth.
8
+
9
+ ```text
10
+ Rails Routes
11
+ +
12
+ Minitest Integration Tests
13
+
14
+ Request Capture
15
+
16
+ Response Capture
17
+
18
+ Sanitization
19
+
20
+ Canonical Dataset
21
+
22
+ Markdown API Docs
23
+
24
+ cURL Examples
25
+ ```
26
+
27
+ ## Why Reqcord?
28
+
29
+ API documentation tends to drift away from the application it describes.
30
+
31
+ A request changes.
32
+
33
+ A header is added.
34
+
35
+ A validation rule changes.
36
+
37
+ A new `422` response appears.
38
+
39
+ The tests are updated, but the documentation is forgotten.
40
+
41
+ Reqcord takes a different approach:
42
+
43
+ > If your tests already know how to call your API, they already contain most of the information required to document it.
44
+
45
+ Reqcord captures that information and turns it into static API documentation.
46
+
47
+ No separate documentation DSL.
48
+
49
+ No duplicate request definitions.
50
+
51
+ No manually maintained cURL examples.
52
+
53
+ Your tests remain normal Rails tests.
54
+
55
+ ## Example
56
+
57
+ Given an existing Rails integration test:
58
+
59
+ ```ruby
60
+ test "creates customer" do
61
+ post "/api/v2/customers",
62
+ params: {
63
+ customer: {
64
+ name: "John Doe",
65
+ email: "john@example.com"
66
+ }
67
+ },
68
+ headers: {
69
+ "Authorization" => "Bearer test-token",
70
+ "X-Account-Id" => "42"
71
+ },
72
+ as: :json
73
+
74
+ assert_response :created
75
+ end
76
+ ```
77
+
78
+ Reqcord captures the request and response while the test executes.
79
+
80
+ It can generate documentation such as:
81
+
82
+ ````markdown
83
+ # Create Customer
84
+
85
+ `POST /api/v2/customers`
86
+
87
+ ## Headers
88
+
89
+ | Header | Value |
90
+ | --- | --- |
91
+ | Authorization | `Bearer {{token}}` |
92
+ | X-Account-Id | `{{account_id}}` |
93
+ | Content-Type | `application/json` |
94
+
95
+ ## Request Body
96
+
97
+ ```json
98
+ {
99
+ "customer": {
100
+ "name": "John Doe",
101
+ "email": "john@example.com"
102
+ }
103
+ }
104
+ ```
105
+
106
+ ## cURL
107
+
108
+ ```bash
109
+ curl --request POST \
110
+ --url "{{base_url}}/api/v2/customers" \
111
+ --header "Authorization: Bearer {{token}}" \
112
+ --header "X-Account-Id: {{account_id}}" \
113
+ --header "Content-Type: application/json" \
114
+ --data '{
115
+ "customer": {
116
+ "name": "John Doe",
117
+ "email": "john@example.com"
118
+ }
119
+ }'
120
+ ```
121
+
122
+ ## Responses
123
+
124
+ ### 201 Created
125
+
126
+ ```json
127
+ {
128
+ "id": 42,
129
+ "name": "John Doe",
130
+ "email": "john@example.com"
131
+ }
132
+ ```
133
+
134
+ ### 401 Unauthorized
135
+
136
+ ```json
137
+ {
138
+ "error": "Unauthorized"
139
+ }
140
+ ```
141
+
142
+ ### 422 Unprocessable Entity
143
+
144
+ ```json
145
+ {
146
+ "errors": {
147
+ "email": [
148
+ "has already been taken"
149
+ ]
150
+ }
151
+ }
152
+ ```
153
+ ````
154
+
155
+ ## Core Idea
156
+
157
+ Reqcord separates **capturing API behavior** from **rendering documentation**.
158
+
159
+ ```text
160
+ Rails Routes
161
+
162
+
163
+ Route Collector
164
+
165
+ Minitest ──────► Test Adapter
166
+
167
+
168
+ Reqcord Dataset
169
+
170
+ ┌─────────┴─────────┐
171
+ ▼ ▼
172
+ Markdown JSON
173
+
174
+
175
+ cURL
176
+ ```
177
+
178
+ The internal dataset is framework-independent and output-independent.
179
+
180
+ This allows Reqcord to support additional test frameworks and documentation formats without coupling them together.
181
+
182
+ ## Installation
183
+
184
+ Add Reqcord to the development and test groups:
185
+
186
+ ```ruby
187
+ group :development, :test do
188
+ gem "reqcord"
189
+ end
190
+ ```
191
+
192
+ Then run:
193
+
194
+ ```bash
195
+ bundle install
196
+ ```
197
+
198
+ Initialize Reqcord:
199
+
200
+ ```bash
201
+ bin/rails reqcord:init
202
+ ```
203
+
204
+ This creates:
205
+
206
+ ```text
207
+ reqcord.yml
208
+ docs/
209
+ └── api/
210
+ ```
211
+
212
+ ## Configuration
213
+
214
+ Reqcord reads its configuration from `reqcord.yml` in the project root.
215
+
216
+ ```yaml
217
+ version: 1
218
+
219
+ test:
220
+ framework: minitest
221
+
222
+ routes:
223
+ prefix: /api
224
+
225
+ output:
226
+ directory: docs/api
227
+
228
+ exporters:
229
+ - markdown
230
+
231
+ variables:
232
+ base_url: http://localhost:3000
233
+
234
+ sanitize:
235
+ headers:
236
+ Authorization: "Bearer {{token}}"
237
+ X-Account-Id: "{{account_id}}"
238
+ ```
239
+
240
+ Configuration precedence:
241
+
242
+ ```text
243
+ CLI / Environment
244
+
245
+ reqcord.yml
246
+
247
+ Reqcord defaults
248
+ ```
249
+
250
+ ## Generating Documentation
251
+
252
+ Generate documentation for the entire API:
253
+
254
+ ```bash
255
+ bin/rails reqcord:generate
256
+ ```
257
+
258
+ Generate documentation for a specific resource:
259
+
260
+ ```bash
261
+ bin/rails reqcord:generate RESOURCE=customers
262
+ ```
263
+
264
+ Multiple resources:
265
+
266
+ ```bash
267
+ bin/rails reqcord:generate RESOURCE=customers,surveys
268
+ ```
269
+
270
+ Filter by API version:
271
+
272
+ ```bash
273
+ bin/rails reqcord:generate VERSION=v2
274
+ ```
275
+
276
+ Combine filters:
277
+
278
+ ```bash
279
+ bin/rails reqcord:generate RESOURCE=customers VERSION=v2
280
+ ```
281
+
282
+ ## Generated Files
283
+
284
+ A typical output looks like:
285
+
286
+ ```text
287
+ docs/api/
288
+ ├── dataset.json
289
+ ├── README.md
290
+ ├── customers/
291
+ │ ├── index.md
292
+ │ ├── create.md
293
+ │ ├── show.md
294
+ │ ├── update.md
295
+ │ └── destroy.md
296
+ └── surveys/
297
+ ├── index.md
298
+ └── create.md
299
+ ```
300
+
301
+ `dataset.json` contains Reqcord's normalized representation of the captured API.
302
+
303
+ Markdown files are generated from that dataset.
304
+
305
+ ## Request Capture
306
+
307
+ Reqcord captures HTTP information from Rails integration tests.
308
+
309
+ The initial version supports:
310
+
311
+ * HTTP method
312
+ * Request path
313
+ * Path parameters
314
+ * Query parameters
315
+ * Request headers
316
+ * JSON request bodies
317
+ * Content type
318
+ * Response status
319
+ * Response headers
320
+ * JSON response bodies
321
+ * Test name and source
322
+ * Multiple request/response examples per endpoint
323
+
324
+ Supported HTTP methods:
325
+
326
+ ```text
327
+ GET
328
+ POST
329
+ PUT
330
+ PATCH
331
+ DELETE
332
+ ```
333
+
334
+ ## Multiple Responses
335
+
336
+ Reqcord does not assume that an endpoint has only one response.
337
+
338
+ For example:
339
+
340
+ ```ruby
341
+ test "creates customer" do
342
+ # ...
343
+ assert_response :created
344
+ end
345
+
346
+ test "requires authentication" do
347
+ # ...
348
+ assert_response :unauthorized
349
+ end
350
+
351
+ test "rejects duplicate email" do
352
+ # ...
353
+ assert_response :unprocessable_entity
354
+ end
355
+ ```
356
+
357
+ can produce:
358
+
359
+ ```text
360
+ POST /api/v2/customers
361
+
362
+ Responses
363
+ ├── 201 Created
364
+ ├── 401 Unauthorized
365
+ └── 422 Unprocessable Entity
366
+ ```
367
+
368
+ Multiple examples for the same status code are also preserved.
369
+
370
+ For example:
371
+
372
+ ```text
373
+ 422 Unprocessable Entity
374
+ ├── Email already exists
375
+ ├── Name is required
376
+ └── Invalid phone number
377
+ ```
378
+
379
+ Reqcord does not overwrite one `422` example with another.
380
+
381
+ ## Sanitization
382
+
383
+ Captured tests may contain credentials or other sensitive values.
384
+
385
+ Reqcord must never blindly write those values into generated documentation.
386
+
387
+ Sensitive headers can be replaced with variables:
388
+
389
+ ```yaml
390
+ sanitize:
391
+ headers:
392
+ Authorization: "Bearer {{token}}"
393
+ X-Api-Key: "{{api_key}}"
394
+ X-Account-Id: "{{account_id}}"
395
+ ```
396
+
397
+ A captured request such as:
398
+
399
+ ```text
400
+ Authorization: Bearer eyJhbGciOi...
401
+ ```
402
+
403
+ becomes:
404
+
405
+ ```text
406
+ Authorization: Bearer {{token}}
407
+ ```
408
+
409
+ Sensitive headers such as authorization credentials, cookies and API keys are treated specially by Reqcord.
410
+
411
+ Request and response body sanitization will follow the same principle.
412
+
413
+ ## Canonical Dataset
414
+
415
+ Reqcord does not directly convert Minitest tests into Markdown.
416
+
417
+ Instead:
418
+
419
+ ```text
420
+ Minitest
421
+
422
+ Test Adapter
423
+
424
+ Canonical Dataset
425
+
426
+ Exporter
427
+ ```
428
+
429
+ A simplified endpoint representation looks like:
430
+
431
+ ```json
432
+ {
433
+ "method": "POST",
434
+ "path": "/api/v2/customers",
435
+ "request_examples": [
436
+ {
437
+ "headers": {
438
+ "Authorization": "Bearer {{token}}"
439
+ },
440
+ "body": {
441
+ "customer": {
442
+ "name": "John Doe"
443
+ }
444
+ }
445
+ }
446
+ ],
447
+ "response_examples": [
448
+ {
449
+ "name": "Created",
450
+ "status": 201,
451
+ "body": {
452
+ "id": 42,
453
+ "name": "John Doe"
454
+ }
455
+ },
456
+ {
457
+ "name": "Unauthorized",
458
+ "status": 401,
459
+ "body": {
460
+ "error": "Unauthorized"
461
+ }
462
+ }
463
+ ]
464
+ }
465
+ ```
466
+
467
+ Every dataset contains a schema version so the internal format can evolve safely.
468
+
469
+ ```json
470
+ {
471
+ "schema_version": 1
472
+ }
473
+ ```
474
+
475
+ ## Architecture
476
+
477
+ ```text
478
+ Reqcord
479
+ ├── Configuration
480
+ ├── Dataset
481
+ │ ├── Resource
482
+ │ ├── Endpoint
483
+ │ ├── RequestExample
484
+ │ └── ResponseExample
485
+
486
+ ├── RouteCollector
487
+
488
+ ├── TestAdapters
489
+ │ └── Minitest
490
+
491
+ ├── Sanitizers
492
+ │ ├── Headers
493
+ │ ├── RequestBody
494
+ │ └── ResponseBody
495
+
496
+ ├── Renderers
497
+ │ └── Curl
498
+
499
+ └── Exporters
500
+ └── Markdown
501
+ ```
502
+
503
+ Test adapters are responsible only for converting test execution into Reqcord's canonical model.
504
+
505
+ Exporters know nothing about Minitest or Rails test internals.
506
+
507
+ ```text
508
+ Minitest ──┐
509
+
510
+ RSpec ─────┼──► Dataset ──► Markdown
511
+ │ ├─► OpenAPI
512
+ Other ─────┘ ├─► Postman
513
+ └─► ...
514
+ ```
515
+
516
+ ## v0.1 Scope
517
+
518
+ The first Reqcord release focuses on proving the capture pipeline.
519
+
520
+ ### Included
521
+
522
+ * Rails 8
523
+ * Minitest integration/request tests
524
+ * Rails route discovery
525
+ * `reqcord.yml`
526
+ * Request capture
527
+ * Response capture
528
+ * Multiple response scenarios
529
+ * Sensitive data sanitization
530
+ * Canonical `dataset.json`
531
+ * Markdown documentation
532
+ * Generated cURL requests
533
+ * Resource filtering
534
+ * API version filtering
535
+
536
+ ### Not included yet
537
+
538
+ * RSpec adapter
539
+ * OpenAPI generation
540
+ * Scalar integration
541
+ * Postman collections
542
+ * Hoppscotch collections
543
+ * Multipart requests
544
+ * Advanced schema inference
545
+ * CI documentation drift detection
546
+
547
+ These features belong to later releases rather than expanding the initial scope.
548
+
549
+ ## Roadmap
550
+
551
+ ### v0.2
552
+
553
+ OpenAPI 3.1 export and Scalar integration.
554
+
555
+ ```text
556
+ Reqcord Dataset
557
+
558
+ OpenAPI 3.1
559
+
560
+ Scalar
561
+ ```
562
+
563
+ This will allow a development application to expose documentation such as:
564
+
565
+ ```text
566
+ http://localhost:3000/api-docs
567
+ ```
568
+
569
+ ### v0.3
570
+
571
+ RSpec request spec adapter.
572
+
573
+ Both test frameworks will produce the exact same Reqcord dataset:
574
+
575
+ ```text
576
+ Minitest ─┐
577
+ ├──► Reqcord Dataset
578
+ RSpec ────┘
579
+ ```
580
+
581
+ ### Future
582
+
583
+ Potential exporters and integrations include:
584
+
585
+ * Postman
586
+ * Hoppscotch
587
+ * Bruno
588
+ * Insomnia
589
+ * `llms.txt`
590
+ * Static HTML documentation
591
+ * JSON Schema
592
+ * CI documentation drift detection
593
+
594
+ ## Design Principles
595
+
596
+ **Tests are the source of truth.**
597
+
598
+ Reqcord should observe existing tests instead of forcing developers to rewrite them using a documentation-specific DSL.
599
+
600
+ **Capture once, export anywhere.**
601
+
602
+ Test execution produces a framework-independent dataset. Exporters operate exclusively on that dataset.
603
+
604
+ **Generated documentation must be safe.**
605
+
606
+ Credentials and sensitive data must not leak into generated files.
607
+
608
+ **Generated documentation must be useful without a server.**
609
+
610
+ Markdown and cURL output should remain readable directly from GitHub or a local checkout.
611
+
612
+ **Adapters stay isolated.**
613
+
614
+ Minitest, RSpec, Markdown, OpenAPI and other integrations should not depend directly on each other.
615
+
616
+ ## Status
617
+
618
+ Reqcord is currently in early development.
619
+
620
+ The initial goal is intentionally narrow:
621
+
622
+ > Capture real Rails API requests and responses from Minitest and generate accurate, sanitized Markdown documentation with executable cURL examples.
623
+
624
+ Once that pipeline is reliable, additional adapters and exporters can be built on top of the same dataset.
625
+
626
+ ## License
627
+
628
+ Reqcord is available as open source under the terms of the MIT License.
metadata ADDED
@@ -0,0 +1,45 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: reqcord
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Ahmet Saridogan
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies: []
12
+ description: |
13
+ Reqcord captures HTTP requests and responses from Rails integration tests
14
+ and generates static API documentation with executable cURL examples.
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - README.md
20
+ homepage: https://github.com/ahmetsaridogan/reqcord
21
+ licenses:
22
+ - MIT
23
+ metadata:
24
+ homepage_uri: https://github.com/ahmetsaridogan/reqcord
25
+ source_code_uri: https://github.com/ahmetsaridogan/reqcord
26
+ changelog_uri: https://github.com/ahmetsaridogan/reqcord/blob/main/CHANGELOG.md
27
+ rubygems_mfa_required: 'true'
28
+ rdoc_options: []
29
+ require_paths:
30
+ - lib
31
+ required_ruby_version: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: '3.2'
36
+ required_rubygems_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ requirements: []
42
+ rubygems_version: 4.0.3
43
+ specification_version: 4
44
+ summary: Generate living API documentation from Rails integration tests
45
+ test_files: []