rapitapir 0.1.1 → 2.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 +7 -7
- data/.rubocop_todo.yml +83 -0
- data/README.md +1319 -235
- data/RUBY_WEEKLY_LAUNCH_POST.md +219 -0
- data/docs/RAILS_INTEGRATION_IMPLEMENTATION.md +209 -0
- data/docs/SINATRA_EXTENSION.md +399 -348
- data/docs/STRICT_VALIDATION.md +229 -0
- data/docs/VALIDATION_IMPROVEMENTS.md +218 -0
- data/docs/ai-integration-plan.md +112 -0
- data/docs/auto-derivation.md +505 -92
- data/docs/endpoint-definition.md +536 -129
- data/docs/n8n-integration.md +212 -0
- data/docs/observability.md +810 -500
- data/docs/using-mcp.md +93 -0
- data/examples/ai/knowledge_base_rag.rb +83 -0
- data/examples/ai/user_management_mcp.rb +92 -0
- data/examples/ai/user_validation_llm.rb +187 -0
- data/examples/rails/RAILS_8_GUIDE.md +165 -0
- data/examples/rails/RAILS_LOADING_FIX.rb +35 -0
- data/examples/rails/README.md +497 -0
- data/examples/rails/comprehensive_test.rb +91 -0
- data/examples/rails/config/routes.rb +48 -0
- data/examples/rails/debug_controller.rb +63 -0
- data/examples/rails/detailed_test.rb +46 -0
- data/examples/rails/enhanced_users_controller.rb +278 -0
- data/examples/rails/final_server_test.rb +50 -0
- data/examples/rails/hello_world_app.rb +116 -0
- data/examples/rails/hello_world_controller.rb +186 -0
- data/examples/rails/hello_world_routes.rb +28 -0
- data/examples/rails/rails8_minimal_demo.rb +132 -0
- data/examples/rails/rails8_simple_demo.rb +140 -0
- data/examples/rails/rails8_working_demo.rb +255 -0
- data/examples/rails/real_world_blog_api.rb +510 -0
- data/examples/rails/server_test.rb +46 -0
- data/examples/rails/test_direct_processing.rb +41 -0
- data/examples/rails/test_hello_world.rb +80 -0
- data/examples/rails/test_rails_integration.rb +54 -0
- data/examples/rails/traditional_app/Gemfile +37 -0
- data/examples/rails/traditional_app/README.md +265 -0
- data/examples/rails/traditional_app/app/controllers/api/v1/posts_controller.rb +254 -0
- data/examples/rails/traditional_app/app/controllers/api/v1/users_controller.rb +220 -0
- data/examples/rails/traditional_app/app/controllers/application_controller.rb +86 -0
- data/examples/rails/traditional_app/app/controllers/application_controller_simplified.rb +87 -0
- data/examples/rails/traditional_app/app/controllers/documentation_controller.rb +149 -0
- data/examples/rails/traditional_app/app/controllers/health_controller.rb +42 -0
- data/examples/rails/traditional_app/config/routes.rb +25 -0
- data/examples/rails/traditional_app/config/routes_best_practice.rb +25 -0
- data/examples/rails/traditional_app/config/routes_simplified.rb +36 -0
- data/examples/rails/traditional_app_runnable.rb +406 -0
- data/examples/rails/users_controller.rb +4 -1
- data/examples/serverless/Gemfile +43 -0
- data/examples/serverless/QUICKSTART.md +331 -0
- data/examples/serverless/README.md +520 -0
- data/examples/serverless/aws_lambda_example.rb +307 -0
- data/examples/serverless/aws_sam_template.yaml +215 -0
- data/examples/serverless/azure_functions_example.rb +407 -0
- data/examples/serverless/deploy.rb +204 -0
- data/examples/serverless/gcp_cloud_functions_example.rb +367 -0
- data/examples/serverless/gcp_function.yaml +23 -0
- data/examples/serverless/host.json +24 -0
- data/examples/serverless/package.json +32 -0
- data/examples/serverless/spec/aws_lambda_spec.rb +196 -0
- data/examples/serverless/spec/spec_helper.rb +89 -0
- data/examples/serverless/vercel.json +31 -0
- data/examples/serverless/vercel_example.rb +404 -0
- data/examples/strict_validation_examples.rb +104 -0
- data/examples/validation_error_examples.rb +173 -0
- data/lib/rapitapir/ai/llm_instruction.rb +456 -0
- data/lib/rapitapir/ai/mcp.rb +134 -0
- data/lib/rapitapir/ai/rag.rb +287 -0
- data/lib/rapitapir/ai/rag_middleware.rb +147 -0
- data/lib/rapitapir/auth/oauth2.rb +43 -57
- data/lib/rapitapir/cli/command.rb +362 -2
- data/lib/rapitapir/cli/mcp_export.rb +18 -0
- data/lib/rapitapir/cli/validator.rb +2 -6
- data/lib/rapitapir/core/endpoint.rb +59 -6
- data/lib/rapitapir/core/enhanced_endpoint.rb +2 -6
- data/lib/rapitapir/dsl/fluent_endpoint_builder.rb +53 -0
- data/lib/rapitapir/endpoint_registry.rb +47 -0
- data/lib/rapitapir/observability/health_check.rb +4 -4
- data/lib/rapitapir/observability/logging.rb +10 -10
- data/lib/rapitapir/schema.rb +2 -2
- data/lib/rapitapir/server/rack_adapter.rb +1 -3
- data/lib/rapitapir/server/rails/configuration.rb +77 -0
- data/lib/rapitapir/server/rails/controller_base.rb +185 -0
- data/lib/rapitapir/server/rails/documentation_helpers.rb +76 -0
- data/lib/rapitapir/server/rails/resource_builder.rb +181 -0
- data/lib/rapitapir/server/rails/routes.rb +114 -0
- data/lib/rapitapir/server/rails_adapter.rb +10 -3
- data/lib/rapitapir/server/rails_adapter_class.rb +1 -3
- data/lib/rapitapir/server/rails_controller.rb +1 -3
- data/lib/rapitapir/server/rails_integration.rb +67 -0
- data/lib/rapitapir/server/rails_response_handler.rb +16 -3
- data/lib/rapitapir/server/sinatra_adapter.rb +29 -5
- data/lib/rapitapir/server/sinatra_integration.rb +4 -4
- data/lib/rapitapir/sinatra/extension.rb +2 -2
- data/lib/rapitapir/sinatra/oauth2_helpers.rb +34 -40
- data/lib/rapitapir/types/array.rb +4 -0
- data/lib/rapitapir/types/auto_derivation.rb +4 -18
- data/lib/rapitapir/types/datetime.rb +1 -3
- data/lib/rapitapir/types/float.rb +2 -6
- data/lib/rapitapir/types/hash.rb +40 -2
- data/lib/rapitapir/types/integer.rb +4 -12
- data/lib/rapitapir/types/object.rb +6 -2
- data/lib/rapitapir/types.rb +6 -2
- data/lib/rapitapir/version.rb +1 -1
- data/lib/rapitapir.rb +5 -3
- data/rapitapir.gemspec +7 -5
- metadata +116 -16
@@ -0,0 +1,331 @@
|
|
1
|
+
# 🚀 Quick Start: Deploy RapiTapir to Serverless
|
2
|
+
|
3
|
+
This guide will get you from zero to a deployed serverless API in under 5 minutes.
|
4
|
+
|
5
|
+
## ⚡ 30-Second Deploy
|
6
|
+
|
7
|
+
1. **Choose your platform** and copy the appropriate example:
|
8
|
+
```bash
|
9
|
+
# AWS Lambda
|
10
|
+
cp aws_lambda_example.rb my_api.rb
|
11
|
+
|
12
|
+
# Google Cloud Functions
|
13
|
+
cp gcp_cloud_functions_example.rb my_api.rb
|
14
|
+
|
15
|
+
# Azure Functions
|
16
|
+
cp azure_functions_example.rb my_api.rb
|
17
|
+
|
18
|
+
# Vercel Edge
|
19
|
+
cp vercel_example.rb my_api.rb
|
20
|
+
```
|
21
|
+
|
22
|
+
2. **Deploy with one command**:
|
23
|
+
```bash
|
24
|
+
# Automated deployment
|
25
|
+
./deploy.rb --platform aws --name my-api
|
26
|
+
|
27
|
+
# Or manually for AWS
|
28
|
+
sam build && sam deploy
|
29
|
+
|
30
|
+
# Or manually for Vercel
|
31
|
+
vercel --prod
|
32
|
+
```
|
33
|
+
|
34
|
+
3. **Test your API**:
|
35
|
+
```bash
|
36
|
+
curl "https://your-function-url/health"
|
37
|
+
curl "https://your-function-url/books"
|
38
|
+
```
|
39
|
+
|
40
|
+
## 🎯 Platform Comparison
|
41
|
+
|
42
|
+
| Feature | AWS Lambda | Google Cloud Functions | Azure Functions | Vercel Edge |
|
43
|
+
|---------|------------|----------------------|-----------------|-------------|
|
44
|
+
| **Cold Start** | 200ms | 300ms | 400ms | 50ms |
|
45
|
+
| **Free Tier** | 1M requests | 2M requests | 1M requests | 100GB-h |
|
46
|
+
| **Max Memory** | 10GB | 8GB | 1.5GB | 512MB |
|
47
|
+
| **Max Duration** | 15min | 9min | 10min | 30s |
|
48
|
+
| **Best For** | Enterprise | AI/ML | Microsoft stack | Frontend |
|
49
|
+
|
50
|
+
## 🔧 Customization Examples
|
51
|
+
|
52
|
+
### Add Authentication
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
class SecureServerlessAPI < SinatraRapiTapir
|
56
|
+
rapitapir do
|
57
|
+
info(title: 'Secure API', version: '1.0.0')
|
58
|
+
bearer_auth :jwt
|
59
|
+
end
|
60
|
+
|
61
|
+
endpoint(
|
62
|
+
GET('/protected')
|
63
|
+
.bearer_auth(scopes: ['api:read'])
|
64
|
+
.ok(T.hash({ "data" => T.string }))
|
65
|
+
.build
|
66
|
+
) { { data: "Secret information" } }
|
67
|
+
end
|
68
|
+
```
|
69
|
+
|
70
|
+
### Add Database Integration
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
# AWS with DynamoDB
|
74
|
+
endpoint(GET('/users/:id').build) do |inputs|
|
75
|
+
dynamodb.get_item(
|
76
|
+
table_name: 'users',
|
77
|
+
key: { id: inputs[:id] }
|
78
|
+
).item
|
79
|
+
end
|
80
|
+
|
81
|
+
# GCP with Firestore
|
82
|
+
endpoint(GET('/users/:id').build) do |inputs|
|
83
|
+
firestore = Google::Cloud::Firestore.new
|
84
|
+
doc = firestore.doc("users/#{inputs[:id]}").get
|
85
|
+
doc.data
|
86
|
+
end
|
87
|
+
```
|
88
|
+
|
89
|
+
### Add AI Features
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
endpoint(
|
93
|
+
POST('/ai/analyze')
|
94
|
+
.body(T.hash({ "text" => T.string }))
|
95
|
+
.enable_llm_instructions(purpose: :analysis)
|
96
|
+
.enable_rag
|
97
|
+
.build
|
98
|
+
) do |inputs|
|
99
|
+
# AI-powered text analysis
|
100
|
+
result = AI.analyze(inputs[:body][:text], context: rag_context)
|
101
|
+
{ analysis: result }
|
102
|
+
end
|
103
|
+
```
|
104
|
+
|
105
|
+
## 🛠️ Development Workflow
|
106
|
+
|
107
|
+
### 1. Local Development
|
108
|
+
|
109
|
+
```bash
|
110
|
+
# Install dependencies
|
111
|
+
bundle install
|
112
|
+
|
113
|
+
# Run locally
|
114
|
+
ruby aws_lambda_example.rb
|
115
|
+
# or
|
116
|
+
functions-framework-ruby --target=rapitapir_book_api
|
117
|
+
# or
|
118
|
+
func start
|
119
|
+
# or
|
120
|
+
vercel dev
|
121
|
+
```
|
122
|
+
|
123
|
+
### 2. Testing
|
124
|
+
|
125
|
+
```bash
|
126
|
+
# Run tests
|
127
|
+
bundle exec rspec
|
128
|
+
|
129
|
+
# Test specific platform
|
130
|
+
bundle exec rspec spec/aws_lambda_spec.rb
|
131
|
+
```
|
132
|
+
|
133
|
+
### 3. Deployment
|
134
|
+
|
135
|
+
```bash
|
136
|
+
# Deploy to specific platform
|
137
|
+
./deploy.rb --platform vercel --name my-api
|
138
|
+
|
139
|
+
# Deploy to all platforms
|
140
|
+
./deploy.rb --platform all --name my-api
|
141
|
+
|
142
|
+
# Dry run (see commands without executing)
|
143
|
+
./deploy.rb --platform aws --dry-run
|
144
|
+
```
|
145
|
+
|
146
|
+
## 📊 Monitoring & Debugging
|
147
|
+
|
148
|
+
### Platform-Specific Monitoring
|
149
|
+
|
150
|
+
**AWS Lambda:**
|
151
|
+
```bash
|
152
|
+
# View logs
|
153
|
+
aws logs tail /aws/lambda/my-function --follow
|
154
|
+
|
155
|
+
# View metrics
|
156
|
+
aws cloudwatch get-metric-statistics --namespace AWS/Lambda
|
157
|
+
```
|
158
|
+
|
159
|
+
**Google Cloud Functions:**
|
160
|
+
```bash
|
161
|
+
# View logs
|
162
|
+
gcloud functions logs read my-function --limit 50
|
163
|
+
|
164
|
+
# View metrics
|
165
|
+
gcloud logging read "resource.type=cloud_function"
|
166
|
+
```
|
167
|
+
|
168
|
+
**Azure Functions:**
|
169
|
+
```bash
|
170
|
+
# View logs
|
171
|
+
func azure functionapp logstream my-function-app
|
172
|
+
|
173
|
+
# View in portal
|
174
|
+
az functionapp show --name my-function-app
|
175
|
+
```
|
176
|
+
|
177
|
+
**Vercel:**
|
178
|
+
```bash
|
179
|
+
# View logs
|
180
|
+
vercel logs my-deployment-url
|
181
|
+
|
182
|
+
# View analytics
|
183
|
+
vercel inspect my-deployment-url
|
184
|
+
```
|
185
|
+
|
186
|
+
## 🔒 Security Best Practices
|
187
|
+
|
188
|
+
### Environment Variables
|
189
|
+
|
190
|
+
```bash
|
191
|
+
# AWS
|
192
|
+
aws lambda update-function-configuration \
|
193
|
+
--function-name my-function \
|
194
|
+
--environment Variables='{API_KEY=secret}'
|
195
|
+
|
196
|
+
# GCP
|
197
|
+
gcloud functions deploy my-function \
|
198
|
+
--set-env-vars API_KEY=secret
|
199
|
+
|
200
|
+
# Azure
|
201
|
+
az functionapp config appsettings set \
|
202
|
+
--name my-function-app \
|
203
|
+
--settings API_KEY=secret
|
204
|
+
|
205
|
+
# Vercel
|
206
|
+
vercel env add API_KEY
|
207
|
+
```
|
208
|
+
|
209
|
+
### Input Validation
|
210
|
+
|
211
|
+
```ruby
|
212
|
+
# RapiTapir provides automatic validation
|
213
|
+
endpoint(
|
214
|
+
POST('/users')
|
215
|
+
.body(T.hash({
|
216
|
+
"email" => T.email, # Validates email format
|
217
|
+
"age" => T.integer(minimum: 18), # Validates age >= 18
|
218
|
+
"name" => T.string(min_length: 2) # Validates min length
|
219
|
+
}))
|
220
|
+
.build
|
221
|
+
) do |inputs|
|
222
|
+
# inputs[:body] is guaranteed to be valid
|
223
|
+
User.create(inputs[:body])
|
224
|
+
end
|
225
|
+
```
|
226
|
+
|
227
|
+
## 🎭 Common Patterns
|
228
|
+
|
229
|
+
### Pattern 1: API Gateway
|
230
|
+
|
231
|
+
Single function handling multiple endpoints (recommended for most use cases):
|
232
|
+
|
233
|
+
```
|
234
|
+
Function: my-api
|
235
|
+
├── GET /health
|
236
|
+
├── GET /books
|
237
|
+
├── POST /books
|
238
|
+
└── GET /books/:id
|
239
|
+
```
|
240
|
+
|
241
|
+
### Pattern 2: Microservices
|
242
|
+
|
243
|
+
Separate functions for different domains:
|
244
|
+
|
245
|
+
```
|
246
|
+
Function: users-api → /api/users/*
|
247
|
+
Function: books-api → /api/books/*
|
248
|
+
Function: orders-api → /api/orders/*
|
249
|
+
```
|
250
|
+
|
251
|
+
### Pattern 3: Edge + Origin
|
252
|
+
|
253
|
+
Fast edge responses with backend fallback:
|
254
|
+
|
255
|
+
```
|
256
|
+
Edge (Vercel) → Fast reads, cached data
|
257
|
+
Origin (AWS) → Complex operations, database writes
|
258
|
+
```
|
259
|
+
|
260
|
+
## 🚨 Troubleshooting
|
261
|
+
|
262
|
+
### Common Issues
|
263
|
+
|
264
|
+
**Cold Start Too Slow:**
|
265
|
+
```ruby
|
266
|
+
# Use smaller dependencies
|
267
|
+
gem 'rapitapir', require: ['rapitapir/core'] # Only core features
|
268
|
+
|
269
|
+
# Pre-warm connections
|
270
|
+
configure do
|
271
|
+
database_pool = ConnectionPool.new { Database.connect }
|
272
|
+
set :database, database_pool
|
273
|
+
end
|
274
|
+
```
|
275
|
+
|
276
|
+
**Memory Limit Exceeded:**
|
277
|
+
```ruby
|
278
|
+
# Optimize memory usage
|
279
|
+
configure do
|
280
|
+
set :static, false # Disable static files
|
281
|
+
set :sessions, false # Disable sessions
|
282
|
+
end
|
283
|
+
|
284
|
+
# Use streaming for large responses
|
285
|
+
endpoint(GET('/large-data').build) do
|
286
|
+
stream do |out|
|
287
|
+
LargeDataset.find_each { |record| out << record.to_json + "\n" }
|
288
|
+
end
|
289
|
+
end
|
290
|
+
```
|
291
|
+
|
292
|
+
**Timeout Errors:**
|
293
|
+
```ruby
|
294
|
+
# Set appropriate timeouts
|
295
|
+
endpoint(GET('/slow-operation').build) do
|
296
|
+
# Use async processing for long operations
|
297
|
+
job_id = SlowJobService.enqueue(params)
|
298
|
+
{ job_id: job_id, status: 'processing' }
|
299
|
+
end
|
300
|
+
```
|
301
|
+
|
302
|
+
### Debug Mode
|
303
|
+
|
304
|
+
```ruby
|
305
|
+
class DebugServerlessAPI < SinatraRapiTapir
|
306
|
+
configure do
|
307
|
+
set :logging, true
|
308
|
+
set :show_exceptions, true if development?
|
309
|
+
end
|
310
|
+
|
311
|
+
before do
|
312
|
+
logger.info "Request: #{request.request_method} #{request.path_info}"
|
313
|
+
logger.info "Headers: #{request.env.select { |k,v| k.start_with?('HTTP_') }}"
|
314
|
+
end
|
315
|
+
end
|
316
|
+
```
|
317
|
+
|
318
|
+
## 🎉 You're Ready!
|
319
|
+
|
320
|
+
You now have everything you need to deploy production-ready RapiTapir APIs to any serverless platform. Choose your platform, customize the example, and deploy with confidence!
|
321
|
+
|
322
|
+
### Next Steps
|
323
|
+
|
324
|
+
1. **Explore the examples** in this directory
|
325
|
+
2. **Read the [comprehensive README](README.md)** for advanced features
|
326
|
+
3. **Check out [RapiTapir docs](../../README.md)** for the full DSL reference
|
327
|
+
4. **Join the community** and share your serverless APIs!
|
328
|
+
|
329
|
+
---
|
330
|
+
|
331
|
+
**Happy deploying! 🚀**
|