reqcord 0.1.1 → 0.1.2
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/CHANGELOG.md +13 -0
- data/Gemfile +5 -0
- data/README.md +13 -0
- data/gemfiles/rails_7.1.gemfile +13 -0
- data/gemfiles/rails_7.2.gemfile +13 -0
- data/gemfiles/rails_8.0.gemfile +13 -0
- data/gemfiles/rails_8.1.gemfile +13 -0
- data/lib/reqcord/version.rb +1 -1
- data/reqcord.gemspec +18 -4
- metadata +65 -217
- data/.gitignore +0 -8
- data/Gemfile.lock +0 -171
- data/examples/complex-spec-app/.rspec +0 -1
- data/examples/complex-spec-app/README.md +0 -21
- data/examples/complex-spec-app/app.rb +0 -363
- data/examples/complex-spec-app/docs/api/README.md +0 -104
- data/examples/complex-spec-app/docs/api/api/v1/admin/products/create.md +0 -117
- data/examples/complex-spec-app/docs/api/api/v1/admin/products/destroy.md +0 -51
- data/examples/complex-spec-app/docs/api/api/v1/admin/products/index.md +0 -11
- data/examples/complex-spec-app/docs/api/api/v1/admin/products/list.md +0 -106
- data/examples/complex-spec-app/docs/api/api/v1/auth/index.md +0 -9
- data/examples/complex-spec-app/docs/api/api/v1/auth/login.md +0 -76
- data/examples/complex-spec-app/docs/api/api/v1/cart-items/create.md +0 -91
- data/examples/complex-spec-app/docs/api/api/v1/cart-items/destroy.md +0 -51
- data/examples/complex-spec-app/docs/api/api/v1/cart-items/index.md +0 -10
- data/examples/complex-spec-app/docs/api/api/v1/carts/checkout.md +0 -102
- data/examples/complex-spec-app/docs/api/api/v1/carts/index.md +0 -10
- data/examples/complex-spec-app/docs/api/api/v1/carts/show.md +0 -73
- data/examples/complex-spec-app/docs/api/api/v1/home/index.md +0 -9
- data/examples/complex-spec-app/docs/api/api/v1/home/list.md +0 -47
- data/examples/complex-spec-app/docs/api/api/v1/notes/create.md +0 -94
- data/examples/complex-spec-app/docs/api/api/v1/notes/index.md +0 -10
- data/examples/complex-spec-app/docs/api/api/v1/notes/list.md +0 -61
- data/examples/complex-spec-app/docs/api/api/v1/orders/cancel.md +0 -69
- data/examples/complex-spec-app/docs/api/api/v1/orders/create.md +0 -150
- data/examples/complex-spec-app/docs/api/api/v1/orders/destroy.md +0 -37
- data/examples/complex-spec-app/docs/api/api/v1/orders/index.md +0 -13
- data/examples/complex-spec-app/docs/api/api/v1/orders/list.md +0 -78
- data/examples/complex-spec-app/docs/api/api/v1/orders/show.md +0 -83
- data/examples/complex-spec-app/docs/api/api/v1/products/index.md +0 -11
- data/examples/complex-spec-app/docs/api/api/v1/products/list.md +0 -83
- data/examples/complex-spec-app/docs/api/api/v1/products/search.md +0 -88
- data/examples/complex-spec-app/docs/api/api/v1/products/show.md +0 -71
- data/examples/complex-spec-app/docs/api/api/v1/profiles/index.md +0 -10
- data/examples/complex-spec-app/docs/api/api/v1/profiles/show.md +0 -61
- data/examples/complex-spec-app/docs/api/api/v1/profiles/update.md +0 -91
- data/examples/complex-spec-app/docs/api/api/v2/products/index.md +0 -9
- data/examples/complex-spec-app/docs/api/api/v2/products/list.md +0 -77
- data/examples/complex-spec-app/docs/api/curl/api/v1/admin/products/create.sh +0 -18
- data/examples/complex-spec-app/docs/api/curl/api/v1/admin/products/destroy.sh +0 -9
- data/examples/complex-spec-app/docs/api/curl/api/v1/admin/products/list.sh +0 -9
- data/examples/complex-spec-app/docs/api/curl/api/v1/auth/login.sh +0 -9
- data/examples/complex-spec-app/docs/api/curl/api/v1/cart-items/create.sh +0 -16
- data/examples/complex-spec-app/docs/api/curl/api/v1/cart-items/destroy.sh +0 -9
- data/examples/complex-spec-app/docs/api/curl/api/v1/carts/checkout.sh +0 -13
- data/examples/complex-spec-app/docs/api/curl/api/v1/carts/show.sh +0 -9
- data/examples/complex-spec-app/docs/api/curl/api/v1/home/list.sh +0 -8
- data/examples/complex-spec-app/docs/api/curl/api/v1/notes/create.sh +0 -15
- data/examples/complex-spec-app/docs/api/curl/api/v1/notes/list.sh +0 -9
- data/examples/complex-spec-app/docs/api/curl/api/v1/orders/cancel.sh +0 -9
- data/examples/complex-spec-app/docs/api/curl/api/v1/orders/create.sh +0 -29
- data/examples/complex-spec-app/docs/api/curl/api/v1/orders/destroy.sh +0 -9
- data/examples/complex-spec-app/docs/api/curl/api/v1/orders/list.sh +0 -9
- data/examples/complex-spec-app/docs/api/curl/api/v1/orders/show.sh +0 -9
- data/examples/complex-spec-app/docs/api/curl/api/v1/products/list.sh +0 -8
- data/examples/complex-spec-app/docs/api/curl/api/v1/products/search.sh +0 -8
- data/examples/complex-spec-app/docs/api/curl/api/v1/products/show.sh +0 -8
- data/examples/complex-spec-app/docs/api/curl/api/v1/profiles/show.sh +0 -9
- data/examples/complex-spec-app/docs/api/curl/api/v1/profiles/update.sh +0 -16
- data/examples/complex-spec-app/docs/api/curl/api/v2/products/list.sh +0 -8
- data/examples/complex-spec-app/docs/api/dataset.json +0 -5116
- data/examples/complex-spec-app/docs/api/postman/collection.json +0 -2519
- data/examples/complex-spec-app/generate.rb +0 -14
- data/examples/complex-spec-app/reqcord.yml +0 -28
- data/examples/complex-spec-app/spec/requests/admin_spec.rb +0 -67
- data/examples/complex-spec-app/spec/requests/cart_spec.rb +0 -61
- data/examples/complex-spec-app/spec/requests/home_and_auth_spec.rb +0 -49
- data/examples/complex-spec-app/spec/requests/orders_spec.rb +0 -124
- data/examples/complex-spec-app/spec/requests/products_spec.rb +0 -65
- data/examples/complex-spec-app/spec/spec_helper.rb +0 -17
- data/examples/complex-test-app/README.md +0 -40
- data/examples/complex-test-app/app.rb +0 -384
- data/examples/complex-test-app/docs/api/README.md +0 -104
- data/examples/complex-test-app/docs/api/api/v1/admin/products/create.md +0 -117
- data/examples/complex-test-app/docs/api/api/v1/admin/products/destroy.md +0 -51
- data/examples/complex-test-app/docs/api/api/v1/admin/products/index.md +0 -11
- data/examples/complex-test-app/docs/api/api/v1/admin/products/list.md +0 -106
- data/examples/complex-test-app/docs/api/api/v1/auth/index.md +0 -9
- data/examples/complex-test-app/docs/api/api/v1/auth/login.md +0 -76
- data/examples/complex-test-app/docs/api/api/v1/cart-items/create.md +0 -91
- data/examples/complex-test-app/docs/api/api/v1/cart-items/destroy.md +0 -51
- data/examples/complex-test-app/docs/api/api/v1/cart-items/index.md +0 -10
- data/examples/complex-test-app/docs/api/api/v1/carts/checkout.md +0 -102
- data/examples/complex-test-app/docs/api/api/v1/carts/index.md +0 -10
- data/examples/complex-test-app/docs/api/api/v1/carts/show.md +0 -73
- data/examples/complex-test-app/docs/api/api/v1/home/index.md +0 -9
- data/examples/complex-test-app/docs/api/api/v1/home/list.md +0 -47
- data/examples/complex-test-app/docs/api/api/v1/notes/create.md +0 -94
- data/examples/complex-test-app/docs/api/api/v1/notes/index.md +0 -10
- data/examples/complex-test-app/docs/api/api/v1/notes/list.md +0 -61
- data/examples/complex-test-app/docs/api/api/v1/orders/cancel.md +0 -69
- data/examples/complex-test-app/docs/api/api/v1/orders/create.md +0 -150
- data/examples/complex-test-app/docs/api/api/v1/orders/destroy.md +0 -37
- data/examples/complex-test-app/docs/api/api/v1/orders/index.md +0 -13
- data/examples/complex-test-app/docs/api/api/v1/orders/list.md +0 -71
- data/examples/complex-test-app/docs/api/api/v1/orders/show.md +0 -83
- data/examples/complex-test-app/docs/api/api/v1/products/index.md +0 -11
- data/examples/complex-test-app/docs/api/api/v1/products/list.md +0 -83
- data/examples/complex-test-app/docs/api/api/v1/products/search.md +0 -88
- data/examples/complex-test-app/docs/api/api/v1/products/show.md +0 -71
- data/examples/complex-test-app/docs/api/api/v1/profiles/index.md +0 -10
- data/examples/complex-test-app/docs/api/api/v1/profiles/show.md +0 -61
- data/examples/complex-test-app/docs/api/api/v1/profiles/update.md +0 -91
- data/examples/complex-test-app/docs/api/api/v2/products/index.md +0 -9
- data/examples/complex-test-app/docs/api/api/v2/products/list.md +0 -77
- data/examples/complex-test-app/docs/api/curl/api/v1/admin/products/create.sh +0 -18
- data/examples/complex-test-app/docs/api/curl/api/v1/admin/products/destroy.sh +0 -9
- data/examples/complex-test-app/docs/api/curl/api/v1/admin/products/list.sh +0 -9
- data/examples/complex-test-app/docs/api/curl/api/v1/auth/login.sh +0 -9
- data/examples/complex-test-app/docs/api/curl/api/v1/cart-items/create.sh +0 -16
- data/examples/complex-test-app/docs/api/curl/api/v1/cart-items/destroy.sh +0 -9
- data/examples/complex-test-app/docs/api/curl/api/v1/carts/checkout.sh +0 -13
- data/examples/complex-test-app/docs/api/curl/api/v1/carts/show.sh +0 -9
- data/examples/complex-test-app/docs/api/curl/api/v1/home/list.sh +0 -8
- data/examples/complex-test-app/docs/api/curl/api/v1/notes/create.sh +0 -15
- data/examples/complex-test-app/docs/api/curl/api/v1/notes/list.sh +0 -9
- data/examples/complex-test-app/docs/api/curl/api/v1/orders/cancel.sh +0 -9
- data/examples/complex-test-app/docs/api/curl/api/v1/orders/create.sh +0 -29
- data/examples/complex-test-app/docs/api/curl/api/v1/orders/destroy.sh +0 -9
- data/examples/complex-test-app/docs/api/curl/api/v1/orders/list.sh +0 -9
- data/examples/complex-test-app/docs/api/curl/api/v1/orders/show.sh +0 -9
- data/examples/complex-test-app/docs/api/curl/api/v1/products/list.sh +0 -8
- data/examples/complex-test-app/docs/api/curl/api/v1/products/search.sh +0 -8
- data/examples/complex-test-app/docs/api/curl/api/v1/products/show.sh +0 -8
- data/examples/complex-test-app/docs/api/curl/api/v1/profiles/show.sh +0 -9
- data/examples/complex-test-app/docs/api/curl/api/v1/profiles/update.sh +0 -16
- data/examples/complex-test-app/docs/api/curl/api/v2/products/list.sh +0 -8
- data/examples/complex-test-app/docs/api/dataset.json +0 -5109
- data/examples/complex-test-app/docs/api/postman/collection.json +0 -2568
- data/examples/complex-test-app/generate.rb +0 -14
- data/examples/complex-test-app/reqcord.yml +0 -28
- data/examples/complex-test-app/test/integration/admin_test.rb +0 -70
- data/examples/complex-test-app/test/integration/cart_test.rb +0 -64
- data/examples/complex-test-app/test/integration/home_and_auth_test.rb +0 -53
- data/examples/complex-test-app/test/integration/orders_test.rb +0 -127
- data/examples/complex-test-app/test/integration/products_test.rb +0 -66
- data/examples/spec-app/.rspec +0 -1
- data/examples/spec-app/README.md +0 -36
- data/examples/spec-app/app.rb +0 -209
- data/examples/spec-app/docs/api/README.md +0 -45
- data/examples/spec-app/docs/api/api/v1/customers/create.md +0 -95
- data/examples/spec-app/docs/api/api/v1/customers/index.md +0 -11
- data/examples/spec-app/docs/api/api/v1/customers/list.md +0 -67
- data/examples/spec-app/docs/api/api/v1/customers/show.md +0 -65
- data/examples/spec-app/docs/api/api/v1/tasks/complete.md +0 -51
- data/examples/spec-app/docs/api/api/v1/tasks/create.md +0 -90
- data/examples/spec-app/docs/api/api/v1/tasks/destroy.md +0 -35
- data/examples/spec-app/docs/api/api/v1/tasks/index.md +0 -14
- data/examples/spec-app/docs/api/api/v1/tasks/list.md +0 -65
- data/examples/spec-app/docs/api/api/v1/tasks/show.md +0 -65
- data/examples/spec-app/docs/api/api/v1/tasks/update.md +0 -74
- data/examples/spec-app/docs/api/api/v1/users/create.md +0 -95
- data/examples/spec-app/docs/api/api/v1/users/index.md +0 -11
- data/examples/spec-app/docs/api/api/v1/users/list.md +0 -67
- data/examples/spec-app/docs/api/api/v1/users/show.md +0 -65
- data/examples/spec-app/docs/api/curl/api/v1/customers/create.sh +0 -17
- data/examples/spec-app/docs/api/curl/api/v1/customers/list.sh +0 -9
- data/examples/spec-app/docs/api/curl/api/v1/customers/show.sh +0 -9
- data/examples/spec-app/docs/api/curl/api/v1/tasks/complete.sh +0 -8
- data/examples/spec-app/docs/api/curl/api/v1/tasks/create.sh +0 -15
- data/examples/spec-app/docs/api/curl/api/v1/tasks/destroy.sh +0 -8
- data/examples/spec-app/docs/api/curl/api/v1/tasks/list.sh +0 -8
- data/examples/spec-app/docs/api/curl/api/v1/tasks/show.sh +0 -8
- data/examples/spec-app/docs/api/curl/api/v1/tasks/update.sh +0 -14
- data/examples/spec-app/docs/api/curl/api/v1/users/create.sh +0 -17
- data/examples/spec-app/docs/api/curl/api/v1/users/list.sh +0 -9
- data/examples/spec-app/docs/api/curl/api/v1/users/show.sh +0 -9
- data/examples/spec-app/docs/api/dataset.json +0 -2402
- data/examples/spec-app/docs/api/postman/collection.json +0 -1290
- data/examples/spec-app/generate.rb +0 -14
- data/examples/spec-app/reqcord.yml +0 -27
- data/examples/spec-app/spec/requests/customers_spec.rb +0 -71
- data/examples/spec-app/spec/requests/tasks_spec.rb +0 -78
- data/examples/spec-app/spec/requests/users_spec.rb +0 -68
- data/examples/spec-app/spec/spec_helper.rb +0 -17
- data/examples/test-app/README.md +0 -57
- data/examples/test-app/app.rb +0 -212
- data/examples/test-app/docs/api/README.md +0 -45
- data/examples/test-app/docs/api/api/v1/customers/create.md +0 -95
- data/examples/test-app/docs/api/api/v1/customers/index.md +0 -11
- data/examples/test-app/docs/api/api/v1/customers/list.md +0 -67
- data/examples/test-app/docs/api/api/v1/customers/show.md +0 -65
- data/examples/test-app/docs/api/api/v1/tasks/complete.md +0 -51
- data/examples/test-app/docs/api/api/v1/tasks/create.md +0 -90
- data/examples/test-app/docs/api/api/v1/tasks/destroy.md +0 -35
- data/examples/test-app/docs/api/api/v1/tasks/index.md +0 -14
- data/examples/test-app/docs/api/api/v1/tasks/list.md +0 -65
- data/examples/test-app/docs/api/api/v1/tasks/show.md +0 -65
- data/examples/test-app/docs/api/api/v1/tasks/update.md +0 -74
- data/examples/test-app/docs/api/api/v1/users/create.md +0 -95
- data/examples/test-app/docs/api/api/v1/users/index.md +0 -11
- data/examples/test-app/docs/api/api/v1/users/list.md +0 -67
- data/examples/test-app/docs/api/api/v1/users/show.md +0 -65
- data/examples/test-app/docs/api/curl/api/v1/customers/create.sh +0 -17
- data/examples/test-app/docs/api/curl/api/v1/customers/list.sh +0 -9
- data/examples/test-app/docs/api/curl/api/v1/customers/show.sh +0 -9
- data/examples/test-app/docs/api/curl/api/v1/tasks/complete.sh +0 -8
- data/examples/test-app/docs/api/curl/api/v1/tasks/create.sh +0 -15
- data/examples/test-app/docs/api/curl/api/v1/tasks/destroy.sh +0 -8
- data/examples/test-app/docs/api/curl/api/v1/tasks/list.sh +0 -8
- data/examples/test-app/docs/api/curl/api/v1/tasks/show.sh +0 -8
- data/examples/test-app/docs/api/curl/api/v1/tasks/update.sh +0 -14
- data/examples/test-app/docs/api/curl/api/v1/users/create.sh +0 -17
- data/examples/test-app/docs/api/curl/api/v1/users/list.sh +0 -9
- data/examples/test-app/docs/api/curl/api/v1/users/show.sh +0 -9
- data/examples/test-app/docs/api/dataset.json +0 -2402
- data/examples/test-app/docs/api/postman/collection.json +0 -1290
- data/examples/test-app/generate.rb +0 -14
- data/examples/test-app/reqcord.yml +0 -28
- data/examples/test-app/test/integration/customers_test.rb +0 -72
- data/examples/test-app/test/integration/tasks_test.rb +0 -80
- data/examples/test-app/test/integration/users_test.rb +0 -72
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# Stands in for `bin/rails reqcord:generate`, which this single file example
|
|
4
|
-
# has no `bin/rails` to run.
|
|
5
|
-
require_relative "app"
|
|
6
|
-
|
|
7
|
-
dataset = Reqcord::Generator.call(
|
|
8
|
-
resources: ENV.fetch("RESOURCE", "").split(",").map(&:strip).reject(&:empty?),
|
|
9
|
-
version: ENV["VERSION"]
|
|
10
|
-
)
|
|
11
|
-
|
|
12
|
-
puts
|
|
13
|
-
puts "Endpoints: #{dataset.endpoints.size} (#{dataset.documented_endpoints.size} covered by tests)"
|
|
14
|
-
puts "Output: #{Reqcord.configuration.output_directory}"
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
version: 1
|
|
2
|
-
|
|
3
|
-
test:
|
|
4
|
-
framework: rspec
|
|
5
|
-
# A directory is enough: Reqcord runs `rspec <paths>`.
|
|
6
|
-
paths:
|
|
7
|
-
- spec/requests
|
|
8
|
-
|
|
9
|
-
routes:
|
|
10
|
-
prefix: /api
|
|
11
|
-
|
|
12
|
-
output:
|
|
13
|
-
directory: docs/api
|
|
14
|
-
|
|
15
|
-
exporters:
|
|
16
|
-
- curl
|
|
17
|
-
- markdown
|
|
18
|
-
- postman
|
|
19
|
-
|
|
20
|
-
variables:
|
|
21
|
-
base_url: http://localhost:3000
|
|
22
|
-
|
|
23
|
-
sanitize:
|
|
24
|
-
headers:
|
|
25
|
-
Authorization: "Bearer {{token}}"
|
|
26
|
-
body:
|
|
27
|
-
password: "{{password}}"
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# Ordinary request specs. As with Minitest, nothing here mentions Reqcord.
|
|
4
|
-
#
|
|
5
|
-
# The status assertions are spelled out because this example runs on plain
|
|
6
|
-
# rspec-core; with rspec-rails you would write `have_http_status(:created)`.
|
|
7
|
-
require "spec_helper"
|
|
8
|
-
|
|
9
|
-
RSpec.describe "Customers", type: :request do
|
|
10
|
-
let(:auth) { { "Authorization" => "Bearer eyJhbGciOiJIUzI1NiJ9.super-secret" } }
|
|
11
|
-
|
|
12
|
-
it "lists customers" do
|
|
13
|
-
get "/api/v1/customers", params: { per_page: 1 }, headers: auth, as: :json
|
|
14
|
-
|
|
15
|
-
expect(response.status).to eq(200)
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
it "shows customer" do
|
|
19
|
-
get "/api/v1/customers/1", headers: auth, as: :json
|
|
20
|
-
|
|
21
|
-
expect(response.status).to eq(200)
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
it "returns not found for an unknown customer" do
|
|
25
|
-
get "/api/v1/customers/999", headers: auth, as: :json
|
|
26
|
-
|
|
27
|
-
expect(response.status).to eq(404)
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
it "creates an active customer" do
|
|
31
|
-
post "/api/v1/customers",
|
|
32
|
-
params: { customer: { name: "Ada Lovelace", email: "ada@example.com", status: "active" } },
|
|
33
|
-
headers: auth,
|
|
34
|
-
as: :json
|
|
35
|
-
|
|
36
|
-
expect(response.status).to eq(201)
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
it "creates a passive customer" do
|
|
40
|
-
post "/api/v1/customers",
|
|
41
|
-
params: { customer: { name: "Grace Hopper", email: "grace@example.com", status: "passive" } },
|
|
42
|
-
headers: auth,
|
|
43
|
-
as: :json
|
|
44
|
-
|
|
45
|
-
expect(response.status).to eq(201)
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
it "rejects an unknown status" do
|
|
49
|
-
post "/api/v1/customers",
|
|
50
|
-
params: { customer: { name: "Ada Lovelace", email: "ada@example.com", status: "inactive" } },
|
|
51
|
-
headers: auth,
|
|
52
|
-
as: :json
|
|
53
|
-
|
|
54
|
-
expect(response.status).to eq(422)
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
it "rejects a customer without an email" do
|
|
58
|
-
post "/api/v1/customers",
|
|
59
|
-
params: { customer: { name: "Ada Lovelace", email: "", status: "active" } },
|
|
60
|
-
headers: auth,
|
|
61
|
-
as: :json
|
|
62
|
-
|
|
63
|
-
expect(response.status).to eq(422)
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
it "requires authentication" do
|
|
67
|
-
get "/api/v1/customers", as: :json
|
|
68
|
-
|
|
69
|
-
expect(response.status).to eq(401)
|
|
70
|
-
end
|
|
71
|
-
end
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# Ordinary request specs. As with Minitest, nothing here mentions Reqcord.
|
|
4
|
-
require "spec_helper"
|
|
5
|
-
|
|
6
|
-
RSpec.describe "Tasks", type: :request do
|
|
7
|
-
it "lists tasks" do
|
|
8
|
-
get "/api/v1/tasks", as: :json
|
|
9
|
-
|
|
10
|
-
expect(response.status).to eq(200)
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
it "lists open tasks" do
|
|
14
|
-
get "/api/v1/tasks", params: { status: "open" }, as: :json
|
|
15
|
-
|
|
16
|
-
expect(response.status).to eq(200)
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
it "lists done tasks" do
|
|
20
|
-
get "/api/v1/tasks", params: { status: "done" }, as: :json
|
|
21
|
-
|
|
22
|
-
expect(response.status).to eq(200)
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
it "shows a task" do
|
|
26
|
-
get "/api/v1/tasks/1", as: :json
|
|
27
|
-
|
|
28
|
-
expect(response.status).to eq(200)
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
it "returns not found for an unknown task" do
|
|
32
|
-
get "/api/v1/tasks/999", as: :json
|
|
33
|
-
|
|
34
|
-
expect(response.status).to eq(404)
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
it "creates a high priority task" do
|
|
38
|
-
post "/api/v1/tasks", params: { task: { title: "Review the release", priority: "high" } }, as: :json
|
|
39
|
-
|
|
40
|
-
expect(response.status).to eq(201)
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
it "creates a low priority task" do
|
|
44
|
-
post "/api/v1/tasks", params: { task: { title: "Water the plants", priority: "low" } }, as: :json
|
|
45
|
-
|
|
46
|
-
expect(response.status).to eq(201)
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
it "rejects a task without a title" do
|
|
50
|
-
post "/api/v1/tasks", params: { task: { title: "", priority: "high" } }, as: :json
|
|
51
|
-
|
|
52
|
-
expect(response.status).to eq(422)
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
it "rejects an unknown priority" do
|
|
56
|
-
post "/api/v1/tasks", params: { task: { title: "Anything", priority: "urgent" } }, as: :json
|
|
57
|
-
|
|
58
|
-
expect(response.status).to eq(422)
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
it "updates a task" do
|
|
62
|
-
patch "/api/v1/tasks/1", params: { task: { title: "Write better docs" } }, as: :json
|
|
63
|
-
|
|
64
|
-
expect(response.status).to eq(200)
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
it "completes a task" do
|
|
68
|
-
post "/api/v1/tasks/1/complete", as: :json
|
|
69
|
-
|
|
70
|
-
expect(response.status).to eq(200)
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
it "deletes a task" do
|
|
74
|
-
delete "/api/v1/tasks/3", as: :json
|
|
75
|
-
|
|
76
|
-
expect(response.status).to eq(204)
|
|
77
|
-
end
|
|
78
|
-
end
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# Ordinary request specs. As with Minitest, nothing here mentions Reqcord.
|
|
4
|
-
require "spec_helper"
|
|
5
|
-
|
|
6
|
-
RSpec.describe "Users", type: :request do
|
|
7
|
-
let(:auth) { { "Authorization" => "Bearer eyJhbGciOiJIUzI1NiJ9.super-secret" } }
|
|
8
|
-
|
|
9
|
-
it "lists users" do
|
|
10
|
-
get "/api/v1/users", params: { per_page: 1 }, headers: auth, as: :json
|
|
11
|
-
|
|
12
|
-
expect(response.status).to eq(200)
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
it "shows user" do
|
|
16
|
-
get "/api/v1/users/1", headers: auth, as: :json
|
|
17
|
-
|
|
18
|
-
expect(response.status).to eq(200)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
it "returns not found for an unknown user" do
|
|
22
|
-
get "/api/v1/users/999", headers: auth, as: :json
|
|
23
|
-
|
|
24
|
-
expect(response.status).to eq(404)
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
it "creates an active user" do
|
|
28
|
-
post "/api/v1/users",
|
|
29
|
-
params: { user: { name: "Ada Lovelace", email: "ada@example.com", status: "active" } },
|
|
30
|
-
headers: auth,
|
|
31
|
-
as: :json
|
|
32
|
-
|
|
33
|
-
expect(response.status).to eq(201)
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
it "creates an inactive user" do
|
|
37
|
-
post "/api/v1/users",
|
|
38
|
-
params: { user: { name: "Grace Hopper", email: "grace@example.com", status: "inactive" } },
|
|
39
|
-
headers: auth,
|
|
40
|
-
as: :json
|
|
41
|
-
|
|
42
|
-
expect(response.status).to eq(201)
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
it "rejects an unknown status" do
|
|
46
|
-
post "/api/v1/users",
|
|
47
|
-
params: { user: { name: "Ada Lovelace", email: "ada@example.com", status: "passive" } },
|
|
48
|
-
headers: auth,
|
|
49
|
-
as: :json
|
|
50
|
-
|
|
51
|
-
expect(response.status).to eq(422)
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
it "rejects a user without an email" do
|
|
55
|
-
post "/api/v1/users",
|
|
56
|
-
params: { user: { name: "Ada Lovelace", email: "", status: "active" } },
|
|
57
|
-
headers: auth,
|
|
58
|
-
as: :json
|
|
59
|
-
|
|
60
|
-
expect(response.status).to eq(422)
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
it "requires authentication" do
|
|
64
|
-
get "/api/v1/users", as: :json
|
|
65
|
-
|
|
66
|
-
expect(response.status).to eq(401)
|
|
67
|
-
end
|
|
68
|
-
end
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative "../app"
|
|
4
|
-
|
|
5
|
-
require "rspec/core"
|
|
6
|
-
require "action_dispatch/testing/integration"
|
|
7
|
-
|
|
8
|
-
RSpec.configure do |config|
|
|
9
|
-
# What rspec-rails would give you as `type: :request`; spelled out here so
|
|
10
|
-
# the example runs with plain rspec-core.
|
|
11
|
-
config.include ActionDispatch::Integration::Runner, type: :request
|
|
12
|
-
config.include ActionDispatch::IntegrationTest::Behavior, type: :request
|
|
13
|
-
|
|
14
|
-
config.before(:each, type: :request) { integration_session }
|
|
15
|
-
|
|
16
|
-
config.expect_with(:rspec) { |expectations| expectations.syntax = :expect }
|
|
17
|
-
end
|
data/examples/test-app/README.md
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
# test-app (Minitest)
|
|
2
|
-
|
|
3
|
-
A one file Rails API with ordinary Minitest integration tests, and the
|
|
4
|
-
documentation Reqcord generates from them. Three resources, each there to
|
|
5
|
-
show something different in the output:
|
|
6
|
-
|
|
7
|
-
| Resource | Shows |
|
|
8
|
-
| --- | --- |
|
|
9
|
-
| `customers` | bearer auth, a closed set of values (`"active" \| "passive"`), 401/422 responses |
|
|
10
|
-
| `users` | a second authenticated resource with its own status set |
|
|
11
|
-
| `tasks` | no auth, full CRUD, `PATCH` and `PUT` folded into one page, a `204`, a member action (`complete`), a filtered index (`?status=open`) |
|
|
12
|
-
|
|
13
|
-
```text
|
|
14
|
-
app.rb the application
|
|
15
|
-
test/integration/*_test.rb ordinary integration tests
|
|
16
|
-
reqcord.yml Reqcord configuration
|
|
17
|
-
docs/api/ generated output, committed here so you can
|
|
18
|
-
read it without running anything:
|
|
19
|
-
api/v1/{customers,users,tasks}/*.md Markdown, one page per endpoint
|
|
20
|
-
curl/api/v1/**/*.sh runnable cURL scripts
|
|
21
|
-
postman/collection.json Postman collection (Hoppscotch imports it)
|
|
22
|
-
dataset.json the canonical dataset behind all three
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
## Regenerate
|
|
26
|
-
|
|
27
|
-
```bash
|
|
28
|
-
ruby generate.rb
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
In a real application you would run `bin/rails reqcord:generate` instead;
|
|
32
|
-
`generate.rb` only exists because this example has no `bin/rails`.
|
|
33
|
-
|
|
34
|
-
`reqcord.yml` only names the test directory; with no `bin/rails` around,
|
|
35
|
-
Reqcord runs every `*_test.rb` beneath it itself.
|
|
36
|
-
|
|
37
|
-
Filters work the same way:
|
|
38
|
-
|
|
39
|
-
```bash
|
|
40
|
-
RESOURCE=tasks ruby generate.rb
|
|
41
|
-
RESOURCE=customers,users ruby generate.rb
|
|
42
|
-
VERSION=v1 ruby generate.rb
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
## What to look at
|
|
46
|
-
|
|
47
|
-
- The tests never mention Reqcord.
|
|
48
|
-
- `Authorization: Bearer eyJ...` is written as `Bearer {{token}}` in
|
|
49
|
-
[docs/api/api/v1/customers/create.md](docs/api/api/v1/customers/create.md).
|
|
50
|
-
- `customer.status` is documented as `"active" | "passive"`: two tests sent
|
|
51
|
-
those and passed, a third sent `"inactive"` and was rejected, so the
|
|
52
|
-
rejected value never becomes a documented parameter.
|
|
53
|
-
- One endpoint carries every status its tests produced: `201`, `422`, `401`.
|
|
54
|
-
- Each cURL example uses the real captured path, so it can be pasted into a
|
|
55
|
-
terminal once `{{token}}` is replaced; the same request is in
|
|
56
|
-
[docs/api/postman/collection.json](docs/api/postman/collection.json) with
|
|
57
|
-
`{{token}}` as a collection variable.
|
data/examples/test-app/app.rb
DELETED
|
@@ -1,212 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# A tiny Rails API, in one file, so the example stays readable. In a real
|
|
4
|
-
# application this is just your app; Reqcord does not care how it is built.
|
|
5
|
-
#
|
|
6
|
-
# Three resources, each showing something different in the output:
|
|
7
|
-
# customers authenticated, a closed set of statuses ("active" | "passive")
|
|
8
|
-
# users the same shape with its own status set, to show two resources
|
|
9
|
-
# tasks public (no auth), full CRUD with PATCH/PUT, a 204, a member
|
|
10
|
-
# action (`complete`) and a filtered index (`?status=`)
|
|
11
|
-
ENV["RAILS_ENV"] ||= "test"
|
|
12
|
-
|
|
13
|
-
# Only needed because this example lives inside the Reqcord repository.
|
|
14
|
-
# In your own application, `gem "reqcord"` in the Gemfile is enough.
|
|
15
|
-
$LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
|
|
16
|
-
|
|
17
|
-
require "rails"
|
|
18
|
-
require "action_controller/railtie"
|
|
19
|
-
require "reqcord"
|
|
20
|
-
|
|
21
|
-
class ExampleApp < Rails::Application
|
|
22
|
-
config.root = __dir__
|
|
23
|
-
config.eager_load = false
|
|
24
|
-
config.logger = Logger.new(IO::NULL)
|
|
25
|
-
config.secret_key_base = "a" * 64
|
|
26
|
-
config.hosts.clear
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
Rails.application.initialize!
|
|
30
|
-
|
|
31
|
-
module Api
|
|
32
|
-
module V1
|
|
33
|
-
class CustomersController < ActionController::API
|
|
34
|
-
CUSTOMERS = [
|
|
35
|
-
{ id: 1, name: "John Doe", email: "john@example.com" },
|
|
36
|
-
{ id: 2, name: "Jane Roe", email: "jane@example.com" }
|
|
37
|
-
].freeze
|
|
38
|
-
|
|
39
|
-
before_action :authenticate!
|
|
40
|
-
|
|
41
|
-
def index
|
|
42
|
-
render json: CUSTOMERS.first(params.fetch(:per_page, 25).to_i)
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def show
|
|
46
|
-
customer = CUSTOMERS.find { |record| record[:id] == params[:id].to_i }
|
|
47
|
-
|
|
48
|
-
return render(json: { error: "Not Found" }, status: :not_found) unless customer
|
|
49
|
-
|
|
50
|
-
render json: customer
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
STATUSES = %w[active passive].freeze
|
|
54
|
-
|
|
55
|
-
def create
|
|
56
|
-
if params.dig(:customer, :email).to_s.empty?
|
|
57
|
-
return render(
|
|
58
|
-
json: { errors: { email: ["can't be blank"] } },
|
|
59
|
-
status: :unprocessable_entity
|
|
60
|
-
)
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
unless STATUSES.include?(params.dig(:customer, :status).to_s)
|
|
64
|
-
return render(
|
|
65
|
-
json: { errors: { status: ["is not included in the list"] } },
|
|
66
|
-
status: :unprocessable_entity
|
|
67
|
-
)
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
render json: { id: 3, **customer_params }, status: :created
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
private
|
|
74
|
-
|
|
75
|
-
def authenticate!
|
|
76
|
-
return if request.headers["Authorization"].present?
|
|
77
|
-
|
|
78
|
-
render json: { error: "Unauthorized" }, status: :unauthorized
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
def customer_params
|
|
82
|
-
params.require(:customer).permit(:name, :email, :status).to_h.symbolize_keys
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
class UsersController < ActionController::API
|
|
87
|
-
USERS = [
|
|
88
|
-
{ id: 1, name: "John Doe", email: "john@example.com" },
|
|
89
|
-
{ id: 2, name: "Jane Roe", email: "jane@example.com" }
|
|
90
|
-
].freeze
|
|
91
|
-
|
|
92
|
-
before_action :authenticate!
|
|
93
|
-
|
|
94
|
-
def index
|
|
95
|
-
render json: USERS.first(params.fetch(:per_page, 25).to_i)
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
def show
|
|
99
|
-
user = USERS.find { |record| record[:id] == params[:id].to_i }
|
|
100
|
-
|
|
101
|
-
return render(json: { error: "Not Found" }, status: :not_found) unless user
|
|
102
|
-
|
|
103
|
-
render json: user
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
STATUSES = %w[active inactive].freeze
|
|
107
|
-
|
|
108
|
-
def create
|
|
109
|
-
if params.dig(:user, :email).to_s.empty?
|
|
110
|
-
return render(
|
|
111
|
-
json: { errors: { email: ["can't be blank"] } },
|
|
112
|
-
status: :unprocessable_entity
|
|
113
|
-
)
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
unless STATUSES.include?(params.dig(:user, :status).to_s)
|
|
117
|
-
return render(
|
|
118
|
-
json: { errors: { status: ["is not included in the list"] } },
|
|
119
|
-
status: :unprocessable_entity
|
|
120
|
-
)
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
render json: { id: 3, **user_params }, status: :created
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
private
|
|
127
|
-
|
|
128
|
-
def authenticate!
|
|
129
|
-
return if request.headers["Authorization"].present?
|
|
130
|
-
|
|
131
|
-
render json: { error: "Unauthorized" }, status: :unauthorized
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
def user_params
|
|
135
|
-
params.require(:user).permit(:name, :email, :status).to_h.symbolize_keys
|
|
136
|
-
end
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
class TasksController < ActionController::API
|
|
140
|
-
TASKS = [
|
|
141
|
-
{ id: 1, title: "Write the docs", status: "open", priority: "high" },
|
|
142
|
-
{ id: 2, title: "Ship 0.1.1", status: "done", priority: "high" },
|
|
143
|
-
{ id: 3, title: "Tidy the backlog", status: "open", priority: "low" }
|
|
144
|
-
].freeze
|
|
145
|
-
|
|
146
|
-
STATUSES = %w[open done].freeze
|
|
147
|
-
PRIORITIES = %w[low high].freeze
|
|
148
|
-
|
|
149
|
-
def index
|
|
150
|
-
tasks = TASKS
|
|
151
|
-
tasks = tasks.select { |task| task[:status] == params[:status] } if params[:status].present?
|
|
152
|
-
|
|
153
|
-
render json: tasks
|
|
154
|
-
end
|
|
155
|
-
|
|
156
|
-
before_action :find_task, only: %i[show update complete destroy]
|
|
157
|
-
|
|
158
|
-
def show
|
|
159
|
-
render json: @task
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
def create
|
|
163
|
-
if params.dig(:task, :title).to_s.empty?
|
|
164
|
-
return render(json: { errors: { title: ["can't be blank"] } }, status: :unprocessable_entity)
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
unless PRIORITIES.include?(params.dig(:task, :priority).to_s)
|
|
168
|
-
return render(json: { errors: { priority: ["is not included in the list"] } }, status: :unprocessable_entity)
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
render json: { id: 4, status: "open", **task_params }, status: :created
|
|
172
|
-
end
|
|
173
|
-
|
|
174
|
-
def update
|
|
175
|
-
render json: @task.merge(task_params)
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
def complete
|
|
179
|
-
render json: @task.merge(status: "done")
|
|
180
|
-
end
|
|
181
|
-
|
|
182
|
-
def destroy
|
|
183
|
-
head :no_content
|
|
184
|
-
end
|
|
185
|
-
|
|
186
|
-
private
|
|
187
|
-
|
|
188
|
-
# Rendering in a before_action halts the chain, so the action never runs.
|
|
189
|
-
def find_task
|
|
190
|
-
@task = TASKS.find { |task| task[:id] == params[:id].to_i }
|
|
191
|
-
|
|
192
|
-
render(json: { error: "Not Found" }, status: :not_found) unless @task
|
|
193
|
-
end
|
|
194
|
-
|
|
195
|
-
def task_params
|
|
196
|
-
params.require(:task).permit(:title, :priority, :status).to_h.symbolize_keys
|
|
197
|
-
end
|
|
198
|
-
end
|
|
199
|
-
end
|
|
200
|
-
end
|
|
201
|
-
|
|
202
|
-
Rails.application.routes.draw do
|
|
203
|
-
namespace :api do
|
|
204
|
-
namespace :v1 do
|
|
205
|
-
resources :customers, only: %i[index show create]
|
|
206
|
-
resources :users, only: %i[index show create]
|
|
207
|
-
resources :tasks, except: %i[new edit] do
|
|
208
|
-
post :complete, on: :member
|
|
209
|
-
end
|
|
210
|
-
end
|
|
211
|
-
end
|
|
212
|
-
end
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
# API Documentation
|
|
2
|
-
|
|
3
|
-
Generated by Reqcord from the application's integration tests.
|
|
4
|
-
|
|
5
|
-
Base URL: `http://localhost:3000`
|
|
6
|
-
|
|
7
|
-
## Placeholders
|
|
8
|
-
|
|
9
|
-
| Header | Replace with |
|
|
10
|
-
| --- | --- |
|
|
11
|
-
| Authorization | `Bearer {{token}}` |
|
|
12
|
-
| X-Api-Key | `{{api_key}}` |
|
|
13
|
-
|
|
14
|
-
## Customers
|
|
15
|
-
|
|
16
|
-
Namespace: `api/v1`
|
|
17
|
-
|
|
18
|
-
| Method | Path | Description |
|
|
19
|
-
| --- | --- | --- |
|
|
20
|
-
| `GET` | [`/api/v1/customers`](api/v1/customers/list.md) | List Customers |
|
|
21
|
-
| `POST` | [`/api/v1/customers`](api/v1/customers/create.md) | Create Customer |
|
|
22
|
-
| `GET` | [`/api/v1/customers/:id`](api/v1/customers/show.md) | Get Customer |
|
|
23
|
-
|
|
24
|
-
## Tasks
|
|
25
|
-
|
|
26
|
-
Namespace: `api/v1`
|
|
27
|
-
|
|
28
|
-
| Method | Path | Description |
|
|
29
|
-
| --- | --- | --- |
|
|
30
|
-
| `GET` | [`/api/v1/tasks`](api/v1/tasks/list.md) | List Tasks |
|
|
31
|
-
| `POST` | [`/api/v1/tasks`](api/v1/tasks/create.md) | Create Task |
|
|
32
|
-
| `DELETE` | [`/api/v1/tasks/:id`](api/v1/tasks/destroy.md) | Delete Task |
|
|
33
|
-
| `GET` | [`/api/v1/tasks/:id`](api/v1/tasks/show.md) | Get Task |
|
|
34
|
-
| `PATCH` | [`/api/v1/tasks/:id`](api/v1/tasks/update.md) | Update Task |
|
|
35
|
-
| `POST` | [`/api/v1/tasks/:id/complete`](api/v1/tasks/complete.md) | Complete Task |
|
|
36
|
-
|
|
37
|
-
## Users
|
|
38
|
-
|
|
39
|
-
Namespace: `api/v1`
|
|
40
|
-
|
|
41
|
-
| Method | Path | Description |
|
|
42
|
-
| --- | --- | --- |
|
|
43
|
-
| `GET` | [`/api/v1/users`](api/v1/users/list.md) | List Users |
|
|
44
|
-
| `POST` | [`/api/v1/users`](api/v1/users/create.md) | Create User |
|
|
45
|
-
| `GET` | [`/api/v1/users/:id`](api/v1/users/show.md) | Get User |
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
# Create Customer
|
|
2
|
-
|
|
3
|
-
`POST /api/v1/customers`
|
|
4
|
-
|
|
5
|
-
Namespace: `api/v1`
|
|
6
|
-
|
|
7
|
-
## Headers
|
|
8
|
-
|
|
9
|
-
| Header | Value |
|
|
10
|
-
| --- | --- |
|
|
11
|
-
| Authorization | `Bearer {{token}}` |
|
|
12
|
-
| Content-Type | `application/json` |
|
|
13
|
-
| Accept | `application/json` |
|
|
14
|
-
|
|
15
|
-
## Body Parameters
|
|
16
|
-
|
|
17
|
-
| Field | Type | Required | Values |
|
|
18
|
-
| --- | --- | --- | --- |
|
|
19
|
-
| `customer.name` | string | yes | `"Ada Lovelace"` |
|
|
20
|
-
| `customer.email` | string | yes | `"ada@example.com"` |
|
|
21
|
-
| `customer.status` | string | yes | `"active"` \| `"passive"` |
|
|
22
|
-
|
|
23
|
-
## Example Request
|
|
24
|
-
|
|
25
|
-
```json
|
|
26
|
-
{
|
|
27
|
-
"customer": {
|
|
28
|
-
"name": "Ada Lovelace",
|
|
29
|
-
"email": "ada@example.com",
|
|
30
|
-
"status": "active"
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
## cURL
|
|
36
|
-
|
|
37
|
-
```bash
|
|
38
|
-
curl --request POST \
|
|
39
|
-
--url "http://localhost:3000/api/v1/customers" \
|
|
40
|
-
--header "Authorization: Bearer {{token}}" \
|
|
41
|
-
--header "Content-Type: application/json" \
|
|
42
|
-
--header "Accept: application/json" \
|
|
43
|
-
--data '{
|
|
44
|
-
"customer": {
|
|
45
|
-
"name": "Ada Lovelace",
|
|
46
|
-
"email": "ada@example.com",
|
|
47
|
-
"status": "active"
|
|
48
|
-
}
|
|
49
|
-
}'
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
## Responses
|
|
53
|
-
|
|
54
|
-
### 201 Created
|
|
55
|
-
|
|
56
|
-
#### Fields
|
|
57
|
-
|
|
58
|
-
| Field | Type | Required | Values |
|
|
59
|
-
| --- | --- | --- | --- |
|
|
60
|
-
| `id` | integer | yes | `3` |
|
|
61
|
-
| `name` | string | yes | `"Ada Lovelace"` |
|
|
62
|
-
| `email` | string | yes | `"ada@example.com"` |
|
|
63
|
-
| `status` | string | yes | `"active"` \| `"passive"` |
|
|
64
|
-
|
|
65
|
-
```json
|
|
66
|
-
{
|
|
67
|
-
"id": 3,
|
|
68
|
-
"name": "Ada Lovelace",
|
|
69
|
-
"email": "ada@example.com",
|
|
70
|
-
"status": "active"
|
|
71
|
-
}
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
### 422 Unprocessable Content
|
|
75
|
-
|
|
76
|
-
#### Fields
|
|
77
|
-
|
|
78
|
-
| Field | Type | Required | Values |
|
|
79
|
-
| --- | --- | --- | --- |
|
|
80
|
-
| `errors.email[]` | string | no | `"can't be blank"` |
|
|
81
|
-
| `errors.status[]` | string | no | `"is not included in the list"` |
|
|
82
|
-
|
|
83
|
-
```json
|
|
84
|
-
{
|
|
85
|
-
"errors": {
|
|
86
|
-
"email": [
|
|
87
|
-
"can't be blank"
|
|
88
|
-
]
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
---
|
|
94
|
-
|
|
95
|
-
Resource: [Customers](index.md)
|