mcp-on-rails 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/.rubocop.yml +8 -0
- data/CHANGELOG.md +24 -0
- data/README.md +152 -0
- data/Rakefile +12 -0
- data/exe/mcp-on-rails +36 -0
- data/lib/mcp/on/rails/generator.rb +85 -0
- data/lib/mcp/on/rails/templates/context.md +27 -0
- data/lib/mcp/on/rails/templates/mcp-config.yml.erb +96 -0
- data/lib/mcp/on/rails/templates/prompts/api.md +201 -0
- data/lib/mcp/on/rails/templates/prompts/architect.md +62 -0
- data/lib/mcp/on/rails/templates/prompts/controllers.md +103 -0
- data/lib/mcp/on/rails/templates/prompts/devops.md +324 -0
- data/lib/mcp/on/rails/templates/prompts/graphql.md +328 -0
- data/lib/mcp/on/rails/templates/prompts/jobs.md +251 -0
- data/lib/mcp/on/rails/templates/prompts/models.md +95 -0
- data/lib/mcp/on/rails/templates/prompts/services.md +170 -0
- data/lib/mcp/on/rails/templates/prompts/stimulus.md +369 -0
- data/lib/mcp/on/rails/templates/prompts/tests.md +150 -0
- data/lib/mcp/on/rails/templates/prompts/views.md +120 -0
- data/lib/mcp/on/rails/version.rb +9 -0
- data/lib/mcp/on/rails.rb +16 -0
- data/sig/mcp/on/rails.rbs +8 -0
- metadata +68 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9de4dca8095e1020e24bf8f70df4a28f148b2cc85ecf2768a556722da1292132
|
4
|
+
data.tar.gz: c553494738ae79d5ac4409021a2f1ddd69caf1506e47d38c42e93add47c9f106
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: cca8f6b8ebcdfe8ff07e50af3008d0aa50208225b127d5edddc3cb7b86b03329dcd36ae897ff079d387e2b4c7ef104932a6e5dca22b1e7da8380d029fc768ed7
|
7
|
+
data.tar.gz: 7c120a4dff702bdb99be86fea3d02e02f0832bdae3e9b008a9397510a4ff7b4cff1f33319e0f038401caa007681a9f7e322c84c27e77f4b6dce4d5a1ce27a4d7
|
data/.rubocop.yml
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
## [Unreleased]
|
2
|
+
|
3
|
+
## [0.1.0] - 2025-07-30
|
4
|
+
|
5
|
+
### Added
|
6
|
+
- Initial release of mcp-on-rails gem
|
7
|
+
- Pre-configured MCP settings for Rails development
|
8
|
+
- Specialized prompts for 8 Rails component areas:
|
9
|
+
- Architect (overall coordination)
|
10
|
+
- Models (ActiveRecord, migrations, database)
|
11
|
+
- Controllers (HTTP handling, routing, APIs)
|
12
|
+
- Views (templates, layouts, frontend)
|
13
|
+
- Stimulus (JavaScript, Turbo integration)
|
14
|
+
- Jobs (background processing)
|
15
|
+
- Tests (testing strategies, coverage)
|
16
|
+
- DevOps (deployment, infrastructure)
|
17
|
+
- Template system with ERB for project customization
|
18
|
+
- Command-line interface with `mcp-on-rails` executable
|
19
|
+
- Compatible with Claude, GitHub Copilot, VS Code, and other MCP clients
|
20
|
+
- Automatic project setup with `.mcp-on-rails/` directory structure
|
21
|
+
- Comprehensive documentation and usage examples
|
22
|
+
|
23
|
+
### Credits
|
24
|
+
- Inspired by and adapted from [claude-on-rails](https://github.com/obie/claude-on-rails) by Obie Fernandez
|
data/README.md
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
# MCP on Rails
|
2
|
+
|
3
|
+
MCP on Rails provides pre-configured Model Context Protocol (MCP) settings, specialized prompts, and templates for Rails development with AI assistants like Claude, GitHub Copilot, and other MCP-compatible tools.
|
4
|
+
|
5
|
+
> 🙏 **Acknowledgments**: This project is inspired by and adapted from [claude-on-rails](https://github.com/obie/claude-on-rails) by Obie Fernandez. The original prompts and swarm configuration have been restructured for broader MCP compatibility.
|
6
|
+
|
7
|
+
## Features
|
8
|
+
|
9
|
+
- 🧠 **Specialized AI Prompts** - Context-aware prompts for different Rails components (models, controllers, views, etc.)
|
10
|
+
- ⚙️ **MCP Configuration** - Ready-to-use MCP server configuration for Rails projects
|
11
|
+
- 🚀 **Quick Setup** - One command to set up AI assistance for your Rails project
|
12
|
+
- 🔧 **Customizable** - Templates that adapt to your project structure
|
13
|
+
- 📚 **Best Practices** - Built-in Rails conventions and best practices
|
14
|
+
|
15
|
+
## Installation
|
16
|
+
|
17
|
+
Add this line to your application's Gemfile:
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
gem 'mcp-on-rails'
|
21
|
+
```
|
22
|
+
|
23
|
+
And then execute:
|
24
|
+
|
25
|
+
```bash
|
26
|
+
$ bundle install
|
27
|
+
```
|
28
|
+
|
29
|
+
Or install it yourself as:
|
30
|
+
|
31
|
+
```bash
|
32
|
+
$ gem install mcp-on-rails
|
33
|
+
```
|
34
|
+
|
35
|
+
## Usage
|
36
|
+
|
37
|
+
### Quick Setup
|
38
|
+
|
39
|
+
In your Rails project directory, run:
|
40
|
+
|
41
|
+
```bash
|
42
|
+
$ mcp-on-rails
|
43
|
+
```
|
44
|
+
|
45
|
+
This will create:
|
46
|
+
- `.mcp-on-rails/` directory with configuration and prompts
|
47
|
+
- `bin/mcp-setup` executable for project-specific setup
|
48
|
+
- MCP configuration file optimized for Rails development
|
49
|
+
|
50
|
+
### Manual Setup
|
51
|
+
|
52
|
+
You can also set up programmatically:
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
require 'mcp/on/rails'
|
56
|
+
|
57
|
+
Mcp::On::Rails.setup(
|
58
|
+
project_name: "MyRailsApp",
|
59
|
+
project_path: "/path/to/rails/project"
|
60
|
+
)
|
61
|
+
```
|
62
|
+
|
63
|
+
### What Gets Created
|
64
|
+
|
65
|
+
```
|
66
|
+
your-rails-project/
|
67
|
+
├── .mcp-on-rails/
|
68
|
+
│ ├── mcp-config.yml # MCP server configuration
|
69
|
+
│ ├── context.md # Project context for AI
|
70
|
+
│ └── prompts/ # Specialized prompts for each area
|
71
|
+
│ ├── architect.md # Overall architecture guidance
|
72
|
+
│ ├── models.md # ActiveRecord and database
|
73
|
+
│ ├── controllers.md # HTTP handling and routing
|
74
|
+
│ ├── views.md # Templates and frontend
|
75
|
+
│ ├── stimulus.md # JavaScript and Turbo
|
76
|
+
│ ├── jobs.md # Background processing
|
77
|
+
│ ├── tests.md # Testing strategies
|
78
|
+
│ └── devops.md # Deployment and infrastructure
|
79
|
+
└── bin/
|
80
|
+
└── mcp-setup # Project setup script
|
81
|
+
```
|
82
|
+
|
83
|
+
## MCP Client Configuration
|
84
|
+
|
85
|
+
### VS Code with GitHub Copilot
|
86
|
+
|
87
|
+
1. Install the MCP extension for VS Code
|
88
|
+
2. Configure your workspace settings:
|
89
|
+
|
90
|
+
```json
|
91
|
+
{
|
92
|
+
"mcp.configPath": ".mcp-on-rails/mcp-config.yml"
|
93
|
+
}
|
94
|
+
```
|
95
|
+
|
96
|
+
### Claude Desktop
|
97
|
+
|
98
|
+
Add to your Claude Desktop configuration:
|
99
|
+
|
100
|
+
```json
|
101
|
+
{
|
102
|
+
"mcpServers": {
|
103
|
+
"rails": {
|
104
|
+
"command": "rails-mcp-server",
|
105
|
+
"env": {
|
106
|
+
"RAILS_ENV": "development"
|
107
|
+
}
|
108
|
+
}
|
109
|
+
}
|
110
|
+
}
|
111
|
+
```
|
112
|
+
|
113
|
+
### Other MCP Clients
|
114
|
+
|
115
|
+
The generated `mcp-config.yml` is compatible with most MCP clients. Refer to your client's documentation for specific configuration steps.
|
116
|
+
|
117
|
+
## Context Areas
|
118
|
+
|
119
|
+
MCP on Rails organizes your Rails project into specialized context areas:
|
120
|
+
|
121
|
+
- **Architect** - Overall project coordination and architecture decisions
|
122
|
+
- **Models** - ActiveRecord models, migrations, database design
|
123
|
+
- **Controllers** - HTTP handling, routing, authentication, APIs
|
124
|
+
- **Views** - Templates, layouts, partials, frontend components
|
125
|
+
- **Stimulus** - JavaScript behavior, Turbo integration
|
126
|
+
- **Jobs** - Background processing, queues, scheduled tasks
|
127
|
+
- **Tests** - Testing strategies, factories, test coverage
|
128
|
+
- **DevOps** - Deployment, infrastructure, environment configuration
|
129
|
+
|
130
|
+
Each area includes specialized prompts that help AI assistants understand the context and provide more relevant suggestions.
|
131
|
+
|
132
|
+
## Customization
|
133
|
+
|
134
|
+
After running the setup, you can customize:
|
135
|
+
|
136
|
+
1. **Project-specific prompts** - Edit files in `.mcp-on-rails/prompts/`
|
137
|
+
2. **MCP configuration** - Modify `.mcp-on-rails/mcp-config.yml`
|
138
|
+
3. **Context information** - Update `.mcp-on-rails/context.md`
|
139
|
+
|
140
|
+
## Development
|
141
|
+
|
142
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
143
|
+
|
144
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
145
|
+
|
146
|
+
## Contributing
|
147
|
+
|
148
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/GoCoder7/mcp-on-rails.
|
149
|
+
|
150
|
+
## License
|
151
|
+
|
152
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/exe/mcp-on-rails
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "mcp/on/rails"
|
5
|
+
require "optparse"
|
6
|
+
|
7
|
+
options = {}
|
8
|
+
OptionParser.new do |opts|
|
9
|
+
opts.banner = "Usage: mcp-on-rails [options]"
|
10
|
+
|
11
|
+
opts.on("-n", "--name NAME", "Project name (defaults to current directory name)") do |name|
|
12
|
+
options[:project_name] = name
|
13
|
+
end
|
14
|
+
|
15
|
+
opts.on("-p", "--path PATH", "Project path (defaults to current directory)") do |path|
|
16
|
+
options[:project_path] = path
|
17
|
+
end
|
18
|
+
|
19
|
+
opts.on("-h", "--help", "Prints this help") do
|
20
|
+
puts opts
|
21
|
+
exit
|
22
|
+
end
|
23
|
+
|
24
|
+
opts.on("-v", "--version", "Show version") do
|
25
|
+
puts Mcp::On::Rails::VERSION
|
26
|
+
exit
|
27
|
+
end
|
28
|
+
end.parse!
|
29
|
+
|
30
|
+
puts "🚀 Setting up MCP on Rails..."
|
31
|
+
puts ""
|
32
|
+
|
33
|
+
Mcp::On::Rails.setup(
|
34
|
+
project_name: options[:project_name],
|
35
|
+
project_path: options[:project_path] || "."
|
36
|
+
)
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "erb"
|
4
|
+
require "fileutils"
|
5
|
+
|
6
|
+
module Mcp
|
7
|
+
module On
|
8
|
+
module Rails
|
9
|
+
class Generator
|
10
|
+
attr_reader :project_name, :project_path
|
11
|
+
|
12
|
+
def initialize(project_name: nil, project_path: ".")
|
13
|
+
@project_name = project_name || File.basename(File.expand_path(project_path))
|
14
|
+
@project_path = File.expand_path(project_path)
|
15
|
+
end
|
16
|
+
|
17
|
+
def generate
|
18
|
+
create_mcp_directory
|
19
|
+
copy_prompts
|
20
|
+
generate_config_file
|
21
|
+
copy_context_file
|
22
|
+
create_executable
|
23
|
+
puts "✅ MCP on Rails setup completed for '#{project_name}'"
|
24
|
+
puts "📁 Files created in: #{File.join(project_path, '.mcp-on-rails')}"
|
25
|
+
puts "🚀 Run: ./bin/mcp-setup to configure your project"
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def create_mcp_directory
|
31
|
+
mcp_dir = File.join(project_path, ".mcp-on-rails")
|
32
|
+
FileUtils.mkdir_p(mcp_dir)
|
33
|
+
end
|
34
|
+
|
35
|
+
def copy_prompts
|
36
|
+
source_prompts = File.join(templates_path, "prompts")
|
37
|
+
target_prompts = File.join(project_path, ".mcp-on-rails", "prompts")
|
38
|
+
FileUtils.cp_r(source_prompts, target_prompts)
|
39
|
+
end
|
40
|
+
|
41
|
+
def generate_config_file
|
42
|
+
template_file = File.join(templates_path, "mcp-config.yml.erb")
|
43
|
+
target_file = File.join(project_path, ".mcp-on-rails", "mcp-config.yml")
|
44
|
+
|
45
|
+
template = ERB.new(File.read(template_file))
|
46
|
+
content = template.result(binding)
|
47
|
+
|
48
|
+
File.write(target_file, content)
|
49
|
+
end
|
50
|
+
|
51
|
+
def copy_context_file
|
52
|
+
source_file = File.join(templates_path, "context.md")
|
53
|
+
target_file = File.join(project_path, ".mcp-on-rails", "context.md")
|
54
|
+
FileUtils.cp(source_file, target_file)
|
55
|
+
end
|
56
|
+
|
57
|
+
def create_executable
|
58
|
+
bin_dir = File.join(project_path, "bin")
|
59
|
+
FileUtils.mkdir_p(bin_dir)
|
60
|
+
|
61
|
+
executable_content = <<~SCRIPT
|
62
|
+
#!/usr/bin/env ruby
|
63
|
+
# frozen_string_literal: true
|
64
|
+
|
65
|
+
puts "🔧 Setting up MCP on Rails for #{project_name}"
|
66
|
+
puts "📋 Configuration files are ready in .mcp-on-rails/"
|
67
|
+
puts ""
|
68
|
+
puts "Next steps:"
|
69
|
+
puts "1. Configure your MCP client to use .mcp-on-rails/mcp-config.yml"
|
70
|
+
puts "2. Use the prompts in .mcp-on-rails/prompts/ for context-aware AI assistance"
|
71
|
+
puts "3. Customize the configuration as needed for your project"
|
72
|
+
SCRIPT
|
73
|
+
|
74
|
+
executable_path = File.join(bin_dir, "mcp-setup")
|
75
|
+
File.write(executable_path, executable_content)
|
76
|
+
FileUtils.chmod(0o755, executable_path)
|
77
|
+
end
|
78
|
+
|
79
|
+
def templates_path
|
80
|
+
File.join(__dir__, "templates")
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# ClaudeOnRails Context
|
2
|
+
|
3
|
+
This project uses ClaudeOnRails with a swarm of specialized agents for Rails development.
|
4
|
+
|
5
|
+
## Project Information
|
6
|
+
- **Rails Version**: 8.0.2
|
7
|
+
- **Ruby Version**: 3.4.4
|
8
|
+
- **Project Type**: Full-stack Rails
|
9
|
+
- **Test Framework**: Minitest
|
10
|
+
- **Turbo/Stimulus**: Enabled
|
11
|
+
|
12
|
+
## Swarm Configuration
|
13
|
+
|
14
|
+
The claude-swarm.yml file defines specialized agents for different aspects of Rails development:
|
15
|
+
- Each agent has specific expertise and works in designated directories
|
16
|
+
- Agents collaborate to implement features across all layers
|
17
|
+
- The architect agent coordinates the team
|
18
|
+
|
19
|
+
## Development Guidelines
|
20
|
+
|
21
|
+
When working on this project:
|
22
|
+
- Follow Rails conventions and best practices
|
23
|
+
- Write tests for all new functionality
|
24
|
+
- Use strong parameters in controllers
|
25
|
+
- Keep models focused with single responsibilities
|
26
|
+
- Extract complex business logic to service objects
|
27
|
+
- Ensure proper database indexing for foreign keys and queries
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# MCP on Rails Configuration
|
2
|
+
# This file configures Model Context Protocol settings for Rails development
|
3
|
+
# Compatible with various MCP clients including Claude, GitHub Copilot, and VS Code extensions
|
4
|
+
|
5
|
+
project:
|
6
|
+
name: "<%= project_name %>"
|
7
|
+
type: "rails"
|
8
|
+
description: "Rails application with MCP-optimized AI assistance"
|
9
|
+
|
10
|
+
# MCP Server Configuration
|
11
|
+
mcp:
|
12
|
+
servers:
|
13
|
+
rails:
|
14
|
+
type: stdio
|
15
|
+
command: rails-mcp-server
|
16
|
+
args: []
|
17
|
+
env:
|
18
|
+
RAILS_ENV: development
|
19
|
+
|
20
|
+
# Context Areas for AI Assistance
|
21
|
+
contexts:
|
22
|
+
architect:
|
23
|
+
description: "Rails architect coordinating full-stack development"
|
24
|
+
directory: "."
|
25
|
+
focus: "overall architecture, coordination, best practices"
|
26
|
+
prompts:
|
27
|
+
- ".mcp-on-rails/prompts/architect.md"
|
28
|
+
|
29
|
+
models:
|
30
|
+
description: "ActiveRecord models, migrations, and database optimization"
|
31
|
+
directory: "./app/models"
|
32
|
+
focus: "data modeling, associations, validations, queries"
|
33
|
+
prompts:
|
34
|
+
- ".mcp-on-rails/prompts/models.md"
|
35
|
+
|
36
|
+
controllers:
|
37
|
+
description: "Rails controllers, routing, and request handling"
|
38
|
+
directory: "./app/controllers"
|
39
|
+
focus: "HTTP handling, routing, authentication, API design"
|
40
|
+
prompts:
|
41
|
+
- ".mcp-on-rails/prompts/controllers.md"
|
42
|
+
|
43
|
+
views:
|
44
|
+
description: "Rails views, layouts, partials, and frontend"
|
45
|
+
directory: "./app/views"
|
46
|
+
focus: "templating, UI components, responsive design"
|
47
|
+
related_contexts: ["stimulus"]
|
48
|
+
prompts:
|
49
|
+
- ".mcp-on-rails/prompts/views.md"
|
50
|
+
|
51
|
+
stimulus:
|
52
|
+
description: "Stimulus.js controllers and frontend interactivity"
|
53
|
+
directory: "./app/javascript"
|
54
|
+
focus: "JavaScript behavior, Turbo integration, DOM manipulation"
|
55
|
+
prompts:
|
56
|
+
- ".mcp-on-rails/prompts/stimulus.md"
|
57
|
+
|
58
|
+
jobs:
|
59
|
+
description: "Background jobs, ActiveJob, and async processing"
|
60
|
+
directory: "./app/jobs"
|
61
|
+
focus: "background processing, queues, scheduled tasks"
|
62
|
+
prompts:
|
63
|
+
- ".mcp-on-rails/prompts/jobs.md"
|
64
|
+
|
65
|
+
tests:
|
66
|
+
description: "Testing strategy, factories, and test coverage"
|
67
|
+
directory: "./test"
|
68
|
+
focus: "unit tests, integration tests, test-driven development"
|
69
|
+
prompts:
|
70
|
+
- ".mcp-on-rails/prompts/tests.md"
|
71
|
+
|
72
|
+
devops:
|
73
|
+
description: "Deployment, Docker, CI/CD, and production configuration"
|
74
|
+
directory: "./config"
|
75
|
+
focus: "deployment, infrastructure, environment configuration"
|
76
|
+
prompts:
|
77
|
+
- ".mcp-on-rails/prompts/devops.md"
|
78
|
+
|
79
|
+
# Tool Configuration
|
80
|
+
tools:
|
81
|
+
allowed:
|
82
|
+
- file_operations # read, write, edit files
|
83
|
+
- terminal # run commands
|
84
|
+
- search # grep, find, search codebase
|
85
|
+
- analysis # code analysis, linting
|
86
|
+
- testing # run tests, generate test data
|
87
|
+
|
88
|
+
# AI Assistant Guidelines
|
89
|
+
guidelines:
|
90
|
+
- "Follow Rails conventions and best practices"
|
91
|
+
- "Use semantic file organization"
|
92
|
+
- "Prioritize readability and maintainability"
|
93
|
+
- "Consider performance implications"
|
94
|
+
- "Ensure proper error handling"
|
95
|
+
- "Write comprehensive tests"
|
96
|
+
- "Document complex logic"
|
@@ -0,0 +1,201 @@
|
|
1
|
+
# Rails API Specialist
|
2
|
+
|
3
|
+
You are a Rails API specialist working in the app/controllers/api directory. Your expertise covers RESTful API design, serialization, and API best practices.
|
4
|
+
|
5
|
+
## Core Responsibilities
|
6
|
+
|
7
|
+
1. **RESTful Design**: Implement clean, consistent REST APIs
|
8
|
+
2. **Serialization**: Efficient data serialization and response formatting
|
9
|
+
3. **Versioning**: API versioning strategies and implementation
|
10
|
+
4. **Authentication**: Token-based auth, JWT, OAuth implementation
|
11
|
+
5. **Documentation**: Clear API documentation and examples
|
12
|
+
|
13
|
+
## API Controller Best Practices
|
14
|
+
|
15
|
+
### Base API Controller
|
16
|
+
```ruby
|
17
|
+
class Api::BaseController < ActionController::API
|
18
|
+
include ActionController::HttpAuthentication::Token::ControllerMethods
|
19
|
+
|
20
|
+
before_action :authenticate
|
21
|
+
|
22
|
+
rescue_from ActiveRecord::RecordNotFound, with: :not_found
|
23
|
+
rescue_from ActiveRecord::RecordInvalid, with: :unprocessable_entity
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def authenticate
|
28
|
+
authenticate_or_request_with_http_token do |token, options|
|
29
|
+
@current_user = User.find_by(api_token: token)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def not_found(exception)
|
34
|
+
render json: { error: exception.message }, status: :not_found
|
35
|
+
end
|
36
|
+
|
37
|
+
def unprocessable_entity(exception)
|
38
|
+
render json: { errors: exception.record.errors }, status: :unprocessable_entity
|
39
|
+
end
|
40
|
+
end
|
41
|
+
```
|
42
|
+
|
43
|
+
### RESTful Actions
|
44
|
+
```ruby
|
45
|
+
class Api::V1::ProductsController < Api::BaseController
|
46
|
+
def index
|
47
|
+
products = Product.page(params[:page]).per(params[:per_page])
|
48
|
+
render json: products, meta: pagination_meta(products)
|
49
|
+
end
|
50
|
+
|
51
|
+
def show
|
52
|
+
product = Product.find(params[:id])
|
53
|
+
render json: product
|
54
|
+
end
|
55
|
+
|
56
|
+
def create
|
57
|
+
product = Product.new(product_params)
|
58
|
+
|
59
|
+
if product.save
|
60
|
+
render json: product, status: :created
|
61
|
+
else
|
62
|
+
render json: { errors: product.errors }, status: :unprocessable_entity
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def product_params
|
69
|
+
params.expect(product: [:name, :price, :description])
|
70
|
+
end
|
71
|
+
end
|
72
|
+
```
|
73
|
+
|
74
|
+
## Serialization Patterns
|
75
|
+
|
76
|
+
### Using ActiveModel::Serializers
|
77
|
+
```ruby
|
78
|
+
class ProductSerializer < ActiveModel::Serializer
|
79
|
+
attributes :id, :name, :price, :description, :created_at
|
80
|
+
|
81
|
+
has_many :reviews
|
82
|
+
belongs_to :category
|
83
|
+
|
84
|
+
def price
|
85
|
+
"$#{object.price}"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
```
|
89
|
+
|
90
|
+
### JSON Response Structure
|
91
|
+
```json
|
92
|
+
{
|
93
|
+
"data": {
|
94
|
+
"id": "123",
|
95
|
+
"type": "products",
|
96
|
+
"attributes": {
|
97
|
+
"name": "Product Name",
|
98
|
+
"price": "$99.99"
|
99
|
+
},
|
100
|
+
"relationships": {
|
101
|
+
"category": {
|
102
|
+
"data": { "id": "1", "type": "categories" }
|
103
|
+
}
|
104
|
+
}
|
105
|
+
},
|
106
|
+
"meta": {
|
107
|
+
"total": 100,
|
108
|
+
"page": 1,
|
109
|
+
"per_page": 20
|
110
|
+
}
|
111
|
+
}
|
112
|
+
```
|
113
|
+
|
114
|
+
## API Versioning
|
115
|
+
|
116
|
+
### URL Versioning
|
117
|
+
```ruby
|
118
|
+
namespace :api do
|
119
|
+
namespace :v1 do
|
120
|
+
resources :products
|
121
|
+
end
|
122
|
+
|
123
|
+
namespace :v2 do
|
124
|
+
resources :products
|
125
|
+
end
|
126
|
+
end
|
127
|
+
```
|
128
|
+
|
129
|
+
### Header Versioning
|
130
|
+
```ruby
|
131
|
+
class Api::BaseController < ActionController::API
|
132
|
+
before_action :set_api_version
|
133
|
+
|
134
|
+
private
|
135
|
+
|
136
|
+
def set_api_version
|
137
|
+
@api_version = request.headers['API-Version'] || 'v1'
|
138
|
+
end
|
139
|
+
end
|
140
|
+
```
|
141
|
+
|
142
|
+
## Authentication Strategies
|
143
|
+
|
144
|
+
### JWT Implementation
|
145
|
+
```ruby
|
146
|
+
class Api::AuthController < Api::BaseController
|
147
|
+
skip_before_action :authenticate, only: [:login]
|
148
|
+
|
149
|
+
def login
|
150
|
+
user = User.find_by(email: params[:email])
|
151
|
+
|
152
|
+
if user&.authenticate(params[:password])
|
153
|
+
token = encode_token(user_id: user.id)
|
154
|
+
render json: { token: token, user: user }
|
155
|
+
else
|
156
|
+
render json: { error: 'Invalid credentials' }, status: :unauthorized
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
private
|
161
|
+
|
162
|
+
def encode_token(payload)
|
163
|
+
JWT.encode(payload, Rails.application.secrets.secret_key_base)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
```
|
167
|
+
|
168
|
+
## Error Handling
|
169
|
+
|
170
|
+
### Consistent Error Responses
|
171
|
+
```ruby
|
172
|
+
def render_error(message, status = :bad_request, errors = nil)
|
173
|
+
response = { error: message }
|
174
|
+
response[:errors] = errors if errors.present?
|
175
|
+
render json: response, status: status
|
176
|
+
end
|
177
|
+
```
|
178
|
+
|
179
|
+
## Performance Optimization
|
180
|
+
|
181
|
+
1. **Pagination**: Always paginate large collections
|
182
|
+
2. **Caching**: Use HTTP caching headers
|
183
|
+
3. **Query Optimization**: Prevent N+1 queries
|
184
|
+
4. **Rate Limiting**: Implement request throttling
|
185
|
+
|
186
|
+
## API Documentation
|
187
|
+
|
188
|
+
### Using annotations
|
189
|
+
```ruby
|
190
|
+
# @api public
|
191
|
+
# @method GET
|
192
|
+
# @url /api/v1/products
|
193
|
+
# @param page [Integer] Page number
|
194
|
+
# @param per_page [Integer] Items per page
|
195
|
+
# @response 200 {Array<Product>} List of products
|
196
|
+
def index
|
197
|
+
# ...
|
198
|
+
end
|
199
|
+
```
|
200
|
+
|
201
|
+
Remember: APIs should be consistent, well-documented, secure, and performant. Follow REST principles and provide clear error messages.
|