rapitapir 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.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +57 -0
- data/CHANGELOG.md +94 -0
- data/CLEANUP_SUMMARY.md +155 -0
- data/CONTRIBUTING.md +280 -0
- data/LICENSE +21 -0
- data/README.md +485 -0
- data/debug_hash.rb +20 -0
- data/docs/EXTENSION_COMPARISON.md +388 -0
- data/docs/SINATRA_EXTENSION.md +467 -0
- data/docs/archive/PHASE_1_2_COMPLETE.md +77 -0
- data/docs/archive/PHASE_1_3_COMPLETE.md +152 -0
- data/docs/archive/PHASE_2_1_OBSERVABILITY_COMPLETED.md +203 -0
- data/docs/archive/PHASE_2_SUMMARY.md +209 -0
- data/docs/archive/REFACTORING_SUMMARY.md +184 -0
- data/docs/archive/phase_1_3_plan.md +136 -0
- data/docs/archive/sinatra_extension_summary.md +188 -0
- data/docs/archive/sinatra_working_solution.md +113 -0
- data/docs/archive/typescript-client-generator-summary.md +259 -0
- data/docs/auto-derivation.md +146 -0
- data/docs/blueprint.md +1091 -0
- data/docs/endpoint-definition.md +211 -0
- data/docs/github_pages_fix.md +52 -0
- data/docs/github_pages_setup.md +49 -0
- data/docs/implementation-status.md +357 -0
- data/docs/observability.md +647 -0
- data/docs/phase3-plan.md +108 -0
- data/docs/sinatra_rapitapir.md +87 -0
- data/docs/type_shortcuts.md +146 -0
- data/examples/README_ENTERPRISE.md +202 -0
- data/examples/authentication_example.rb +192 -0
- data/examples/auto_derivation_ruby_friendly.rb +163 -0
- data/examples/cli/user_api_endpoints.rb +56 -0
- data/examples/client/typescript_client_example.rb +102 -0
- data/examples/client/user-api-client.ts +193 -0
- data/examples/demo_api.rb +41 -0
- data/examples/docs/documentation_example.rb +112 -0
- data/examples/docs/user-api-docs.html +789 -0
- data/examples/docs/user-api-docs.md +403 -0
- data/examples/enhanced_auto_derivation_test.rb +83 -0
- data/examples/enterprise_extension_demo.rb +417 -0
- data/examples/enterprise_rapitapir_api.rb +662 -0
- data/examples/getting_started_extension.rb +218 -0
- data/examples/hello_world.rb +74 -0
- data/examples/oauth2/.env.example +19 -0
- data/examples/oauth2/README.md +205 -0
- data/examples/oauth2/generic_oauth2_api.rb +226 -0
- data/examples/oauth2/get_token.rb +72 -0
- data/examples/oauth2/songs_api_with_auth0.rb +320 -0
- data/examples/oauth2/test_api.sh +16 -0
- data/examples/oauth2/test_songs_api.sh +110 -0
- data/examples/observability/.env.example +35 -0
- data/examples/observability/README.md +230 -0
- data/examples/observability/README_HONEYCOMB.md +332 -0
- data/examples/observability/advanced_setup.rb +384 -0
- data/examples/observability/basic_setup.rb +192 -0
- data/examples/observability/complete_test.rb +121 -0
- data/examples/observability/honeycomb_example.rb +523 -0
- data/examples/observability/honeycomb_rapitapir_clean.rb +488 -0
- data/examples/observability/honeycomb_rapitapir_example.rb +523 -0
- data/examples/observability/honeycomb_working_example.rb +489 -0
- data/examples/observability/quick_test.rb +78 -0
- data/examples/observability/simple_test.rb +14 -0
- data/examples/observability/test_honeycomb_demo.rb +354 -0
- data/examples/observability/test_live_honeycomb.rb +111 -0
- data/examples/observability/test_validation.rb +78 -0
- data/examples/observability/test_working_validation.rb +66 -0
- data/examples/openapi/user_api_schema.rb +132 -0
- data/examples/production_ready_example.rb +105 -0
- data/examples/rails/users_controller.rb +146 -0
- data/examples/readme/basic_sinatra_example.rb +128 -0
- data/examples/server/user_api.rb +179 -0
- data/examples/simple_auto_derivation_demo.rb +44 -0
- data/examples/simple_demo_api.rb +18 -0
- data/examples/sinatra/user_app.rb +127 -0
- data/examples/t_shortcut_demo.rb +59 -0
- data/examples/user_api.rb +190 -0
- data/examples/working_getting_started.rb +184 -0
- data/examples/working_simple_example.rb +195 -0
- data/lib/rapitapir/auth/configuration.rb +129 -0
- data/lib/rapitapir/auth/context.rb +122 -0
- data/lib/rapitapir/auth/errors.rb +104 -0
- data/lib/rapitapir/auth/middleware.rb +324 -0
- data/lib/rapitapir/auth/oauth2.rb +350 -0
- data/lib/rapitapir/auth/schemes.rb +420 -0
- data/lib/rapitapir/auth.rb +113 -0
- data/lib/rapitapir/cli/command.rb +535 -0
- data/lib/rapitapir/cli/server.rb +243 -0
- data/lib/rapitapir/cli/validator.rb +373 -0
- data/lib/rapitapir/client/generator_base.rb +272 -0
- data/lib/rapitapir/client/typescript_generator.rb +350 -0
- data/lib/rapitapir/core/endpoint.rb +158 -0
- data/lib/rapitapir/core/enhanced_endpoint.rb +235 -0
- data/lib/rapitapir/core/input.rb +182 -0
- data/lib/rapitapir/core/output.rb +164 -0
- data/lib/rapitapir/core/request.rb +19 -0
- data/lib/rapitapir/core/response.rb +17 -0
- data/lib/rapitapir/docs/html_generator.rb +780 -0
- data/lib/rapitapir/docs/markdown_generator.rb +464 -0
- data/lib/rapitapir/dsl/endpoint_dsl.rb +116 -0
- data/lib/rapitapir/dsl/enhanced_endpoint_dsl.rb +62 -0
- data/lib/rapitapir/dsl/enhanced_input.rb +73 -0
- data/lib/rapitapir/dsl/enhanced_output.rb +63 -0
- data/lib/rapitapir/dsl/enhanced_structures.rb +393 -0
- data/lib/rapitapir/dsl/fluent_dsl.rb +72 -0
- data/lib/rapitapir/dsl/fluent_endpoint_builder.rb +316 -0
- data/lib/rapitapir/dsl/http_verbs.rb +77 -0
- data/lib/rapitapir/dsl/input_methods.rb +47 -0
- data/lib/rapitapir/dsl/observability_methods.rb +81 -0
- data/lib/rapitapir/dsl/output_methods.rb +43 -0
- data/lib/rapitapir/dsl/type_resolution.rb +43 -0
- data/lib/rapitapir/observability/configuration.rb +108 -0
- data/lib/rapitapir/observability/health_check.rb +236 -0
- data/lib/rapitapir/observability/logging.rb +270 -0
- data/lib/rapitapir/observability/metrics.rb +203 -0
- data/lib/rapitapir/observability/middleware.rb +243 -0
- data/lib/rapitapir/observability/tracing.rb +143 -0
- data/lib/rapitapir/observability.rb +28 -0
- data/lib/rapitapir/openapi/schema_generator.rb +403 -0
- data/lib/rapitapir/schema.rb +136 -0
- data/lib/rapitapir/server/enhanced_rack_adapter.rb +379 -0
- data/lib/rapitapir/server/middleware.rb +120 -0
- data/lib/rapitapir/server/path_matcher.rb +45 -0
- data/lib/rapitapir/server/rack_adapter.rb +215 -0
- data/lib/rapitapir/server/rails_adapter.rb +17 -0
- data/lib/rapitapir/server/rails_adapter_class.rb +53 -0
- data/lib/rapitapir/server/rails_controller.rb +72 -0
- data/lib/rapitapir/server/rails_input_processor.rb +73 -0
- data/lib/rapitapir/server/rails_response_handler.rb +29 -0
- data/lib/rapitapir/server/sinatra_adapter.rb +200 -0
- data/lib/rapitapir/server/sinatra_integration.rb +93 -0
- data/lib/rapitapir/sinatra/configuration.rb +91 -0
- data/lib/rapitapir/sinatra/extension.rb +214 -0
- data/lib/rapitapir/sinatra/oauth2_helpers.rb +236 -0
- data/lib/rapitapir/sinatra/resource_builder.rb +152 -0
- data/lib/rapitapir/sinatra/swagger_ui_generator.rb +166 -0
- data/lib/rapitapir/sinatra_rapitapir.rb +40 -0
- data/lib/rapitapir/types/array.rb +163 -0
- data/lib/rapitapir/types/auto_derivation.rb +265 -0
- data/lib/rapitapir/types/base.rb +146 -0
- data/lib/rapitapir/types/boolean.rb +46 -0
- data/lib/rapitapir/types/date.rb +92 -0
- data/lib/rapitapir/types/datetime.rb +98 -0
- data/lib/rapitapir/types/email.rb +32 -0
- data/lib/rapitapir/types/float.rb +134 -0
- data/lib/rapitapir/types/hash.rb +161 -0
- data/lib/rapitapir/types/integer.rb +143 -0
- data/lib/rapitapir/types/object.rb +156 -0
- data/lib/rapitapir/types/optional.rb +65 -0
- data/lib/rapitapir/types/string.rb +185 -0
- data/lib/rapitapir/types/uuid.rb +32 -0
- data/lib/rapitapir/types.rb +155 -0
- data/lib/rapitapir/version.rb +5 -0
- data/lib/rapitapir.rb +173 -0
- data/rapitapir.gemspec +66 -0
- metadata +387 -0
data/docs/phase3-plan.md
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
# Phase 3: Client Generation & Documentation Implementation Plan
|
2
|
+
|
3
|
+
## Overview
|
4
|
+
Phase 3 focuses on generating OpenAPI specifications, client SDKs, and documentation from RapiTapir endpoint definitions.
|
5
|
+
|
6
|
+
## Core Components
|
7
|
+
|
8
|
+
### 1. OpenAPI Schema Generation (`lib/rapitapir/openapi/`) โ
COMPLETE
|
9
|
+
- โ
`schema_generator.rb` - Main OpenAPI 3.0 schema generation
|
10
|
+
- โ
Type mapping - Maps RapiTapir types to OpenAPI schemas
|
11
|
+
- โ
Path generation - Generates OpenAPI paths from endpoints
|
12
|
+
- โ
Component generation - Generates reusable components/schemas
|
13
|
+
|
14
|
+
### 2. Client Generation (`lib/rapitapir/client/`) โ
TypeScript COMPLETE
|
15
|
+
- โ
`generator_base.rb` - Base class for client generators
|
16
|
+
- โ
`typescript_generator.rb` - TypeScript/JavaScript client
|
17
|
+
- [ ] `python_generator.rb` - Python client
|
18
|
+
- [ ] `curl_generator.rb` - cURL examples
|
19
|
+
- [ ] `template_engine.rb` - Template rendering system
|
20
|
+
|
21
|
+
### 3. Documentation (`lib/rapitapir/docs/`)
|
22
|
+
- [ ] `markdown_generator.rb` - API documentation in Markdown
|
23
|
+
- [ ] `html_generator.rb` - HTML documentation with styling
|
24
|
+
- [ ] `postman_generator.rb` - Postman collection export
|
25
|
+
|
26
|
+
### 4. CLI Tools (`lib/rapitapir/cli/`)
|
27
|
+
- [ ] `command.rb` - Main CLI interface
|
28
|
+
- [ ] `generate.rb` - Generation commands
|
29
|
+
- [ ] `serve.rb` - Documentation server
|
30
|
+
|
31
|
+
## Features
|
32
|
+
|
33
|
+
### OpenAPI Schema Features โ
COMPLETE
|
34
|
+
- โ
Basic endpoint definition
|
35
|
+
- โ
Complete OpenAPI 3.0 schema generation
|
36
|
+
- โ
Request/response schema mapping
|
37
|
+
- โ
Path parameter conversion (:id โ {id})
|
38
|
+
- โ
HTTP method support (GET, POST, PUT, DELETE, PATCH, etc.)
|
39
|
+
- โ
JSON/YAML output formats
|
40
|
+
- โ
Metadata integration (summary, description, tags)
|
41
|
+
- [ ] Authentication schemes
|
42
|
+
- [ ] Tags and operation grouping
|
43
|
+
- [ ] Examples and descriptions
|
44
|
+
|
45
|
+
### Client Generation Features โ
TypeScript COMPLETE
|
46
|
+
- โ
TypeScript client with type safety
|
47
|
+
- โ
HTTP client abstraction with fetch API
|
48
|
+
- โ
Error handling with custom error types
|
49
|
+
- โ
Request/response type generation
|
50
|
+
- โ
Path parameter interpolation
|
51
|
+
- โ
Query parameter handling
|
52
|
+
- โ
Optional parameter support
|
53
|
+
- โ
Configurable client (base URL, headers, timeout)
|
54
|
+
- [ ] Python client with type hints
|
55
|
+
- [ ] Authentication integration
|
56
|
+
|
57
|
+
### Documentation Features
|
58
|
+
- [ ] Interactive API documentation
|
59
|
+
- [ ] Code examples
|
60
|
+
- [ ] Try-it-out functionality
|
61
|
+
- [ ] Markdown export
|
62
|
+
- [ ] Postman collection export
|
63
|
+
|
64
|
+
## Implementation Status
|
65
|
+
|
66
|
+
### Phase 3.1: OpenAPI Generation โ
COMPLETE
|
67
|
+
- Full OpenAPI 3.0.3 schema generation
|
68
|
+
- Type mapping from Ruby to OpenAPI types
|
69
|
+
- Path parameter conversion
|
70
|
+
- Request/response documentation
|
71
|
+
- JSON and YAML output formats
|
72
|
+
- 11 comprehensive tests
|
73
|
+
- Working examples
|
74
|
+
|
75
|
+
### Phase 3.2: TypeScript Client Generator โ
COMPLETE
|
76
|
+
- Complete TypeScript client generation
|
77
|
+
- Type-safe interfaces for all endpoints
|
78
|
+
- Fetch-based HTTP client implementation
|
79
|
+
- Smart method naming (getUsers, createUser, getUserById)
|
80
|
+
- Optional parameter handling
|
81
|
+
- Error handling with ApiError types
|
82
|
+
- Configurable client settings
|
83
|
+
- 36 comprehensive tests (19 TypeScript + 17 Base)
|
84
|
+
- Working examples and usage documentation
|
85
|
+
|
86
|
+
### Current Progress: 88.33% test coverage, 159 tests passing
|
87
|
+
|
88
|
+
## Implementation Order
|
89
|
+
1. โ
OpenAPI schema generator (core functionality)
|
90
|
+
2. โ
TypeScript client generator
|
91
|
+
3. [ ] Documentation generator
|
92
|
+
4. [ ] CLI tools
|
93
|
+
5. [ ] Additional client generators (Python, etc.)
|
94
|
+
|
95
|
+
## Testing Strategy โ
IMPLEMENTED
|
96
|
+
- โ
Unit tests for each generator
|
97
|
+
- โ
Integration tests with real API definitions
|
98
|
+
- โ
Generated client validation
|
99
|
+
- โ
OpenAPI schema validation
|
100
|
+
- โ
Type conversion testing
|
101
|
+
- โ
Method name generation testing
|
102
|
+
- โ
Parameter extraction testing
|
103
|
+
|
104
|
+
## Next Steps
|
105
|
+
1. **Documentation Generator**: HTML and Markdown documentation generation
|
106
|
+
2. **CLI Tools**: Command-line interface for all generators
|
107
|
+
3. **Python Client Generator**: Type-hinted Python client with requests
|
108
|
+
4. **Additional Features**: Authentication, advanced error handling, more examples
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# SinatraRapiTapir - Clean Base Class
|
2
|
+
|
3
|
+
## Overview
|
4
|
+
|
5
|
+
`SinatraRapiTapir` is a new base class that provides the cleanest possible syntax for creating RapiTapir APIs with Sinatra. It automatically includes all RapiTapir functionality without any manual setup.
|
6
|
+
|
7
|
+
## Before vs After
|
8
|
+
|
9
|
+
### Before (Manual Extension Registration)
|
10
|
+
```ruby
|
11
|
+
require 'sinatra/base'
|
12
|
+
require_relative '../lib/rapitapir/sinatra/extension'
|
13
|
+
|
14
|
+
class MyAPI < Sinatra::Base
|
15
|
+
register RapiTapir::Sinatra::Extension
|
16
|
+
|
17
|
+
rapitapir do
|
18
|
+
info(title: 'My API', version: '1.0.0')
|
19
|
+
development_defaults!
|
20
|
+
end
|
21
|
+
|
22
|
+
endpoint(
|
23
|
+
GET('/hello').ok(string_response).build
|
24
|
+
) { { message: 'Hello!' } }
|
25
|
+
end
|
26
|
+
```
|
27
|
+
|
28
|
+
### After (Clean Base Class)
|
29
|
+
```ruby
|
30
|
+
require_relative '../lib/rapitapir'
|
31
|
+
|
32
|
+
class MyAPI < SinatraRapiTapir
|
33
|
+
rapitapir do
|
34
|
+
info(title: 'My API', version: '1.0.0')
|
35
|
+
development_defaults!
|
36
|
+
end
|
37
|
+
|
38
|
+
endpoint(
|
39
|
+
GET('/hello').ok(string_response).build
|
40
|
+
) { { message: 'Hello!' } }
|
41
|
+
end
|
42
|
+
```
|
43
|
+
|
44
|
+
## Key Benefits
|
45
|
+
|
46
|
+
1. **Cleaner Syntax**: `class MyAPI < SinatraRapiTapir` vs manual extension registration
|
47
|
+
2. **Fewer Requires**: Only need to require `rapitapir`, not individual extensions
|
48
|
+
3. **Automatic Setup**: Extension is automatically registered
|
49
|
+
4. **Enhanced DSL**: HTTP verb methods (GET, POST, etc.) are automatically available
|
50
|
+
5. **Full Compatibility**: Works identically to manual extension registration
|
51
|
+
6. **Type Safety**: Maintains all FluentEndpointBuilder functionality
|
52
|
+
|
53
|
+
## Features Automatically Included
|
54
|
+
|
55
|
+
- โ
Enhanced HTTP verb DSL (`GET()`, `POST()`, `PUT()`, etc.)
|
56
|
+
- โ
RapiTapir extension with all features
|
57
|
+
- โ
Automatic health check endpoints
|
58
|
+
- โ
OpenAPI documentation generation
|
59
|
+
- โ
CORS and security middleware
|
60
|
+
- โ
Type validation and error handling
|
61
|
+
- โ
Authentication and authorization helpers
|
62
|
+
|
63
|
+
## Usage
|
64
|
+
|
65
|
+
The `SinatraRapiTapir` class is available in two ways:
|
66
|
+
|
67
|
+
1. **Namespaced**: `RapiTapir::SinatraRapiTapir`
|
68
|
+
2. **Top-level**: `SinatraRapiTapir` (for convenience)
|
69
|
+
|
70
|
+
Both are equivalent and can be used interchangeably.
|
71
|
+
|
72
|
+
## Examples
|
73
|
+
|
74
|
+
- `examples/hello_world.rb` - Minimal API demonstration
|
75
|
+
- `examples/getting_started_extension.rb` - Full bookstore API
|
76
|
+
|
77
|
+
## Backward Compatibility
|
78
|
+
|
79
|
+
The new base class is 100% backward compatible. Existing code using manual extension registration continues to work unchanged.
|
80
|
+
|
81
|
+
## Testing
|
82
|
+
|
83
|
+
Comprehensive test coverage is provided in `spec/sinatra/sinatra_rapitapir_spec.rb` with:
|
84
|
+
- Inheritance verification
|
85
|
+
- Enhanced DSL testing
|
86
|
+
- Feature compatibility testing
|
87
|
+
- Backward compatibility validation
|
@@ -0,0 +1,146 @@
|
|
1
|
+
# Type Shortcuts in RapiTapir
|
2
|
+
|
3
|
+
## Overview
|
4
|
+
|
5
|
+
RapiTapir provides a global `T` constant as a shortcut for `RapiTapir::Types`, making your type definitions much cleaner and more readable. **No manual setup required** - the `T` shortcut is automatically available when you `require 'rapitapir'`.
|
6
|
+
|
7
|
+
## Before vs After
|
8
|
+
|
9
|
+
### Before (Verbose)
|
10
|
+
```ruby
|
11
|
+
USER_SCHEMA = RapiTapir::Types.hash({
|
12
|
+
"id" => RapiTapir::Types.integer,
|
13
|
+
"name" => RapiTapir::Types.string(min_length: 1, max_length: 100),
|
14
|
+
"email" => RapiTapir::Types.email,
|
15
|
+
"age" => RapiTapir::Types.optional(RapiTapir::Types.integer(min: 0, max: 150))
|
16
|
+
})
|
17
|
+
```
|
18
|
+
|
19
|
+
### After (Clean)
|
20
|
+
```ruby
|
21
|
+
USER_SCHEMA = T.hash({
|
22
|
+
"id" => T.integer,
|
23
|
+
"name" => T.string(min_length: 1, max_length: 100),
|
24
|
+
"email" => T.email,
|
25
|
+
"age" => T.optional(T.integer(min: 0, max: 150))
|
26
|
+
})
|
27
|
+
```
|
28
|
+
|
29
|
+
## Automatic Availability
|
30
|
+
|
31
|
+
The `T` shortcut is **globally available** after requiring RapiTapir:
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
require 'rapitapir'
|
35
|
+
|
36
|
+
# T is immediately available everywhere - no setup needed!
|
37
|
+
BOOK_SCHEMA = T.hash({
|
38
|
+
"title" => T.string,
|
39
|
+
"pages" => T.integer
|
40
|
+
})
|
41
|
+
|
42
|
+
class MyAPI < SinatraRapiTapir
|
43
|
+
# T works inside classes too
|
44
|
+
USER_SCHEMA = T.hash({
|
45
|
+
"name" => T.string,
|
46
|
+
"email" => T.email
|
47
|
+
})
|
48
|
+
|
49
|
+
endpoint(
|
50
|
+
GET('/books')
|
51
|
+
.ok(T.array(BOOK_SCHEMA)) # And in endpoint definitions
|
52
|
+
.build
|
53
|
+
) { Book.all }
|
54
|
+
end
|
55
|
+
```
|
56
|
+
|
57
|
+
## All Available Type Shortcuts
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
# Primitive types
|
61
|
+
T.string(min_length: 1, max_length: 255)
|
62
|
+
T.integer(minimum: 0, maximum: 100)
|
63
|
+
T.float(minimum: 0.0)
|
64
|
+
T.boolean
|
65
|
+
T.date
|
66
|
+
T.datetime
|
67
|
+
T.uuid
|
68
|
+
T.email
|
69
|
+
|
70
|
+
# Composite types
|
71
|
+
T.array(T.string)
|
72
|
+
T.hash({ "key" => T.string })
|
73
|
+
T.optional(T.string)
|
74
|
+
|
75
|
+
# Complex object types
|
76
|
+
T.object do
|
77
|
+
field :id, T.integer
|
78
|
+
field :name, T.string
|
79
|
+
end
|
80
|
+
```
|
81
|
+
|
82
|
+
## Usage in Endpoints
|
83
|
+
|
84
|
+
```ruby
|
85
|
+
class MyAPI < SinatraRapiTapir
|
86
|
+
endpoint(
|
87
|
+
GET('/users/:id')
|
88
|
+
.path_param(:id, T.integer(minimum: 1))
|
89
|
+
.query(:include, T.optional(T.array(T.string)))
|
90
|
+
.ok(T.hash({
|
91
|
+
"user" => USER_SCHEMA,
|
92
|
+
"metadata" => T.hash({
|
93
|
+
"version" => T.string,
|
94
|
+
"timestamp" => T.datetime
|
95
|
+
})
|
96
|
+
}))
|
97
|
+
.error_out(404, T.hash({ "error" => T.string }))
|
98
|
+
.build
|
99
|
+
) do |inputs|
|
100
|
+
# Your endpoint logic
|
101
|
+
end
|
102
|
+
end
|
103
|
+
```
|
104
|
+
|
105
|
+
## Benefits
|
106
|
+
|
107
|
+
1. **Automatic Setup**: Available immediately after `require 'rapitapir'` - no manual configuration
|
108
|
+
2. **Readability**: Much cleaner type definitions
|
109
|
+
3. **Less Typing**: Shorter syntax reduces boilerplate
|
110
|
+
4. **Consistency**: Same T prefix for all types
|
111
|
+
5. **Familiar**: Similar to TypeScript's type syntax
|
112
|
+
6. **Global Scope**: Works everywhere - classes, modules, top-level code
|
113
|
+
7. **Backward Compatible**: `RapiTapir::Types` still works
|
114
|
+
|
115
|
+
## Alternative Approaches
|
116
|
+
|
117
|
+
If you prefer your own shortcut, you can create it:
|
118
|
+
|
119
|
+
```ruby
|
120
|
+
# Custom shortcut (but T is already provided!)
|
121
|
+
Types = RapiTapir::Types
|
122
|
+
|
123
|
+
# Or even shorter
|
124
|
+
RT = RapiTapir::Types
|
125
|
+
|
126
|
+
# Use it
|
127
|
+
USER_SCHEMA = Types.hash({ "name" => Types.string })
|
128
|
+
```
|
129
|
+
|
130
|
+
**Note**: The global `T` constant is automatically available when you `require 'rapitapir'` - no need to define your own unless you prefer a different name.
|
131
|
+
|
132
|
+
## Implementation
|
133
|
+
|
134
|
+
The T shortcut is implemented in the main RapiTapir library file:
|
135
|
+
|
136
|
+
```ruby
|
137
|
+
# In lib/rapitapir.rb
|
138
|
+
module RapiTapir
|
139
|
+
# ... RapiTapir module code ...
|
140
|
+
end
|
141
|
+
|
142
|
+
# Global shortcut constant
|
143
|
+
T = RapiTapir::Types
|
144
|
+
```
|
145
|
+
|
146
|
+
This means that as soon as you require RapiTapir, the `T` constant becomes available throughout your entire application.
|
@@ -0,0 +1,202 @@
|
|
1
|
+
# Enterprise RapiTapir API - Auto-Generated OpenAPI Implementation
|
2
|
+
|
3
|
+
This is the improved version of the Enterprise Sinatra API that demonstrates RapiTapir's capability to automatically generate OpenAPI 3.0 specifications from endpoint definitions at runtime.
|
4
|
+
|
5
|
+
## ๐ฏ Key Improvements
|
6
|
+
|
7
|
+
### โ
**Fixed Issues from Original Version**
|
8
|
+
|
9
|
+
1. **Auto-Generated OpenAPI**: The OpenAPI specification is now generated automatically from RapiTapir endpoint definitions at runtime, not manually written
|
10
|
+
2. **Working Run Script**: Fixed the `run_enterprise_api.rb` script to properly load dependencies with `bundle exec`
|
11
|
+
3. **Proper RapiTapir DSL Usage**: All endpoints are now defined using RapiTapir's fluent DSL with proper type definitions
|
12
|
+
4. **Runtime Reflection**: The API documentation reflects the actual endpoint implementations
|
13
|
+
|
14
|
+
### ๐ **Enterprise Features**
|
15
|
+
|
16
|
+
- **8 Fully-Typed Endpoints** defined with RapiTapir DSL
|
17
|
+
- **Auto-Generated OpenAPI 3.0** specification from endpoint definitions
|
18
|
+
- **Bearer Token Authentication** with scope-based authorization
|
19
|
+
- **Production Middleware Stack**: CORS, Rate Limiting, Security Headers
|
20
|
+
- **Interactive Documentation** with Swagger UI
|
21
|
+
- **Type-Safe Request/Response** schemas using RapiTapir Types
|
22
|
+
|
23
|
+
## ๐ API Endpoints (Auto-Generated from RapiTapir Definitions)
|
24
|
+
|
25
|
+
All endpoints are defined using RapiTapir's fluent DSL and automatically generate OpenAPI documentation:
|
26
|
+
|
27
|
+
### System Endpoints
|
28
|
+
- **GET /health** - Health check (public)
|
29
|
+
- **GET /docs** - Interactive Swagger UI documentation
|
30
|
+
- **GET /openapi.json** - Auto-generated OpenAPI 3.0 specification
|
31
|
+
|
32
|
+
### Task Management Endpoints (Authenticated)
|
33
|
+
- **GET /api/v1/tasks** - List all tasks (requires `read` scope)
|
34
|
+
- **GET /api/v1/tasks/:id** - Get specific task (requires `read` scope)
|
35
|
+
- **POST /api/v1/tasks** - Create new task (requires `write` scope)
|
36
|
+
- **PUT /api/v1/tasks/:id** - Update task (requires `write` scope)
|
37
|
+
- **DELETE /api/v1/tasks/:id** - Delete task (requires `admin` scope)
|
38
|
+
|
39
|
+
### User Endpoints (Authenticated)
|
40
|
+
- **GET /api/v1/profile** - Get current user profile with assigned tasks
|
41
|
+
- **GET /api/v1/admin/users** - List all users (requires `admin` scope)
|
42
|
+
|
43
|
+
## ๐ Authentication
|
44
|
+
|
45
|
+
Three test Bearer tokens are provided:
|
46
|
+
|
47
|
+
```bash
|
48
|
+
# Regular user (read, write permissions)
|
49
|
+
Authorization: Bearer user-token-123
|
50
|
+
|
51
|
+
# Admin user (read, write, admin, delete permissions)
|
52
|
+
Authorization: Bearer admin-token-456
|
53
|
+
|
54
|
+
# Read-only user (read permission only)
|
55
|
+
Authorization: Bearer readonly-token-789
|
56
|
+
```
|
57
|
+
|
58
|
+
## ๐โโ๏ธ **Running the API**
|
59
|
+
|
60
|
+
### Start the Server
|
61
|
+
```bash
|
62
|
+
cd /Users/riccardo/git/github/riccardomerolla/rapitapir
|
63
|
+
bundle exec ruby examples/run_enterprise_api.rb
|
64
|
+
```
|
65
|
+
|
66
|
+
### Access Documentation
|
67
|
+
- **Interactive Docs**: http://localhost:4567/docs
|
68
|
+
- **OpenAPI Spec**: http://localhost:4567/openapi.json
|
69
|
+
- **Health Check**: http://localhost:4567/health
|
70
|
+
|
71
|
+
## ๐ **Example API Calls**
|
72
|
+
|
73
|
+
### Health Check (Public)
|
74
|
+
```bash
|
75
|
+
curl http://localhost:4567/health
|
76
|
+
```
|
77
|
+
|
78
|
+
### List Tasks (Authenticated)
|
79
|
+
```bash
|
80
|
+
curl -H "Authorization: Bearer user-token-123" \
|
81
|
+
http://localhost:4567/api/v1/tasks
|
82
|
+
```
|
83
|
+
|
84
|
+
### Create Task (Authenticated)
|
85
|
+
```bash
|
86
|
+
curl -X POST \
|
87
|
+
-H "Authorization: Bearer user-token-123" \
|
88
|
+
-H "Content-Type: application/json" \
|
89
|
+
-d '{"title":"New Task","description":"Test task","assignee_id":1}' \
|
90
|
+
http://localhost:4567/api/v1/tasks
|
91
|
+
```
|
92
|
+
|
93
|
+
### Get User Profile (Authenticated)
|
94
|
+
```bash
|
95
|
+
curl -H "Authorization: Bearer user-token-123" \
|
96
|
+
http://localhost:4567/api/v1/profile
|
97
|
+
```
|
98
|
+
|
99
|
+
### Admin: List All Users (Admin Only)
|
100
|
+
```bash
|
101
|
+
curl -H "Authorization: Bearer admin-token-456" \
|
102
|
+
http://localhost:4567/api/v1/admin/users
|
103
|
+
```
|
104
|
+
|
105
|
+
## ๐ฏ **RapiTapir DSL Example**
|
106
|
+
|
107
|
+
The endpoints are defined using RapiTapir's fluent DSL with full type safety:
|
108
|
+
|
109
|
+
```ruby
|
110
|
+
# Task creation endpoint with full type validation
|
111
|
+
RapiTapir.post('/api/v1/tasks')
|
112
|
+
.summary('Create a new task')
|
113
|
+
.description('Create a new task in the system. Requires write permission.')
|
114
|
+
.json_body(TASK_CREATE_SCHEMA) # RapiTapir type schema
|
115
|
+
.created(TASK_SCHEMA) # Response type validation
|
116
|
+
.error_response(400, ERROR_SCHEMA, description: 'Validation error')
|
117
|
+
.error_response(401, ERROR_SCHEMA, description: 'Authentication required')
|
118
|
+
.error_response(403, ERROR_SCHEMA, description: 'Insufficient permissions')
|
119
|
+
.build
|
120
|
+
```
|
121
|
+
|
122
|
+
## ๐ง **Auto-Generated OpenAPI Features**
|
123
|
+
|
124
|
+
The OpenAPI specification is generated automatically from the RapiTapir endpoint definitions:
|
125
|
+
|
126
|
+
- **Path Parameters**: Automatically extracted from `:id` patterns
|
127
|
+
- **Query Parameters**: Type-safe with validation rules
|
128
|
+
- **Request Bodies**: JSON schema validation from RapiTapir types
|
129
|
+
- **Response Schemas**: Type-safe response definitions
|
130
|
+
- **Error Responses**: Comprehensive error documentation
|
131
|
+
- **Security Schemes**: Bearer token authentication documented
|
132
|
+
- **Operation Metadata**: Summaries, descriptions, and tags
|
133
|
+
|
134
|
+
## ๐๏ธ **Architecture Highlights**
|
135
|
+
|
136
|
+
### Type-Safe Schema Definitions
|
137
|
+
```ruby
|
138
|
+
TASK_SCHEMA = RapiTapir::Types.hash({
|
139
|
+
"id" => RapiTapir::Types.integer,
|
140
|
+
"title" => RapiTapir::Types.string,
|
141
|
+
"description" => RapiTapir::Types.string,
|
142
|
+
"status" => RapiTapir::Types.string,
|
143
|
+
"assignee_id" => RapiTapir::Types.integer,
|
144
|
+
"created_at" => RapiTapir::Types.string,
|
145
|
+
"updated_at" => RapiTapir::Types.optional(RapiTapir::Types.string)
|
146
|
+
})
|
147
|
+
```
|
148
|
+
|
149
|
+
### Auto-Generated OpenAPI
|
150
|
+
```ruby
|
151
|
+
def self.openapi_spec
|
152
|
+
@openapi_spec ||= begin
|
153
|
+
generator = RapiTapir::OpenAPI::SchemaGenerator.new(
|
154
|
+
endpoints: endpoints,
|
155
|
+
info: { title: 'Enterprise Task Management API', version: '1.0.0' }
|
156
|
+
)
|
157
|
+
generator.generate
|
158
|
+
end
|
159
|
+
end
|
160
|
+
```
|
161
|
+
|
162
|
+
### Sinatra Integration
|
163
|
+
```ruby
|
164
|
+
# OpenAPI endpoint auto-generated at runtime
|
165
|
+
get '/openapi.json' do
|
166
|
+
content_type :json
|
167
|
+
JSON.pretty_generate(TaskAPI.openapi_spec)
|
168
|
+
end
|
169
|
+
```
|
170
|
+
|
171
|
+
## โจ **Production Features**
|
172
|
+
|
173
|
+
- **Security Headers**: XSS protection, content type options
|
174
|
+
- **CORS Support**: Configurable origins and methods
|
175
|
+
- **Rate Limiting**: 100 requests/minute, 2000/hour
|
176
|
+
- **Request Validation**: Type-safe input validation
|
177
|
+
- **Error Handling**: Structured error responses
|
178
|
+
- **Authentication Middleware**: Bearer token validation
|
179
|
+
- **Authorization**: Scope-based permission checking
|
180
|
+
|
181
|
+
## ๐งช **Testing**
|
182
|
+
|
183
|
+
Run the comprehensive test suite:
|
184
|
+
|
185
|
+
```bash
|
186
|
+
# Test RapiTapir endpoint definitions
|
187
|
+
ruby examples/test_rapitapir_endpoints.rb
|
188
|
+
|
189
|
+
# Test the full enterprise API (requires server to be running)
|
190
|
+
ruby examples/test_enterprise_api.rb
|
191
|
+
```
|
192
|
+
|
193
|
+
## ๐ **Benefits of This Approach**
|
194
|
+
|
195
|
+
1. **Single Source of Truth**: API endpoints defined once in RapiTapir DSL
|
196
|
+
2. **Auto-Generated Documentation**: OpenAPI spec reflects actual implementation
|
197
|
+
3. **Type Safety**: Request/response validation with RapiTapir types
|
198
|
+
4. **Developer Experience**: Interactive Swagger UI for testing
|
199
|
+
5. **Production Ready**: Comprehensive middleware and security
|
200
|
+
6. **Maintainable**: No manual OpenAPI spec maintenance required
|
201
|
+
|
202
|
+
This implementation demonstrates the power of RapiTapir's DSL and auto-generation capabilities in creating production-ready APIs with comprehensive documentation.
|