Skip to content

Commit afe1fc2

Browse files
authored
Merge pull request #1 from SiloGecho97/add-committe-rack-middleware
feat: add committee rack middleware
2 parents bce2edb + 3453f56 commit afe1fc2

File tree

4 files changed

+196
-0
lines changed

4 files changed

+196
-0
lines changed

Gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ gem "thruster", require: false
3434

3535
# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin Ajax possible
3636
# gem "rack-cors"
37+
gem "committee"
3738

3839
group :development, :test do
3940
# See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem

Gemfile.lock

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ GEM
8383
brakeman (7.0.0)
8484
racc
8585
builder (3.3.0)
86+
committee (5.5.1)
87+
json_schema (~> 0.14, >= 0.14.3)
88+
openapi_parser (~> 2.0)
89+
rack (>= 1.5, < 3.2)
8690
concurrent-ruby (1.3.5)
8791
connection_pool (2.5.0)
8892
crass (1.0.6)
@@ -109,6 +113,7 @@ GEM
109113
rdoc (>= 4.0.0)
110114
reline (>= 0.4.2)
111115
json (2.10.2)
116+
json_schema (0.21.0)
112117
kamal (2.5.3)
113118
activesupport (>= 7.0)
114119
base64 (~> 0.2)
@@ -156,6 +161,7 @@ GEM
156161
racc (~> 1.4)
157162
nokogiri (1.18.3-x86_64-linux-gnu)
158163
racc (~> 1.4)
164+
openapi_parser (2.2.4)
159165
ostruct (0.6.1)
160166
parallel (1.26.3)
161167
parser (3.3.7.1)
@@ -297,6 +303,7 @@ PLATFORMS
297303
DEPENDENCIES
298304
bootsnap
299305
brakeman
306+
committee
300307
debug
301308
kamal
302309
puma (>= 5.0)

config/application.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,13 @@ class Application < Rails::Application
2828
# Middleware like session, flash, cookies can be added back manually.
2929
# Skip views, helpers and assets when generating a new resource.
3030
config.api_only = true
31+
32+
config.middleware.use Committee::Middleware::RequestValidation,
33+
schema_path: "docs/openapi.json",
34+
coerce_date_times: true,
35+
params_key: "action_dispatch.request.request_parameters",
36+
query_hash_key: "action_dispatch.request.query_parameters",
37+
strict_reference_validation: true
38+
config.middleware.use Committee::Middleware::ResponseValidation, schema_path: "docs/openapi.json", strict_reference_validation: true
3139
end
3240
end

docs/openapi.json

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
{
2+
"openapi": "3.0.0",
3+
"info": {
4+
"title": "API Schema and Validation POC",
5+
"description": "API Schema and Validation POC.",
6+
7+
"version": "1.0.1"
8+
},
9+
"host": "localhost:3000",
10+
"schemes": ["http", "https"],
11+
"consumes": ["application/json"],
12+
"produces": ["application/json"],
13+
"paths": {
14+
"/comments": {
15+
"get": {
16+
"summary": "Returns a list of comments",
17+
"description": "A simple endpoint that returns a JSON response with a list of comments.",
18+
"responses": {
19+
"200": {
20+
"description": "A successful response",
21+
"content": {
22+
"application/json": {
23+
"schema": {
24+
"type": "array",
25+
"items": {
26+
"type": "object",
27+
"properties": {
28+
"id": { "type": "number" },
29+
"message": { "type": "string" },
30+
"created_at": { "type": "string", "format": "date-time" },
31+
"updated_at": { "type": "string", "format": "date-time" }
32+
}
33+
}
34+
}
35+
}
36+
}
37+
}
38+
}
39+
},
40+
"post": {
41+
"summary": "Creates a new comment",
42+
"description": "A simple endpoint that creates a new comment.",
43+
"requestBody": {
44+
"required": true,
45+
"content": {
46+
"application/json": {
47+
"schema": {
48+
"type": "object",
49+
"properties": {
50+
"comment": {
51+
"type": "object",
52+
"properties": {
53+
"message": { "type": "string" }
54+
},
55+
"required": ["message"]
56+
}
57+
}
58+
}
59+
}
60+
}
61+
},
62+
"responses": {
63+
"201": {
64+
"description": "Comment created successfully",
65+
"content": {
66+
"application/json": {
67+
"schema": {
68+
"type": "object",
69+
"properties": {
70+
"id": { "type": "number" },
71+
"message": { "type": "string" },
72+
"created_at": { "type": "string", "format": "date-time" },
73+
"updated_at": { "type": "string", "format": "date-time" }
74+
}
75+
}
76+
}
77+
}
78+
}
79+
}
80+
}
81+
},
82+
"/comments/{comment_id}": {
83+
"get": {
84+
"summary": "Returns a specific comment",
85+
"description": "A simple endpoint that returns a JSON response with a specific comment.",
86+
"parameters": [
87+
{
88+
"name": "comment_id",
89+
"in": "path",
90+
"required": true,
91+
"description": "The ID of the comment",
92+
"schema": { "type": "number" }
93+
}
94+
],
95+
"responses": {
96+
"200": {
97+
"description": "A successful response",
98+
"content": {
99+
"application/json": {
100+
"schema": {
101+
"type": "object",
102+
"properties": {
103+
"id": { "type": "number" },
104+
"message": { "type": "string" }
105+
}
106+
}
107+
}
108+
}
109+
}
110+
}
111+
},
112+
"put": {
113+
"summary": "Updates a specific comment",
114+
"description": "A simple endpoint that updates a specific comment.",
115+
"parameters": [
116+
{
117+
"name": "comment_id",
118+
"in": "path",
119+
"required": true,
120+
"description": "The ID of the comment",
121+
"schema": { "type": "string" }
122+
}
123+
],
124+
"requestBody": {
125+
"required": true,
126+
"content": {
127+
"application/json": {
128+
"schema": {
129+
"type": "object",
130+
"properties": {
131+
"comment": {
132+
"type": "object",
133+
"properties": {
134+
"message": { "type": "string" }
135+
},
136+
"required": ["message"]
137+
}
138+
}
139+
}
140+
}
141+
}
142+
},
143+
"responses": {
144+
"200": {
145+
"description": "Comment updated successfully",
146+
"content": {
147+
"application/json": {
148+
"schema": {
149+
"type": "object",
150+
"properties": {
151+
"id": { "type": "number" },
152+
"message": { "type": "string" }
153+
}
154+
}
155+
}
156+
}
157+
}
158+
}
159+
},
160+
"delete": {
161+
"summary": "Deletes a specific comment",
162+
"description": "A simple endpoint that deletes a specific comment.",
163+
"parameters": [
164+
{
165+
"name": "comment_id",
166+
"in": "path",
167+
"required": true,
168+
"description": "The ID of the comment",
169+
"schema": { "type": "string" }
170+
}
171+
],
172+
"responses": {
173+
"204": {
174+
"description": "Comment deleted successfully"
175+
}
176+
}
177+
}
178+
}
179+
}
180+
}

0 commit comments

Comments
 (0)