Skip to content
CAI
Software that uses CAICheck a score

ruby-grape/grape

58.8

Adequate · 26 September 2026

10.9k

lines of production code

Ruby

primary language

4

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

This system is the Grape API framework, a Ruby library for building RESTful APIs that handles routing, request parsing, parameter validation, and response formatting. It provides features for API versioning, authentication, and entity serialization, while supporting integration with Rails and modern Ruby environments. The codebase has been significantly refactored to improve performance, thread safety, and modularity, replacing legacy components with newer libraries like Zeitwerk and dry-types.

How it got here

2010–2012 — Modernization and architectural refactoring

17 changes.

This period focused on modernizing the Grape framework by migrating to Zeitwerk autoloading, Dry::Configurable, and RSpec 3.x while dropping support for older Ruby and ActiveSupport versions. The codebase underwent significant architectural refactoring, including a complete rewrite of the middleware layer, error handling, and formatter systems to improve performance, thread safety, and extensibility. Comprehensive test coverage was added to validate these changes, particularly around API remounting, concurrency stability, and new versioning strategies.

2013–2015 — Performance optimization and validation refactoring

16 changes.

This period focused on significantly improving Grape's performance and thread safety by refactoring the validation engine to eliminate mutable state and replace the legacy Virtus library with dry-types. The work involved restructuring core components like the DSL, utilities, and authentication middleware into modular, immutable architectures, accompanied by comprehensive test coverage and benchmarking to ensure stability.

2016–2024 — Router refactoring and dependency modernization

15 changes.

This period focused on refactoring the core router and API instance logic to improve performance, encapsulation, and UTF-8 handling, alongside restructuring lazy configuration evaluation. Extensive test coverage was added for the new router architecture, validation coercers, and various integration points including Rails, Docker, and third-party libraries like Dry::Schema and Grape::Entity. The project also expanded CI support to include newer versions of Rails and Rack to ensure ongoing compatibility.

2026 — Routing refactoring and performance benchmarking

8 changes.

This period focused on refactoring the router's path assembly logic into a dedicated Pattern::Path class and introducing an immutable Options value object to prevent endpoint configuration side effects. Concurrently, the team established comprehensive benchmarking suites to measure throughput and memory usage across Ruby versions, while expanding test coverage for the parser, serve stream, and Swagger integration modules.

Features

Added Grape::Presenters::Presenter stub

A new \Grape::Presenters::Presenter\ class has been introduced in the codebase. This class provides a \represent\ method that currently acts as a pass-through, returning the input object unchanged. This serves as a base or stub implementation for the presenters module.

lib/grape/presenters · high confidence

Added benchmark scripts for route compilation, mounting, and parameter handling

New benchmark scripts have been added to the \benchmark/\ directory to measure performance characteristics of the Grape API framework. These include \compile\_many\_routes.rb\ for measuring route compilation time with 2000 routes, \nested\_params.rb\ and \simple.rb\ for request processing performance, \remounting.rb\ for comparing memory usage between Array and Set implementations during API remounting, and \large\_model.rb\ for testing complex API definitions. Additionally, \issue\_mounting.rb\ provides a test case for a specific mounting bug.

benchmark · high confidence

Initial Docker support for Grape

Added a Dockerfile and entrypoint script to enable running Grape in a containerized environment. The Dockerfile is based on Ruby 4 slim, installs system dependencies including jemalloc for memory management, and configures Ruby with frozen string literals and YJIT for performance. The entrypoint script handles gem installation and updates, then executes the provided command.

docker · high confidence

Introduce Grape::Router::Pattern::Path for route assembly

A new Grape::Router::Pattern::Path class has been added to handle the assembly of route path templates. This component takes raw paths and namespace settings to construct the route origin and suffix, managing details such as mount paths, root prefixes, path versioning, and format segments. It serves as the specific logic for building the path pattern within the router, replacing or supplementing previous inline assembly methods.

lib/grape/router/pattern · high confidence

Introduce cross-version throughput benchmark with route-shape isolation

Added a new \benchmark/version\_throughput\ suite that measures requests-per-second across Grape releases (3.0.1 through master) using four distinct route shapes: single static, single parameterized, 200 static, and 200 parameterized routes. The benchmark orchestrator (\run.rb\) runs each shape under No JIT, YJIT, and ZJIT modes, caching results per Ruby version to track performance deltas over time and prevent static-route optimizations from masking regressions in parameterized routing. Initial results show significant throughput improvements in master, particularly for many-parameterized routes (+1721% without JIT), and include detailed analysis of JIT speedups and ZJIT vs YJIT performance characteristics.

_benchmark/version\throughput · high confidence

New grape-on-rack benchmark harness for memory profiling

Added a new benchmark application in \benchmark/grape\_on\_rack\ that serves a comprehensive Grape API via Puma to enable live-server memory profiling. The harness includes a full Rack application with CORS, static file serving, and error pages, alongside mounted API endpoints covering JSON handling, file uploads, streaming, versioning, and entity serialization. It also provides a parallel load-generation script (\profile\_api\_calls.rb\) to drive requests against the server while \ruby-memory-profiler\ captures memory usage data.

_benchmark/grape\_on\rack · high confidence

Removals

Removal of Grape integration test suite

The feature tests, step definitions, and support environment configuration for the Grape integration have been removed. This eliminates the existing test coverage for the Grape gem integration, meaning the application no longer includes automated verification for this specific component.

_features, features/step\definitions, features/support · high confidence

Architecture

Grape DSL modules extracted into separate files

The Grape DSL implementation has been refactored by extracting its various components into individual, dedicated files within the \lib/grape/dsl/\ directory. This change improves code organization and maintainability by separating concerns into modules such as \Callbacks\, \Declared\, \Desc\, \Entity\, \Headers\, \Helpers\, \InsideRoute\, \Logger\, \Middleware\, \Parameters\, \RequestResponse\, \RescueOptions\, \Routing\, \Settings\, \Validations\, and \VersionOptions\. For users, this is an internal architectural change that preserves the existing public API surface while making the framework's internal structure more modular and easier to navigate.

lib/grape/dsl · high confidence

Behavioural changes

Drop support for Ruby 3.0 and ActiveSupport 7.0

The framework no longer supports Ruby 3.0 or ActiveSupport 7.0, raising the minimum required versions to ensure compatibility with newer releases. This change removes legacy compatibility code and dependencies associated with these older versions.

(repo-wide) · high confidence

Endpoint options are now handled via an immutable value object

The internal handling of endpoint configuration has been refactored to use a new immutable \Grape::Endpoint::Options\ value object. This change ensures that the \path\ array passed to an endpoint is never mutated in place, preventing side effects where constructing an endpoint could inadvertently modify the caller's original array. Additionally, route parameters, requirements, and anchor settings are now treated as first-class inputs within this structured options object, providing a more robust and predictable foundation for endpoint initialization.

lib/grape/endpoint · high confidence

Grape API remounting and lazy configuration overhaul

The Grape API class has been refactored to support remountable instances, allowing APIs to be recompiled and reconfigured at runtime without restarting the application. This change introduces a lazy evaluation system for configuration arguments, enabling dynamic values (such as those derived from a configuration hash) to be resolved only when the API is mounted or remounted. The internal setup process now records DSL steps and replays them on new instances, ensuring that changes to the API definition propagate to all mounted versions. Additionally, the API class now extends the Grape::Mountable marker module to explicitly identify Grape apps, and several internal components like content types, cookies, and declared params handling have been restructured to support this new architecture.

lib/grape · high confidence

Migrate to Zeitwerk autoloading and Dry::Configurable

Grape now uses Zeitwerk for autoloading, which improves thread safety and performance while allowing opt-in loading of test helpers like \grape/testing\ to prevent unnecessary eager loading in production. Configuration management has shifted from \ActiveSupport::Configurable\ to \Dry::Configurable\, and type validation now relies on \dry-types\ instead of Virtus. The library also adds support for the HTTP QUERY method (RFC 10008) and improves error handling by wrapping specific Rack parsing errors (such as multipart limits and parameter type errors) into \Grape::Exceptions::RequestError\ for consistent bad request responses.

lib · high confidence

Refactor API instance compilation and request handling

The core API instance logic has been restructured to improve performance and encapsulation. The \compile!\ method now returns the compiled instance directly, ensuring thread-safe lazy initialization and allowing callers to reuse the same instance without re-reading potentially nil state. Request handling in \call\ has been optimized to reduce per-request allocations by using \merge!\ instead of \merge\ for headers and resolving the \cascade\ setting once during initialization rather than per request. Additionally, the \to\_s\ method now correctly delegates to the base API instance, fixing issues where the API name was not exposed properly.

lib/grape/api · high confidence

Refactor lazy configuration evaluation to support mount-time resolution

The lazy configuration system has been restructured to allow API classes to read configuration values (such as paths or settings) at class definition time, even before the API is mounted. Previously, such reads would fail or return incorrect data because the configuration was not yet available. The new implementation introduces a \Grape::Util::Lazy::Base\ class hierarchy, including \Value\ and \Block\ subclasses, which capture the configuration path and resolve it later when the API is actually mounted. This enables more flexible and dynamic API definitions where configuration-dependent logic can be written directly in the class body without requiring explicit mounting callbacks.

lib/grape/util/lazy · high confidence

Refactor validation type coercers to use dry-types and improve performance

The validation type coercers in lib/grape/validations/types have been rewritten to replace the legacy Virtus library with dry-types, introducing new classes such as DryTypeCoercer, PrimitiveCoercer, ArrayCoercer, and CustomTypeCoercer. This change maintains backward compatibility with existing Virtus behaviors (e.g., rejecting nil in arrays, treating empty strings as nil for non-String types) while optimizing performance by reducing per-request allocations and avoiding unnecessary round-trips for already-typed values. The new architecture supports nested arrays, custom types with parse methods, and multiple type variants, ensuring robust coercion and validation for complex parameter structures.

lib/grape/validations/types · high confidence

Refactored API versioning middleware with new Accept-Version header support and performance optimizations

The versioning middleware has been restructured into a modular strategy pattern (Base, Header, Param, Path, and new AcceptVersionHeader) to improve maintainability and performance. A new Accept-Version header strategy allows clients to specify the API version directly via the Accept-Version header, in addition to the existing Accept header, query parameter, and path-based versioning methods. The refactoring introduces precomputed content types and caching for media type matching to reduce per-request allocations and speed up request processing. Invalid or malformed Accept headers are now handled more gracefully, returning appropriate 406 Not Acceptable errors instead of causing 500 Internal Server Errors, especially when strict mode is enabled. The base middleware class now uses a Data value object for options, and various micro-optimizations (such as using each instead of reduce, and match? instead of =\~) have been applied to the request hot path.

lib/grape/middleware/versioner · high confidence

Refactored Grape exception hierarchy and error response handling

The exception system in lib/grape/exceptions has been restructured to improve consistency and performance. A new Grape::Exceptions::Base class now serves as the foundation for all framework errors, providing unified I18n translation support and structured message composition. Specific exceptions like Validation, RequestError, and InvalidAcceptHeader have been updated to leverage this base, ensuring standardized status codes and headers. Additionally, a new Grape::Exceptions::ErrorResponse value object replaces the previous implicit hash-based error passing, offering a cleaner interface for middleware to handle error payloads. Validation errors now skip unnecessary backtrace capture to optimize the hot path for 400 Bad Request responses.

lib/grape/exceptions · high confidence

Refactored authentication middleware with compile-time strategy validation

The authentication middleware has been restructured to validate the auth strategy type at compile time rather than runtime. When an unknown strategy is specified, the system now raises a Grape::Exceptions::UnknownAuthStrategy exception immediately, preventing silent failures or unexpected behavior during request processing. This change also introduces a cleaner separation between the DSL for defining auth rules and the base middleware class, improving maintainability and error handling for API developers.

lib/grape/middleware/auth · high confidence

Refactored error formatting into a modular class hierarchy

The error formatting logic has been restructured from a procedural style into a class-based hierarchy under \Grape::ErrorFormatter\, introducing a \Base\ class and specific formatters for JSON, XML, TXT, and SerializableHash. This change standardizes how error responses are constructed, ensuring that the \Base\ class handles common concerns like extracting entity presenters, wrapping messages, and conditionally including backtraces or original exceptions. Users will see consistent error response structures across different content types, with JSON errors now properly handling UTF-8 encoding and XML errors using a standardized root element, while the underlying implementation becomes more extensible for custom formatters.

_lib/grape/error\formatter · high confidence

Refactored formatter architecture with new base class and dedicated formatters

The formatter system has been restructured to use a new \Grape::Formatter::Base\ class that handles automatic registration of formatter subclasses. This change introduces dedicated formatter classes for JSON (\Json\), XML (\Xml\), plain text (\Txt\), and serializable hashes (\SerializableHash\), replacing the previous monolithic implementation. The JSON formatter now supports \Grape::PrecompiledJson\ objects and uses \Grape::Json.dump\ as a fallback, while the XML formatter raises an \InvalidFormatter\ exception for objects that do not support \to\_xml\. The \SerializableHash\ formatter adds logic to handle objects with \serializable\_hash\ methods, arrays of such objects, and hashes, ensuring consistent JSON output for these types.

lib/grape/formatter · high confidence

Refactored parameter validation internals for performance and thread safety

The parameter validation system has been refactored to improve performance and thread safety. Mutable per-request state (such as index tracking for nested arrays) has been moved into a fiber-local \ParamScopeTracker\, allowing shared validator instances to be reused across requests without race conditions. A new \AttributesIterator\ handles array traversal and index bookkeeping, while immutable value objects (\ValidationsSpec\, \CoerceOptions\, \SharedOptions\) replace mutable hashes for declaration data, reducing allocation overhead. Additionally, the \ContractScope\ class now supports integrating Dry::Schema contracts for parameter validation, and \ParamsDocumentation\ has been updated to include \except\_values\ in generated API docs.

lib/grape/validations · high confidence

Refactored request body parsing into a modular, extensible parser system

The request body parsing logic has been restructured into a dedicated \lib/grape/parser\ directory, introducing a base class that supports dynamic registration of parser implementations. This change replaces the previous monolithic approach with specific parsers for JSON and XML, which now explicitly handle parse errors by raising \InvalidMessageBody\ exceptions to ensure consistent bad request responses. This modular design allows for easier extension and maintenance of content-type handling within the API.

lib/grape/parser · high confidence

Refactored settings, performance, and API description utilities

This change introduces a new Grape::Util::ApiDescription class to handle endpoint descriptions, replacing the previous StrictHashConfiguration approach and deprecating the 'default' key in favor of 'default\_response'. It significantly improves performance and memory usage by implementing lazy allocation for inheritable settings, optimizing path normalization with a fast-path check, and using plain Hashes for registries instead of indifferent accessors. The update also adds a Cache utility for synchronized lookups, a DeepFreeze module for immutable data structures, and a ShadowedRescueHandlers utility that warns users when broader rescue\_from handlers obscure more specific ones. Additionally, it standardizes header handling by using Rack::Headers (Rack 3) or Rack::Utils::HeaderHash (Rack 2) and extracts translation logic into a dedicated utility.

lib/grape/util · high confidence

Rewritten middleware architecture with structured options and performance optimizations

The middleware layer in lib/grape/middleware has been completely rewritten to improve performance and code clarity. A new base middleware class introduces a structured options system using Ruby Data classes, allowing for better configuration management and backward compatibility. The error handling middleware now supports backtrace inclusion, custom error formatters, and improved failsafe responses. The formatter middleware has been optimized with precomputed content type caches, case-insensitive Accept header matching, and reduced per-request allocations. The middleware stack now supports inserting middlewares before or after existing ones, and includes new filter middleware for before/after hooks. These changes result in faster request processing, better error handling, and more flexible middleware configuration.

lib/grape/middleware · high confidence

Router refactored with new route classes and UTF-8 path param handling

The router now uses a new class hierarchy (BaseRoute, Route, GreedyRoute) and an inlined Mustermann pattern matcher to improve encapsulation and performance. A key behavioral change is that path parameters are now explicitly tagged as UTF-8, ensuring consistent encoding handling compared to query and body parameters. The router also optimizes matching by grouping routes into buckets based on literal path segments and skips parameter extraction for routes with no captures.

lib/grape/router · high confidence

Validators refactored into a frozen, definition-time architecture with new validation options

The validation engine in lib/grape/validations/validators has been rewritten to instantiate validators at definition time and freeze their state, eliminating per-request mutable state and reducing allocations. This refactor introduces several new validation capabilities: the length validator now supports an is: parameter for exact-length checks and only applies to parameters supporting a length method; the values validator now considers the allow\_blank option and supports one-arity procs as per-element predicates; the exactly\_one\_of and mutually\_exclusive validators now work within groups; and a new oneof: option allows polymorphic Hash parameters to match variant schemas. Additionally, the allow\_blank validator was added, the as validator is now a no-op placeholder, and the hash\_elements validator ensures array elements in blocks are Hashes.

lib/grape/validations/validators · high confidence

Test coverage

Added comprehensive test coverage for Grape exception classes; Added concurrency and remounting stability tests; Added integration test for multi\_xml XML parsing; Added integration tests for Dry::Schema contract validation; Added integration tests for Grape API behavior; Added integration tests for Grape::Entity autodetection and representation; Added integration tests for Grape::Json multi\_json backend; Added integration tests for GrapeSwagger documentation generation; Added integration tests for Hashie::Mash parameter building; Added integration tests for Rails mounting and Railtie behavior; Added shared examples for API versioning behavior; Added specs for the Grape DSL modules; Added test coverage for Grape API validation, mounting, and routing behaviors; Added test coverage for Grape middleware components; Added test coverage for Grape middleware versioning strategies; Added test coverage for Grape utility modules; Added test coverage for Grape::ServeStream components; Added test coverage for the refactored Grape router components; Added test coverage for validation validators; Added test support helpers for authentication, versioning, and response handling; Added tests for Grape JSON parser behavior; Added tests for Grape::Presenters::Presenter; Added tests for Grape::Router::Pattern::Path behavior; Added tests for endpoint parameter declaration, logging, and path options; Added tests for the Grape authentication middleware; Added tests for validation thread safety, adversarial nesting, and type coercion; Added unit tests for validation type coercers; Modernized RSpec test configuration and added code coverage.

Dependencies

Add CI gemfiles for Rails 7.2, 8.0, 8.1, and Rack 3.x

The project adds new Appraisal gemfiles to expand continuous integration coverage, specifically introducing support for Rails 7.2, 8.0, and 8.1, as well as Rack versions 3.0, 3.1, and 3.2. These files ensure the library is tested against the latest major versions of its core dependencies, including specific handling for JSON gem compatibility in Rails 7.2 and 8.0.

gemfiles · high confidence

Update runtime dependencies and Ruby version requirements

The Grape gem now requires Ruby 3.3.1 or higher and has updated its core dependencies to activesupport \>= 7.2, dry-configurable \>= 1.0, dry-types \>= 1.1, mustermann \>= 4.0, rack \>= 2.2.4, and zeitwerk \>= 2.6. Development and testing tooling has also been refreshed, including RuboCop 1.90.0, RSpec \~\> 3.13, and rack-test \~\> 2.1.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

This is the PUBLIC form of this artifact. Findings are listed in full, but the details of SECURITY findings — which rule fired, in which file, on which line, and how to fix it — are deliberately withheld, and any secret-scanner results are excluded entirely. Where detail is absent here it was REMOVED FOR PUBLICATION; it is not missing from the analysis. The complete artifact is available from the repository owner.

Score

  • CAI 46 → 59 (+13.1)
  • Rubric changed (rubric-2026.08.15 → rubric-2026.09.15) — scores are not directly comparable.

Lenses

  • Code Health 100 → 98 (-1.6)
  • Architecture 96 → 96 (+0.4)
  • Maturity 57 → 55 (-2.2)
  • Readiness 18 → 43 (+25.7)
  • Security 74 → 85 (+11.1)

Resolved (16)

  • Coverage not measured — test suite did not build
  • Dimension evaluation failed
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • Low IaC: DS-0026 (docker/Dockerfile)
  • No exposed public API
  • No tests found
  • Test reliability not included

New (32)

  • Ambiguous distinction between call and call!. In many Ruby/Rack contexts, call! implies a stricter or error-raising variant, but without documentation, it is unclear if they differ in behavior (e.g., exception handling) or if one is deprecated. This creates confusion for implementers extending or wrapping endpoints.
  • Change coupling: attributes_iterator.rb ↔ multiple_params_base.rb (lib/grape/validations/attributes_iterator.rb)
  • Change coupling: header.rb ↔ param.rb (lib/grape/middleware/versioner/header.rb)
  • Change coupling: presence_validator.rb ↔ regexp_validator.rb (lib/grape/validations/validators/presence_validator.rb)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • …and 12 more

Changes since last survey

  • 150 commits — 147 feature/other, 3 fixes

By area

  • (root) — 87 commits
  • lib/grape — 34 commits
  • (repo) — 11 commits
  • spec/grape — 9 commits
  • benchmark/version_throughput — 7 commits
  • benchmark/grape_on_rack — 1 commit
  • spec/integration — 1 commit

Notable commits

  • fix: Merge pull request #2899 from ruby-grape/fix/deprecation-horizon
  • fix: Merge pull request #2986 from ruby-grape/fix/header-versioner-vendor-case
  • fix: Remove deprecation test. Fixed in 2.2.0 (#2854)
  • change: Accept a beginless range of values for a bare Array type (#2992)
  • change: Add Grape::PrecompiledJson for bodies that are already JSON (#2869)
  • change: Add support for the HTTP QUERY method (RFC 10008)
  • change: Add the grape-on-rack app as a live-server memory profiling harness (#3008)
  • change: Address review: UPGRADING entry, and rebuild desc options instead of mutating
  • change: Answer 500 when an error response cannot be rendered (#2840)
  • change: Answer Route#success and #failure whichever way desc spelled them (#2859)
  • change: Answer a DELETE whose body holds invalid bytes instead of raising (#2954)
  • change: Answer a HEAD request for a path no route matches without a body (#2958)
  • change: Answer params and versions holding invalid bytes instead of raising (#3006)
  • change: Bench 4.0.0 alongside master in the version throughput benchmark (#2914)
  • change: Bench ZJIT alongside YJIT in the version benchmark (#2913)
  • change: Bench route shapes in separate tables in the version throughput benchmark (#2941)
  • change: Build an error response's backtrace only when it will be rendered (#2878)
  • change: Check Boolean values directly instead of through Boolean.build (#2982)
  • change: Check a group's type in one place for requires and optional (#2864)
  • change: Collapse the lazy configuration value tree into one path-based Value (#2950)
  • …and 130 more

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

ruby-grape/grape was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 26 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit db77d880fae4d620c0aef78b74908137f60a49d7 — the exact code this score is about.
  • Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-d0929f7ac71f.