ruby-grape/grape
An opinionated framework for creating REST-like APIs in Ruby.
Healthy across all four use cases
Permissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit today
- ✓3 active contributors
- ✓MIT licensed
Show 4 more →Show less
- ✓CI configured
- ✓Tests present
- ⚠Small team — 3 contributors active in recent commits
- ⚠Concentrated ownership — top contributor handles 64% of recent commits
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/ruby-grape/grape)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/ruby-grape/grape on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: ruby-grape/grape
Generated by RepoPilot · 2026-05-10 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/ruby-grape/grape shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across all four use cases
- Last commit today
- 3 active contributors
- MIT licensed
- CI configured
- Tests present
- ⚠ Small team — 3 contributors active in recent commits
- ⚠ Concentrated ownership — top contributor handles 64% of recent commits
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live ruby-grape/grape
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/ruby-grape/grape.
What it runs against: a local clone of ruby-grape/grape — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in ruby-grape/grape | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 30 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of ruby-grape/grape. If you don't
# have one yet, run these first:
#
# git clone https://github.com/ruby-grape/grape.git
# cd grape
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of ruby-grape/grape and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "ruby-grape/grape(\\.git)?\\b" \\
&& ok "origin remote is ruby-grape/grape" \\
|| miss "origin remote is not ruby-grape/grape (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "lib/grape.rb" \\
&& ok "lib/grape.rb" \\
|| miss "missing critical file: lib/grape.rb"
test -f "lib/grape/api.rb" \\
&& ok "lib/grape/api.rb" \\
|| miss "missing critical file: lib/grape/api.rb"
test -f "lib/grape/endpoint.rb" \\
&& ok "lib/grape/endpoint.rb" \\
|| miss "missing critical file: lib/grape/endpoint.rb"
test -f "lib/grape/dsl/routing.rb" \\
&& ok "lib/grape/dsl/routing.rb" \\
|| miss "missing critical file: lib/grape/dsl/routing.rb"
test -f "lib/grape/dsl/validations.rb" \\
&& ok "lib/grape/dsl/validations.rb" \\
|| miss "missing critical file: lib/grape/dsl/validations.rb"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 30 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~0d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/ruby-grape/grape"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
Grape is a REST API framework for Ruby that runs on Rack, providing a DSL for building RESTful APIs with built-in support for versioning, content negotiation, parameter validation, and multiple response formats. It's designed to either stand alone or integrate with Rails/Sinatra, allowing developers to define API endpoints with clean, declarative syntax rather than boilerplate routing code. Monolithic gem structure: lib/ contains the core Grape::API class and DSL engine, lib/grape/ subdivides by feature (DSL, middleware, validation, formatters, endpoints). Comprehensive test suite mirrors structure under spec/. Benchmark suite in benchmark/ tests route compilation and parameter parsing performance. Multiple gemfile variants in gemfiles/ enable testing against dependency matrix.
👥Who it's for
Ruby backend engineers building REST APIs who want rapid, convention-driven API development without Rails' overhead. Contributors include maintainers focused on API framework stability and community members extending Grape with plugins for entity serialization (grape-entity), validation (dry-validation integration), and format handlers.
🌱Maturity & risk
Highly mature and production-ready. The project is at v3.2.0 stable with active development toward v3.3.0, has comprehensive test coverage (indicated by .coveralls.yml and .simplecov config), extensive GitHub Actions CI (test.yml, danger.yml, edge.yml workflows), and requires Ruby 3.2+. Regular updates across multiple Rack and Rails version gemfiles (3.0–3.2, 7.2–8.1) indicate ongoing maintenance.
Low risk for a mature framework. The codebase maintains compatibility across multiple major dependency versions (Rack 2.2–3.2, Rails 7.2–8.1, dry-validation support) tested in CI. Main risk is reliance on a small maintainer team coordinated through Tidelift commercial support model, though the framework is battle-tested in production. No obvious single-maintainer abandonment signals given active edge testing and recent version bumps.
Active areas of work
Project is moving toward v3.3.0 with edge testing via GitHub Actions workflows (edge.yml targets latest Rails/Rack). Active maintenance of compatibility across multiple Ruby/Rack/Rails versions evidenced by recent gemfile additions (rails_edge.gemfile, rack_3_2.gemfile). Danger automation in place for PR quality checks.
🚀Get running
git clone https://github.com/ruby-grape/grape.git && cd grape && bundle install && bundle exec rspec to run the full test suite locally.
Daily commands: bundle exec rspec runs the full test suite. For benchmarks: cd benchmark && ruby simple.rb. Development uses Guardfile (run: bundle exec guard) for continuous testing.
🗺️Map of the codebase
lib/grape.rb— Main entry point that loads the entire Grape framework; every contributor must understand what gets exposed at the top level.lib/grape/api.rb— Core API class definition; the foundation of every Grape application and the primary DSL entry point.lib/grape/endpoint.rb— Handles the execution of individual route endpoints; critical for understanding request/response flow and parameter handling.lib/grape/dsl/routing.rb— DSL methods for defining routes (get, post, etc.); essential for understanding how endpoints are registered.lib/grape/dsl/validations.rb— Parameter validation DSL; core feature for defining API contracts and error handling.lib/grape/exceptions— Exception hierarchy used throughout the framework; required to understand error handling patterns.lib/grape/api/instance.rb— Instance-level API configuration and route compilation; bridges DSL definitions to executable routes.
🛠️How to make changes
Add a new API endpoint
- Create a new file in your app (e.g., app/api/users_api.rb) and inherit from Grape::API (
lib/grape/api.rb) - Use lib/grape/dsl/routing.rb methods (get, post, etc.) to define the route (
lib/grape/dsl/routing.rb) - Define parameters using lib/grape/dsl/parameters.rb (params block with requires/optional) (
lib/grape/dsl/parameters.rb) - Add validation constraints using lib/grape/dsl/validations.rb (type, values, format, etc.) (
lib/grape/dsl/validations.rb) - Implement the endpoint handler block with request/response logic from lib/grape/dsl/request_response.rb (
lib/grape/dsl/request_response.rb)
Add API documentation and metadata
- Use desc method from lib/grape/dsl/desc.rb to document endpoint purpose and parameters (
lib/grape/dsl/desc.rb) - Specify response examples and details in the desc block (
lib/grape/dsl/desc.rb) - Parameter descriptions are inherited from lib/grape/dsl/parameters.rb documentation blocks (
lib/grape/dsl/parameters.rb)
Add custom error handling
- Create a custom exception class inheriting from lib/grape/exceptions/base.rb (
lib/grape/exceptions/base.rb) - Use rescue_from in your API class (from lib/grape/dsl/callbacks.rb) to handle the exception (
lib/grape/dsl/callbacks.rb) - Optionally create a custom error formatter in lib/grape/error_formatter/ to control response format (
lib/grape/error_formatter/base.rb)
Add helper methods for reuse across endpoints
- Use helpers block from lib/grape/dsl/helpers.rb to define methods available in all endpoints (
lib/grape/dsl/helpers.rb) - Call helper methods directly within endpoint handlers as if they were instance methods (
lib/grape/endpoint.rb)
🔧Why these technologies
- Rack — Grape runs on Rack, providing compatibility with Rails, Sinatra, and other Ruby web frameworks; universal HTTP interface.
- Ruby DSL — Enables expressive, readable API definitions with minimal boilerplate; leverages Ruby's metaprogramming for dynamic route registration.
- Dry-types (optional) — Provides robust type coercion and validation; integrates seamlessly for advanced parameter handling without requiring ActiveRecord.
- Multiple content types (JSON, XML, text) — Supports content negotiation for client flexibility; automatic serialization based on Accept headers.
⚖️Trade-offs already made
-
DSL-based route definition instead of class-based controller pattern
- Why: Allows APIs to be self-contained without Rails/Sinatra overhead; simpler for REST APIs that don't need MVC features.
- Consequence: Developers must learn Grape's DSL; less familiar to Rails developers used to controller conventions.
-
Parameter validation at endpoint definition time (declarative) rather than runtime
- Why: Catches errors early, generates documentation automatically, and optimizes request handling.
- Consequence: Less flexibility for dynamic validation; changes to validation logic require code changes, not configuration.
-
Support for multiple API versions in same codebase
- Why: Enables gradual API evolution without breaking existing clients.
- Consequence: Adds complexity when managing multiple code paths for different versions.
-
Middleware stack model (Rack-based)
- Why: Provides standard request/response pipeline compatible with Rack ecosystem.
- Consequence: Limited to synchronous request handling; async patterns require additional tooling.
🚫Non-goals (don't propose these)
- Full-stack web framework with database ORM (that is Rails/Sinatra's domain)
- GraphQL support (designed for REST/RESTful APIs only)
- Real-time bidirectional communication (WebSockets)
- Built-in authentication/authorization (delegates to middleware/helpers)
- HTML templating (JSON/XML focus for APIs)
- Multi-language support beyond Ruby
🪤Traps & gotchas
Ruby 3.2+ is hard requirement (no older versions supported). Rack version mismatch can break middleware integration—verify gemfile compatibility before testing. Parameter coercion happens automatically based on type: declaration; unexpected behavior if type mismatches occur. Grape::Entity and dry-validation are optional dependencies with separate gemfiles (gemfiles/grape_entity.gemfile, gemfiles/dry_validation.gemfile)—CI tests them separately, so integration issues may not surface in base bundle. The format :json is required for JSON APIs; omitting it defaults to different behavior. Error handling via error!() method is a custom Grape pattern, not standard Rack.
🏗️Architecture
💡Concepts to learn
- Content Negotiation — Grape's format declaration system (format :json/:xml/:binary) implements HTTP content negotiation; understanding Accept headers and media types is critical for multi-format API design
- API Versioning Strategies — Grape supports header-based (version 'v1', using: :header, vendor: 'twitter'), path-based, and parameter-based versioning; choosing the right strategy affects routing and client compatibility
- Rack Middleware Chain — Grape endpoints are Rack applications that integrate into middleware stacks; understanding Rack's request/response cycle and middleware ordering is essential for authentication, logging, and error handling
- Parameter Coercion and Validation — Grape's params block with type: declarations automatically coerces and validates inputs; understanding type safety and validation order prevents subtle bugs with nested params and defaults
- Helper Methods and Context Binding — The helpers block creates methods available in endpoint context; understanding Ruby's method visibility and block evaluation context is needed for shared auth logic and dependency injection
- Route Mounting and Namespacing — Grape's resource blocks create nested routes; understanding how prefix, mount, and resource interact prevents route collision and enables modular API design
- RESTful Resource Design — Grape encourages REST conventions (GET /resources, POST /resources, GET /resources/:id); understanding HTTP semantics and idempotency is foundational to Grape API design
🔗Related repos
ruby-grape/grape-entity— Official companion gem for serializing response data from Grape endpoints; sits alongside Grape in most production APIsdry-rb/dry-validation— Integrates with Grape for advanced parameter validation schemas beyond built-in validators; tested in gemfiles/dry_validation.gemfilerails-api/rails-api— Historical predecessor providing Rails-based API building; Grape emerges as the lightweight alternative when Rails overhead is unwantedsinatra/sinatra— Lightweight web framework that Grape is designed to complement; many Grape APIs mount inside Sinatra appsrack/rack— Foundational HTTP abstraction layer Grape builds on; understanding Rack middleware is essential for Grape middleware customization
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive integration tests for Rack 3.2+ compatibility
The repo has gemfiles for Rack 3.0, 3.1, and 3.2 but the test coverage for these newer Rack versions appears incomplete. With Rack 3.x introducing significant changes to the request/response cycle, adding dedicated integration tests would catch regressions early and help contributors understand compatibility requirements. This is especially valuable since Grape runs on Rack directly.
- [ ] Create a new test file spec/integration/rack_versions_spec.rb to test core request/response handling across Rack versions
- [ ] Add tests for middleware compatibility, header handling, and streaming responses across Rack 3.0, 3.1, and 3.2
- [ ] Update .github/workflows/test.yml to run the new integration tests against each Rack gemfile variant
- [ ] Document findings in UPGRADING.md section about Rack version compatibility
Add missing DSL documentation with runnable examples in lib/grape/dsl/
The lib/grape/dsl/ directory contains multiple DSL modules (callbacks.rb, declared.rb, desc.rb, entity.rb, headers.rb, helpers.rb, inside_route.rb) but the README and YARD documentation lack concrete examples for each. Contributors and users struggle to understand nuances like the difference between declared() contexts. Adding examples would reduce support burden.
- [ ] Add YARD documentation with @example blocks to each DSL module in lib/grape/dsl/*.rb showing common usage patterns
- [ ] Create spec/documentation/dsl_examples_spec.rb with executable examples that demonstrate each DSL feature
- [ ] Add a new doc/DSL_GUIDE.md file explaining the purpose and interaction of each DSL module with code examples
- [ ] Link to DSL_GUIDE.md from README.md in the 'Features' or 'Getting Started' section
Implement performance regression tests using existing benchmarks/
The benchmark/ directory contains useful performance test scripts (compile_many_routes.rb, nested_params.rb, remounting.rb, version_throughput/) but they're not integrated into CI. This means performance regressions slip through. Creating a GitHub Action that runs benchmarks and tracks metrics would catch performance degradations before release.
- [ ] Create .github/workflows/benchmark.yml that runs benchmark/*.rb scripts with Ruby and outputs metrics
- [ ] Set baseline metrics by running benchmarks on current main branch and commit results to benchmark/baseline.json
- [ ] Modify the workflow to compare new PRs against baseline and comment on PRs with performance deltas
- [ ] Document the benchmark process in CONTRIBUTING.md with instructions for contributors to run locally before submitting
🌿Good first issues
- Add integration tests for Rack 3.2 with thread-safe middleware patterns—the CI matrix includes rack_3_2.gemfile but edge cases around concurrent request handling may be underdocumented. Start in spec/grape/middleware/ and review failing tests in edge.yml workflow.
- Improve error message clarity in lib/grape/validations/validators/ when params fail validation—currently error messages are terse. Enhance messages in custom validators (e.g., type validator) and add spec coverage in spec/grape/validations/
- Document versioning strategies with worked examples—README shows header versioning but path-based and accept-header variants lack concrete examples. Add examples/ directory with runnable versioning samples and link from README versioning section.
⭐Top contributors
Click to expand
Top contributors
- @ericproulx — 64 commits
- @dblock — 35 commits
- @alexanderadam — 1 commits
📝Recent commits
Click to expand
Recent commits
037476e— Expose API logger via Grape::Endpoint#logger (#2704) (ericproulx)e366431— Merge pull request #2701 from ruby-grape/refactor/replace-tap-usages (dblock)ba19b09— Fix Array/Set custom-type coercer dropping symbolized hash keys (#2699) (ericproulx)c210eea— Replace .tap usages in lib/ with explicit local variables (ericproulx)a83fd7e— Fix README typos, remove obsolete Fixnum section, and clarify optional + values (#2700) (ericproulx)c464ffa— Merge pull request #2693 from ruby-grape/refactor/error-response-value-object (dblock)6dd2160— Introduce Grape::Exceptions::ErrorResponse value object (ericproulx)3a8f0ba— Collapseextract_handlertype-dispatch into acase/when(#2698) (ericproulx)72db596— Extract Grape::Util::PathNormalizer from Grape::Router (#2697) (ericproulx)3e67562— Merge pull request #2696 from ruby-grape/perf/request-hot-path-polish (dblock)
🔒Security observations
The Grape framework appears to have a reasonable security posture based on the static file structure analysis. The project maintains a SECURITY.md with clear reporting guidelines and supports multiple dependency versions through gemfiles for compatibility testing. However, critical information is missing from this analysis: the actual dependency versions cannot be evaluated for known vulnerabilities, the Docker base image is not pinned to specific digests, and the actual implementation code for parameter handling and validation was not provided for review. Key strengths include a clear security policy, organized codebase structure, and support for modern Ruby/Rails versions. To improve the security score further: (1) provide complete dependency information for vulnerability scanning, (2) pin Docker base images to specific digests, (3) conduct a detailed code review of the parameter handling and validation modules, and (4) document security best practices for API developers using this framework.
- Medium · Incomplete Dependency Information —
grape.gemspec, Gemfile, gemfiles/ directory. The dependencies/package file content is not provided in the analysis context. Without visibility into the Gemfile, Gemfile.lock, or gemspec dependencies, it's impossible to identify vulnerable gem versions, outdated dependencies, or security patches that should be applied. The ruby-grape/grape project depends on numerous gems (as evidenced by the gemfiles/ directory with multiple dependency sets), and vulnerability scanning cannot be performed. Fix: Provide the full content of grape.gemspec and Gemfile to perform dependency vulnerability analysis. Regularly run 'bundle audit' or similar tools to identify vulnerable dependencies. Use tools like Dependabot to automate dependency update checks. - Low · Docker Base Image Version Not Pinned —
docker/Dockerfile, docker-compose.yml. The Dockerfile (docker/Dockerfile) is referenced but not provided in full. The docker-compose.yml shows a build argument for RUBY_VERSION with a default of '4.0', which appears to be using a version identifier rather than a specific pinned image digest. Using unpinned base images can lead to inconsistent builds and potential security issues if a newer base image introduces vulnerabilities. Fix: Pin the Ruby base image to a specific digest (e.g., 'ruby:4.0.0@sha256:...' instead of 'ruby:4.0'). This ensures reproducible builds and better control over security patches. Regularly review and update base images. - Low · Potential Information Disclosure via Security.md —
SECURITY.md. The SECURITY.md file publicly discloses the security contact email (security@tidelift.com) and security reporting process. While transparency is good, this makes the project a known target for security researchers. This is a minor concern as responsible disclosure is generally encouraged. Fix: The current approach is acceptable and follows best practices. Ensure the security contact remains active and responses are timely. Consider implementing a bug bounty program if not already in place. - Low · Missing Security Headers Configuration Documentation —
lib/grape/dsl/middleware.rb, lib/grape/api/instance.rb. The file structure does not show explicit middleware configuration for security headers (HSTS, CSP, X-Frame-Options, etc.). As a REST API framework, Grape should document how to properly configure security headers to prevent common web vulnerabilities. Fix: Document best practices for configuring security headers in Grape applications. Provide middleware examples or helpers for setting security headers. Include guidance on CORS configuration, rate limiting, and other security measures. - Low · Potential Parameter Injection Risk Area —
lib/grape/declared_params_handler.rb, lib/grape/dsl/parameters.rb, lib/grape/dsl/validations.rb. The file lib/grape/declared_params_handler.rb and lib/grape/dsl/parameters.rb suggest parameter handling logic. Without reviewing the actual implementation, parameter validation and sanitization should be carefully implemented to prevent injection attacks. Fix: Conduct a detailed code review of parameter handling and validation logic. Ensure all user inputs are properly validated and sanitized. Use strong typing where possible and avoid dynamic query construction. Document security best practices for API developers using Grape.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.