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,132 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Minimal Rails 8 + RapiTapir example
|
4
|
+
# This demonstrates the proper loading order and setup
|
5
|
+
|
6
|
+
require 'bundler/inline'
|
7
|
+
|
8
|
+
gemfile do
|
9
|
+
source 'https://rubygems.org'
|
10
|
+
gem 'rails', '~> 8.0'
|
11
|
+
gem 'sqlite3'
|
12
|
+
gem 'puma'
|
13
|
+
gem 'webrick' # Required for WEBrick server
|
14
|
+
end
|
15
|
+
|
16
|
+
# Load Rails first (this is crucial!)
|
17
|
+
require 'rails/all'
|
18
|
+
|
19
|
+
# Now load RapiTapir (this will work because Rails is loaded)
|
20
|
+
require_relative '../../lib/rapitapir'
|
21
|
+
|
22
|
+
# Rails 8 Application Setup
|
23
|
+
class Rails8Demo < Rails::Application
|
24
|
+
config.load_defaults 8.0
|
25
|
+
config.api_only = true
|
26
|
+
config.eager_load = false
|
27
|
+
config.logger = Logger.new(STDOUT)
|
28
|
+
config.log_level = :info
|
29
|
+
config.secret_key_base = 'rails8_demo_secret_key'
|
30
|
+
end
|
31
|
+
|
32
|
+
Rails.application.initialize!
|
33
|
+
|
34
|
+
# Simple in-memory data for demo
|
35
|
+
USERS = [
|
36
|
+
{ id: 1, name: "Alice Johnson", email: "alice@example.com" },
|
37
|
+
{ id: 2, name: "Bob Smith", email: "bob@example.com" }
|
38
|
+
].freeze
|
39
|
+
|
40
|
+
# ApplicationController with RapiTapir
|
41
|
+
class ApplicationController < RapiTapir::Server::Rails::ControllerBase
|
42
|
+
rapitapir do
|
43
|
+
development_defaults!
|
44
|
+
|
45
|
+
# Health endpoint
|
46
|
+
GET('/health')
|
47
|
+
.out(json_body(
|
48
|
+
status: T.string,
|
49
|
+
timestamp: T.string,
|
50
|
+
rails_version: T.string,
|
51
|
+
ruby_version: T.string
|
52
|
+
))
|
53
|
+
.summary("System health check")
|
54
|
+
.tag("System")
|
55
|
+
end
|
56
|
+
|
57
|
+
def health_check
|
58
|
+
render json: {
|
59
|
+
status: 'ok',
|
60
|
+
timestamp: Time.current.iso8601,
|
61
|
+
rails_version: Rails.version,
|
62
|
+
ruby_version: RUBY_VERSION
|
63
|
+
}
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# Users API Controller
|
68
|
+
class UsersController < ApplicationController
|
69
|
+
rapitapir do
|
70
|
+
user_type = T.hash(
|
71
|
+
id: T.integer,
|
72
|
+
name: T.string,
|
73
|
+
email: T.string
|
74
|
+
)
|
75
|
+
|
76
|
+
GET('/users')
|
77
|
+
.out(json_body(users: T.array(user_type)))
|
78
|
+
.summary("List all users")
|
79
|
+
.description("Get a list of all users in the system")
|
80
|
+
.tag("Users")
|
81
|
+
|
82
|
+
GET('/users/:id')
|
83
|
+
.in(path(:id, T.integer))
|
84
|
+
.out(json_body(user: user_type))
|
85
|
+
.error_out(json_body(error: T.string), 404)
|
86
|
+
.summary("Get user by ID")
|
87
|
+
.tag("Users")
|
88
|
+
end
|
89
|
+
|
90
|
+
def list_users
|
91
|
+
render json: { users: USERS }
|
92
|
+
end
|
93
|
+
|
94
|
+
def get_user
|
95
|
+
user = USERS.find { |u| u[:id] == params[:id].to_i }
|
96
|
+
|
97
|
+
if user
|
98
|
+
render json: { user: user }
|
99
|
+
else
|
100
|
+
render json: { error: "User not found" }, status: 404
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# Routes
|
106
|
+
Rails.application.routes.draw do
|
107
|
+
rapitapir_routes_for ApplicationController
|
108
|
+
rapitapir_routes_for UsersController
|
109
|
+
end
|
110
|
+
|
111
|
+
# Start server
|
112
|
+
if __FILE__ == $0
|
113
|
+
puts "๐ Rails 8 + RapiTapir Demo starting on http://localhost:3000"
|
114
|
+
puts "๐ Rails Version: #{Rails.version}"
|
115
|
+
puts "๐ Ruby Version: #{RUBY_VERSION}"
|
116
|
+
puts ""
|
117
|
+
puts "๐ Available endpoints:"
|
118
|
+
puts " GET /health - Health check"
|
119
|
+
puts " GET /users - List users"
|
120
|
+
puts " GET /users/1 - Get specific user"
|
121
|
+
puts " GET /docs - Swagger UI documentation"
|
122
|
+
puts " GET /openapi.json - OpenAPI specification"
|
123
|
+
puts ""
|
124
|
+
puts "๐งช Test commands:"
|
125
|
+
puts " curl http://localhost:3000/health"
|
126
|
+
puts " curl http://localhost:3000/users"
|
127
|
+
puts " curl http://localhost:3000/users/1"
|
128
|
+
puts ""
|
129
|
+
|
130
|
+
require 'rack'
|
131
|
+
Rack::Handler::WEBrick.run(Rails.application, Port: 3000)
|
132
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Simple Rails 8 + RapiTapir example using system Rails
|
4
|
+
# Note: Requires Rails 8 to be installed: gem install rails
|
5
|
+
|
6
|
+
puts "๐ Loading Rails and RapiTapir..."
|
7
|
+
|
8
|
+
# Load Rails first (this is crucial!)
|
9
|
+
require 'rails/all'
|
10
|
+
|
11
|
+
# Now load RapiTapir (this will work because Rails is loaded)
|
12
|
+
require_relative '../../lib/rapitapir'
|
13
|
+
|
14
|
+
puts "โ
Libraries loaded successfully"
|
15
|
+
|
16
|
+
# Rails 8 Application Setup
|
17
|
+
class Rails8Demo < Rails::Application
|
18
|
+
config.load_defaults 8.0
|
19
|
+
config.api_only = true
|
20
|
+
config.eager_load = false
|
21
|
+
config.logger = Logger.new(STDOUT)
|
22
|
+
config.log_level = :info
|
23
|
+
config.secret_key_base = 'rails8_demo_secret_key'
|
24
|
+
end
|
25
|
+
|
26
|
+
puts "๐๏ธ Initializing Rails application..."
|
27
|
+
Rails.application.initialize!
|
28
|
+
puts "โ
Rails application initialized"
|
29
|
+
|
30
|
+
# Simple in-memory data for demo
|
31
|
+
USERS = [
|
32
|
+
{ id: 1, name: "Alice Johnson", email: "alice@example.com" },
|
33
|
+
{ id: 2, name: "Bob Smith", email: "bob@example.com" }
|
34
|
+
].freeze
|
35
|
+
|
36
|
+
# ApplicationController with RapiTapir
|
37
|
+
class ApplicationController < RapiTapir::Server::Rails::ControllerBase
|
38
|
+
rapitapir do
|
39
|
+
development_defaults!
|
40
|
+
|
41
|
+
# Health endpoint
|
42
|
+
GET('/health')
|
43
|
+
.out(json_body(
|
44
|
+
status: T.string,
|
45
|
+
timestamp: T.string,
|
46
|
+
rails_version: T.string,
|
47
|
+
ruby_version: T.string
|
48
|
+
))
|
49
|
+
.summary("System health check")
|
50
|
+
.tag("System")
|
51
|
+
end
|
52
|
+
|
53
|
+
def health_check
|
54
|
+
render json: {
|
55
|
+
status: 'ok',
|
56
|
+
timestamp: Time.current.iso8601,
|
57
|
+
rails_version: Rails.version,
|
58
|
+
ruby_version: RUBY_VERSION
|
59
|
+
}
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
puts "โ
ApplicationController defined"
|
64
|
+
|
65
|
+
# Users API Controller
|
66
|
+
class UsersController < ApplicationController
|
67
|
+
rapitapir do
|
68
|
+
user_type = T.hash(
|
69
|
+
id: T.integer,
|
70
|
+
name: T.string,
|
71
|
+
email: T.string
|
72
|
+
)
|
73
|
+
|
74
|
+
GET('/users')
|
75
|
+
.out(json_body(users: T.array(user_type)))
|
76
|
+
.summary("List all users")
|
77
|
+
.description("Get a list of all users in the system")
|
78
|
+
.tag("Users")
|
79
|
+
|
80
|
+
GET('/users/:id')
|
81
|
+
.in(path(:id, T.integer))
|
82
|
+
.out(json_body(user: user_type))
|
83
|
+
.error_out(json_body(error: T.string), 404)
|
84
|
+
.summary("Get user by ID")
|
85
|
+
.tag("Users")
|
86
|
+
end
|
87
|
+
|
88
|
+
def list_users
|
89
|
+
render json: { users: USERS }
|
90
|
+
end
|
91
|
+
|
92
|
+
def get_user
|
93
|
+
user = USERS.find { |u| u[:id] == params[:id].to_i }
|
94
|
+
|
95
|
+
if user
|
96
|
+
render json: { user: user }
|
97
|
+
else
|
98
|
+
render json: { error: "User not found" }, status: 404
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
puts "โ
UsersController defined"
|
104
|
+
|
105
|
+
# Routes
|
106
|
+
Rails.application.routes.draw do
|
107
|
+
rapitapir_routes_for ApplicationController
|
108
|
+
rapitapir_routes_for UsersController
|
109
|
+
end
|
110
|
+
|
111
|
+
puts "โ
Routes configured"
|
112
|
+
|
113
|
+
# Start server
|
114
|
+
if __FILE__ == $0
|
115
|
+
puts ""
|
116
|
+
puts "๐ Rails 8 + RapiTapir Demo starting on http://localhost:3000"
|
117
|
+
puts "๐ Rails Version: #{Rails.version}"
|
118
|
+
puts "๐ Ruby Version: #{RUBY_VERSION}"
|
119
|
+
puts ""
|
120
|
+
puts "๐ Available endpoints:"
|
121
|
+
puts " GET /health - Health check"
|
122
|
+
puts " GET /users - List users"
|
123
|
+
puts " GET /users/1 - Get specific user"
|
124
|
+
puts " GET /docs - Swagger UI documentation"
|
125
|
+
puts " GET /openapi.json - OpenAPI specification"
|
126
|
+
puts ""
|
127
|
+
puts "๐งช Test commands:"
|
128
|
+
puts " curl http://localhost:3000/health"
|
129
|
+
puts " curl http://localhost:3000/users"
|
130
|
+
puts " curl http://localhost:3000/users/1"
|
131
|
+
puts ""
|
132
|
+
|
133
|
+
begin
|
134
|
+
require 'webrick'
|
135
|
+
Rack::Handler::WEBrick.run(Rails.application, Port: 3000)
|
136
|
+
rescue LoadError
|
137
|
+
puts "โ WEBrick not available. Install with: gem install webrick"
|
138
|
+
puts "Or use another server like Puma"
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,255 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Working Rails 8 + RapiTapir example
|
4
|
+
# This uses only the core RapiTapir features that are known to work
|
5
|
+
|
6
|
+
puts "๐ Starting Rails 8 + RapiTapir Demo..."
|
7
|
+
|
8
|
+
# Check if Rails is available
|
9
|
+
begin
|
10
|
+
require 'rails/all'
|
11
|
+
puts "โ
Rails #{Rails::VERSION::STRING} loaded"
|
12
|
+
rescue LoadError => e
|
13
|
+
puts "โ Rails not available: #{e.message}"
|
14
|
+
puts ""
|
15
|
+
puts "To run this demo, install Rails 8:"
|
16
|
+
puts " gem install rails"
|
17
|
+
puts ""
|
18
|
+
exit 1
|
19
|
+
end
|
20
|
+
|
21
|
+
# Load RapiTapir
|
22
|
+
begin
|
23
|
+
require_relative '../../lib/rapitapir'
|
24
|
+
puts "โ
RapiTapir loaded"
|
25
|
+
rescue LoadError => e
|
26
|
+
puts "โ RapiTapir not available: #{e.message}"
|
27
|
+
exit 1
|
28
|
+
end
|
29
|
+
|
30
|
+
# Create Rails application
|
31
|
+
puts "๐๏ธ Setting up Rails application..."
|
32
|
+
|
33
|
+
class Rails8DemoApp < Rails::Application
|
34
|
+
config.load_defaults 8.0
|
35
|
+
config.api_only = true
|
36
|
+
config.eager_load = false
|
37
|
+
config.secret_key_base = 'rails8_demo_secret_key_for_rapitapir_integration'
|
38
|
+
config.log_level = :info
|
39
|
+
config.logger = Logger.new(STDOUT)
|
40
|
+
end
|
41
|
+
|
42
|
+
Rails.application.initialize!
|
43
|
+
puts "โ
Rails application initialized"
|
44
|
+
|
45
|
+
# Sample data
|
46
|
+
DEMO_USERS = [
|
47
|
+
{ id: 1, name: "Alice Johnson", email: "alice@example.com" },
|
48
|
+
{ id: 2, name: "Bob Smith", email: "bob@example.com" }
|
49
|
+
].freeze
|
50
|
+
|
51
|
+
# Define endpoints using standard RapiTapir DSL (not Rails integration)
|
52
|
+
puts "๐ Defining API endpoints..."
|
53
|
+
|
54
|
+
# Health check endpoint
|
55
|
+
HEALTH_ENDPOINT = RapiTapir.get('/health')
|
56
|
+
.out(status_code(200))
|
57
|
+
.out(json_body({
|
58
|
+
status: :string,
|
59
|
+
timestamp: :string,
|
60
|
+
rails_version: :string,
|
61
|
+
ruby_version: :string
|
62
|
+
}))
|
63
|
+
.summary("Health check")
|
64
|
+
.description("Check if the API is running")
|
65
|
+
.tag("System")
|
66
|
+
|
67
|
+
# List users endpoint
|
68
|
+
LIST_USERS_ENDPOINT = RapiTapir.get('/users')
|
69
|
+
.out(status_code(200))
|
70
|
+
.out(json_body({
|
71
|
+
users: [{
|
72
|
+
id: :integer,
|
73
|
+
name: :string,
|
74
|
+
email: :string
|
75
|
+
}]
|
76
|
+
}))
|
77
|
+
.summary("List users")
|
78
|
+
.description("Get all users")
|
79
|
+
.tag("Users")
|
80
|
+
|
81
|
+
# Get user endpoint
|
82
|
+
GET_USER_ENDPOINT = RapiTapir.get('/users/:id')
|
83
|
+
.in(path_param(:id, :integer))
|
84
|
+
.out(status_code(200))
|
85
|
+
.out(json_body({
|
86
|
+
user: {
|
87
|
+
id: :integer,
|
88
|
+
name: :string,
|
89
|
+
email: :string
|
90
|
+
}
|
91
|
+
}))
|
92
|
+
.error_out(404, json_body({ error: :string }))
|
93
|
+
.summary("Get user")
|
94
|
+
.description("Get a specific user by ID")
|
95
|
+
.tag("Users")
|
96
|
+
|
97
|
+
puts "โ
Endpoints defined"
|
98
|
+
|
99
|
+
# Create a standard Rails controller (not using RapiTapir Rails integration)
|
100
|
+
puts "๐ฎ Creating Rails controllers..."
|
101
|
+
|
102
|
+
class ApplicationController < ActionController::API
|
103
|
+
def health_check
|
104
|
+
render json: {
|
105
|
+
status: 'ok',
|
106
|
+
timestamp: Time.current.iso8601,
|
107
|
+
rails_version: Rails.version,
|
108
|
+
ruby_version: RUBY_VERSION
|
109
|
+
}
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
class UsersController < ApplicationController
|
114
|
+
def index
|
115
|
+
render json: { users: DEMO_USERS }
|
116
|
+
end
|
117
|
+
|
118
|
+
def show
|
119
|
+
user = DEMO_USERS.find { |u| u[:id] == params[:id].to_i }
|
120
|
+
|
121
|
+
if user
|
122
|
+
render json: { user: user }
|
123
|
+
else
|
124
|
+
render json: { error: "User not found" }, status: 404
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
puts "โ
Controllers created"
|
130
|
+
|
131
|
+
# Set up routes
|
132
|
+
puts "๐ฃ๏ธ Setting up routes..."
|
133
|
+
|
134
|
+
Rails.application.routes.draw do
|
135
|
+
get '/health', to: 'application#health_check'
|
136
|
+
get '/users', to: 'users#index'
|
137
|
+
get '/users/:id', to: 'users#show'
|
138
|
+
|
139
|
+
# Documentation routes (manual for now)
|
140
|
+
get '/docs', to: proc { |env|
|
141
|
+
[200, { 'Content-Type' => 'text/html' }, [<<~HTML
|
142
|
+
<!DOCTYPE html>
|
143
|
+
<html>
|
144
|
+
<head>
|
145
|
+
<title>Rails 8 + RapiTapir Demo API</title>
|
146
|
+
<style>
|
147
|
+
body { font-family: Arial, sans-serif; margin: 40px; }
|
148
|
+
h1 { color: #333; }
|
149
|
+
.endpoint { background: #f5f5f5; padding: 15px; margin: 10px 0; border-radius: 5px; }
|
150
|
+
.method { font-weight: bold; color: #007bff; }
|
151
|
+
.path { font-family: monospace; background: #eee; padding: 2px 4px; }
|
152
|
+
pre { background: #f8f9fa; padding: 10px; border-radius: 3px; overflow-x: auto; }
|
153
|
+
</style>
|
154
|
+
</head>
|
155
|
+
<body>
|
156
|
+
<h1>Rails 8 + RapiTapir Demo API</h1>
|
157
|
+
<p>This is a working demonstration of RapiTapir with Rails 8.</p>
|
158
|
+
|
159
|
+
<h2>Available Endpoints</h2>
|
160
|
+
|
161
|
+
<div class="endpoint">
|
162
|
+
<h3><span class="method">GET</span> <span class="path">/health</span></h3>
|
163
|
+
<p>Health check endpoint</p>
|
164
|
+
<h4>Example Response:</h4>
|
165
|
+
<pre>{"status":"ok","timestamp":"2025-08-06T10:30:00Z","rails_version":"8.0.2","ruby_version":"3.3.4"}</pre>
|
166
|
+
</div>
|
167
|
+
|
168
|
+
<div class="endpoint">
|
169
|
+
<h3><span class="method">GET</span> <span class="path">/users</span></h3>
|
170
|
+
<p>List all users</p>
|
171
|
+
<h4>Example Response:</h4>
|
172
|
+
<pre>{"users":[{"id":1,"name":"Alice Johnson","email":"alice@example.com"},{"id":2,"name":"Bob Smith","email":"bob@example.com"}]}</pre>
|
173
|
+
</div>
|
174
|
+
|
175
|
+
<div class="endpoint">
|
176
|
+
<h3><span class="method">GET</span> <span class="path">/users/:id</span></h3>
|
177
|
+
<p>Get a specific user by ID</p>
|
178
|
+
<h4>Example Response:</h4>
|
179
|
+
<pre>{"user":{"id":1,"name":"Alice Johnson","email":"alice@example.com"}}</pre>
|
180
|
+
<h4>Error Response (404):</h4>
|
181
|
+
<pre>{"error":"User not found"}</pre>
|
182
|
+
</div>
|
183
|
+
|
184
|
+
<h2>Test Commands</h2>
|
185
|
+
<pre>
|
186
|
+
curl http://localhost:3000/health
|
187
|
+
curl http://localhost:3000/users
|
188
|
+
curl http://localhost:3000/users/1
|
189
|
+
curl http://localhost:3000/users/999
|
190
|
+
</pre>
|
191
|
+
|
192
|
+
<h2>About</h2>
|
193
|
+
<p>This demo shows Rails 8 working with RapiTapir endpoints defined using the standard DSL.</p>
|
194
|
+
<p>While this example doesn't use the Rails integration features (which are still in development),
|
195
|
+
it demonstrates that RapiTapir and Rails 8 can work together successfully.</p>
|
196
|
+
</body>
|
197
|
+
</html>
|
198
|
+
HTML
|
199
|
+
]]
|
200
|
+
}
|
201
|
+
end
|
202
|
+
|
203
|
+
puts "โ
Routes configured"
|
204
|
+
|
205
|
+
# Register endpoints with RapiTapir (for documentation generation)
|
206
|
+
puts "๐ Registering endpoints with RapiTapir..."
|
207
|
+
|
208
|
+
RapiTapir.register_endpoint(HEALTH_ENDPOINT)
|
209
|
+
RapiTapir.register_endpoint(LIST_USERS_ENDPOINT)
|
210
|
+
RapiTapir.register_endpoint(GET_USER_ENDPOINT)
|
211
|
+
|
212
|
+
puts "โ
Endpoints registered"
|
213
|
+
|
214
|
+
# Start the server
|
215
|
+
if __FILE__ == $0
|
216
|
+
puts ""
|
217
|
+
puts "๐ Rails 8 + RapiTapir Demo is ready!"
|
218
|
+
puts ""
|
219
|
+
puts "๐ System Info:"
|
220
|
+
puts " Rails Version: #{Rails.version}"
|
221
|
+
puts " Ruby Version: #{RUBY_VERSION}"
|
222
|
+
puts " RapiTapir: โ
Loaded"
|
223
|
+
puts ""
|
224
|
+
puts "๐ Available endpoints:"
|
225
|
+
puts " GET /health - Health check"
|
226
|
+
puts " GET /users - List all users"
|
227
|
+
puts " GET /users/:id - Get specific user"
|
228
|
+
puts " GET /docs - API documentation"
|
229
|
+
puts ""
|
230
|
+
puts "๐งช Test commands:"
|
231
|
+
puts " curl http://localhost:3000/health"
|
232
|
+
puts " curl http://localhost:3000/users"
|
233
|
+
puts " curl http://localhost:3000/users/1"
|
234
|
+
puts ""
|
235
|
+
puts "Starting server on http://localhost:3000..."
|
236
|
+
puts ""
|
237
|
+
|
238
|
+
begin
|
239
|
+
require 'webrick'
|
240
|
+
puts "Using WEBrick server..."
|
241
|
+
Rack::Handler::WEBrick.run(Rails.application, Port: 3000, Host: '0.0.0.0')
|
242
|
+
rescue LoadError
|
243
|
+
puts "WEBrick not available. Trying Puma..."
|
244
|
+
begin
|
245
|
+
require 'puma'
|
246
|
+
puts "Using Puma server..."
|
247
|
+
Rack::Handler::Puma.run(Rails.application, Port: 3000, Host: '0.0.0.0')
|
248
|
+
rescue LoadError
|
249
|
+
puts "โ No web server available. Install webrick or puma:"
|
250
|
+
puts " gem install webrick"
|
251
|
+
puts " gem install puma"
|
252
|
+
exit 1
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|