graphiti-api/graphiti
64.3
Adequate · 20 September 2026
13.2k
lines of production code
Ruby
primary language
1
measurement over time
What this system is
Graphiti is a Ruby library that implements the JSON:API specification, providing a declarative DSL for defining resources, handling serialization, and managing persistence across various data sources. It supports ActiveRecord and remote APIs, offering features like filtering, sorting, pagination, and complex association sideloading. The system includes a CLI for schema validation, comprehensive testing helpers, and tools for auditing and performance monitoring.
How it got here
2016–2017 — Graphiti rebrand and consolidation
12 changes.
The project rebranded from jsonapi\_compliable to Graphiti and consolidated multiple separate gems into a single core library. This period involved significant infrastructure modernization, including CI migration and documentation integration, alongside the removal of legacy JSON:API-specific code. Comprehensive test suites were added to verify the new unified architecture and core features.
2018 — CLI tooling and adapter abstraction
14 changes.
This period focused on establishing a command-line interface for schema validation and restructuring the core library around a modular adapter abstraction layer. Significant work involved refactoring scoping, sideloading, and resource configuration into distinct components to improve maintainability and support features like public IDs and remote API querying.
2019–2026 — Graphiti 2.0 release and stabilization
15 changes.
This period focused on the development and release of Graphiti 2.0, introducing major architectural changes such as explicit Rails controller integration, modular request validation, and offset-based pagination support. The work also included extensive testing infrastructure improvements, including stress tests, performance monitoring, and expanded Rails version compatibility, alongside a comprehensive documentation migration to Docusaurus and new developer tooling.
Features
Added plain Ruby and Sinatra examples
New in-tree examples demonstrate using Graphiti outside of Rails. The plain Ruby example shows a standalone script querying an in-memory SQLite database with filtering, sorting, pagination, and nested sideloads. The Sinatra example provides a runnable HTTP server exposing JSON:API endpoints, including a web-based explorer page and a smoke test for validation.
examples · high confidence
Executable entry point for the Graphiti CLI tool
A new executable script named 'graphiti' has been added to the 'exe' directory. This script serves as the entry point for the command-line interface, bootstrapping the Ruby environment and invoking the Graphiti CLI application.
exe · high confidence
New CLI tool for schema compatibility checking
A new command-line interface (CLI) is available to validate API schema changes. The \schema\_check\ command compares an old and a new schema (provided as file paths or URLs) and exits with an error if any backwards-incompatible changes are detected, helping teams catch breaking changes before deployment.
lib/graphiti · high confidence
New Graphiti Rake tasks for schema management, auditing, and debugging
A new \lib/tasks/graphiti.rake\ file introduces several CLI tasks to streamline Graphiti usage without a web server. Users can now generate and validate API schemas via \graphiti:schema:generate\ and \graphiti:schema:check\, ensuring schema compatibility and persistence. The \graphiti:audit\ task helps identify relationship issues and provides connection pool advisories, while \graphiti:request\ and \graphiti:benchmark\ allow for direct execution and performance testing of API endpoints.
lib/tasks · high confidence
New RSpec matchers and helpers for testing Graphiti resources
The spec helpers now include dedicated RSpec matchers to validate resource relationships (belong\_to, has\_many, has\_one) and attributes (expose\_attribute, filter\_attribute), allowing tests to assert on DSL options like primary keys, foreign keys, and filter settings. Additionally, helper methods for parsing JSON:API responses (json, jsonapi\_data, sideload) and HTTP verbs (jsonapi\_get, jsonapi\_post, etc.) have been added to streamline request/response testing, alongside a schema-checking task to verify schema compatibility without running the full test suite.
_lib/graphiti/spec\helpers · high confidence
New Rails application template for Graphiti 2.0
A new Rails application template has been added to scaffold projects with Graphiti 2.0, including dependencies like Vandal UI and Kaminari, and pre-configured RSpec helpers with FactoryBot and DatabaseCleaner.
templates · high confidence
New adapter implementations for ActiveRecord, Remote APIs, and Null passthrough
This change introduces three new adapter classes in the \lib/graphiti/adapters\ directory: \Graphiti::Adapters::ActiveRecord\, \Graphiti::Adapters::GraphitiAPI\, and \Graphiti::Adapters::Null\. The ActiveRecord adapter provides concrete implementations for filtering, ordering, and pagination using Arel, including specific handling for string matching (with version-dependent escaping), datetime precision, and public ID filtering. The GraphitiAPI adapter enables querying remote resources by building URLs, handling JSON responses, and mapping remote data to local entities, with a default page size of 999. The Null adapter acts as a pass-through, ignoring filter and sort operations to support services that do not natively support these features.
lib/graphiti/adapters · high confidence
New extensions for boolean, extra, and temporary ID attributes
Added three new extensions to the Graphiti library: BooleanAttribute allows mapping Ruby predicate methods (e.g., \active?\) to \is\_\ prefixed attributes; ExtraAttribute enables conditional rendering of computationally expensive attributes based on user request or specific options; and SerializableTempId injects a \temp-id\ field into resource identifiers to support nested POST operations where temporary IDs need to be mapped to persisted IDs.
lib/graphiti/extensions · high confidence
New generators for API specs, resource specs, and locale files
The Graphiti generator suite has been expanded to include dedicated generators for API request specs (ApiTestGenerator), resource specs (ResourceTestGenerator), and error locale files (LocaleGenerator). The API test generator creates RSpec request specs for controller actions (index, show, create, update, destroy) under the configured endpoint namespace, while the resource test generator creates specs for resource reads and writes. Additionally, the locale generator writes out default error titles and details for all HTTP status codes Graphiti handles, allowing users to customize error messages directly in their application's locale files.
lib/generators/graphiti · high confidence
New stats DSL and payload generation for resource metrics
Users can now define and compute aggregate statistics (such as count, sum, average, maximum, and minimum) on resources using a new DSL interface. The \lib/graphiti/stats/dsl.rb\ file introduces a configuration block that allows specifying which calculations to perform, while \lib/graphiti/stats/payload.rb\ handles the execution of these calculations against the data scope and formats the results into a structured payload returned in the API response metadata. This enables richer data insights directly within resource queries.
lib/graphiti/stats · high confidence
Removals
Removal of core JSONAPICompliable library files
The \lib/jsonapi\_compliable\ directory has been removed, deleting the \base.rb\, \deserializable.rb\, and \version.rb\ files that previously provided JSON:API resource configuration, payload deserialization, and versioning. This change eliminates the library's ability to handle JSON:API-specific features such as filtering, sorting, pagination, and nested write deserialization for Rails applications.
_lib/jsonapi\compliable · high confidence
Architecture
Refactored association persistence logic into dedicated module
Association handling for persistence (including belongs\_to, has\_many, and polymorphic relationships) has been extracted into a new \lib/graphiti/adapters/persistence/associations.rb\ module. This change centralizes the logic for processing sideposts, updating foreign keys, and managing polymorphic type attributes, ensuring that these operations are consistently applied when resources are persisted with relationships.
lib/graphiti/adapters/persistence · high confidence
Refactored scoping logic into dedicated modules
The scoping logic for filtering, pagination, sorting, and default filters has been reorganized from a monolithic structure into distinct, modular classes (Base, DefaultFilter, Filter, Filterable, Paginate, Sort, ExtraAttributes). This change improves code maintainability and separation of concerns within the Graphiti scoping layer, allowing each aspect of request scoping to be handled by its own focused component while preserving existing functionality for users.
lib/graphiti/scoping · high confidence
Behavioural changes
Documentation site migrated to Docusaurus with new navigation and styling
The documentation website has been rebuilt using Docusaurus, replacing the previous Jekyll-based setup. This change introduces a reorganized sidebar structure that orders content from common to niche, updates the code highlighting theme and color palette, and adds a persistent announcement bar for the 2.0 release. To ensure a smooth transition for existing users, the site now includes extensive URL redirects that map old Jekyll paths (such as /guides/\* and /cookbooks/\*) to the new Docusaurus routes, while preserving access to the frozen 1.x documentation via a dedicated version dropdown.
website · high confidence
Error handling refactored with I18n support and legacy compatibility
Error serialization now supports internationalization by looking up error titles in locale files (falling back to defaults), and the ConflictRequest error correctly reports status 409 with code "conflict". To support upgrading from version 1.x, deprecated constants from the merged GraphitiErrors gem are shimmed with deprecation warnings, and the old GraphitiErrors module inclusion raises an error directing users to the new Graphiti::Rails::Controller approach.
_lib/graphiti/error\serializers · high confidence
Explicit controller integration and structured error handling in Graphiti::Rails
Graphiti for Rails now requires explicit integration via the \Graphiti::Rails::Controller\ module rather than applying behavior globally to all controllers. This module provides the necessary context wrapping, debugging hooks, and \MimeResponds\ support. It also registers a comprehensive set of exception handlers for client-side errors (such as invalid filters, unsupported pagination, and missing attributes) to return structured 400 responses instead of generic 500 errors, while ensuring that only explicitly handled formats (defaulting to JSON:API) are intercepted by Graphiti's error logic.
lib/graphiti/rails · high confidence
Graphiti library restructured with new core components and examples
The Graphiti library has been reorganized, introducing a new adapter abstraction layer (lib/graphiti/adapters/abstract.rb) and a dedicated audit system (lib/graphiti/audit.rb) to help developers identify issues like missing association methods or hidden links. The resource generator (lib/generators/graphiti/resource\_generator.rb) has been updated to support explicit controller naming and attribute inference from models. Additionally, the library now includes plain Ruby and Sinatra examples (examples/plain\_ruby/seeds.rb, examples/sinatra/seeds.rb) to demonstrate usage outside of standard Rails setups, and introduces new error handling and serialization utilities.
graphiti · high confidence
Introduces new utility classes for serialization, persistence, and remote resource handling
This change adds a suite of new utility classes within \lib/graphiti/util\ that underpin core serialization and persistence behaviors. \SerializerAttributes\ and \SerializerRelationships\ now handle the dynamic application of attributes and relationships to serializers, including support for readable/writable guards and typecasting. \Persistence\ and \ValidationResponse\ manage the save flow, including nested relationship association and validation checks. \RemoteParams\ and \RemoteSerializer\ enable querying and serializing remote resources, while \Link\ and \RelationshipPayload\ handle link generation and payload traversal. These utilities collectively support the library's behavior around resource linkage, polymorphic relationships, and remote API interactions.
lib/graphiti/util · high confidence
Merged graphiti-rails, graphiti\_spec\_helpers, and graphiti\_errors into the core gem
The separate graphiti-rails, graphiti\_spec\_helpers, and graphiti\_errors gems are now absorbed into the main graphiti gem (version 2.0). The old entry points (lib/graphiti-rails.rb, lib/graphiti\_errors.rb, lib/graphiti\_spec\_helpers.rb) are retained only as deprecated shims that warn users and require the new internal paths; they will be removed in version 3.0. The lib/jsonapi\_compliable.rb file is removed, as its functionality is now part of the core. Users must remove the separate gems from their Gemfile and update their code: drop the require for graphiti-rails and include Graphiti::Rails::Controller in controllers, use Graphiti::SpecHelpers instead of the old constant, and rely on the new rescue\_registry for exception handling instead of including GraphitiErrors.
lib · high confidence
Project rebrand to Graphiti and infrastructure modernization
The gem has been renamed from jsonapi\_compliable to Graphiti, with updated documentation, badges, and copyright in the README. The project has migrated its continuous integration from Travis CI to GitHub Actions and adopted StandardRB for code linting, introducing a .standard.yml configuration and a .git-blame-ignore-revs file to handle formatting changes. Development tooling has been updated to use Appraisals for testing against Rails 7.1, 7.2, 8.0, and 8.1, and the default Ruby version is now 3.3. Additionally, the documentation site has been integrated into the repository using Docusaurus, and a .npmrc file has been added to resolve peer dependency conflicts with semantic-release.
(repo-wide) · high confidence
Refactored ActiveRecord association sideloads to use explicit scopes and AR introspection
The ActiveRecord adapter now uses dedicated sideload classes (BelongsTo, HasMany, HasOne, ManyToMany) that define explicit \default\_base\_scope\ and \scope\ methods, replacing previous implicit loading logic. The ManyToMany sideload has been rewritten to leverage Active Record's \reflections\ API for accurate foreign key and through-table inference, including support for polymorphic associations and inverse filters. This change improves the reliability of association loading and filtering by relying on AR's introspection rather than heuristic naming conventions.
_lib/graphiti/adapters/active\record · high confidence
Refactored request validation into modular components with stricter payload checks
The request validation logic has been split into separate files, introducing a dedicated UpdateValidator and a base Validator class. This change enforces stricter validation for update operations by requiring the data payload to include 'type' and 'id' fields, and by ensuring the payload's ID matches the endpoint ID as strings. The base Validator now explicitly rejects invalid page parameters and non-object data payloads, adds validation errors when 'data' or 'data/type' is missing, and handles polymorphic resource types more robustly. Additionally, the validation process now correctly validates resource relationships and allows unwritable primary keys when associating resources on create.
_lib/graphiti/request\validators · high confidence
Resource configuration and behavior are restructured into modular components
The resource logic in lib/graphiti/resource is reorganized into distinct modules (Configuration, DSL, Interface, Links, Persistence, Polymorphism, Remote, Sideloading, Documentation) to improve maintainability and clarify responsibilities. This change introduces a centralized configuration system with explicit defaults for settings like \belongs\_to\_resource\_ids\_by\_default\ (now \:foreign\_key\), \filter\_blanks\_treated\_as\ (now \:literal\), and \page\_links\ (now \false\), replacing previous implicit behaviors. It also adds new capabilities such as public ID support for hiding database IDs, remote resource support via Faraday, polymorphic relationship handling, and enhanced persistence callbacks (\before\_commit\, \after\_commit\, \after\_graph\_persist\). Deprecated methods like \autolink\ and \validate\_endpoints\ are aliased to their new counterparts (\relationship\_links\, \validate\_requests\, \validate\_links\) with deprecation warnings, ensuring a smoother transition for existing code.
lib/graphiti/resource · high confidence
Restored archived 1.13 documentation site with static assets and content
The archived 1.13 documentation site has been restored to the repository, including the full HTML content for release announcements (1.0, 1.1, 1.2) and the tutorial write-ups, along with the necessary static assets such as syntax highlighting styles, favicons, and JavaScript libraries. This ensures that historical documentation for the 1.13 version remains accessible and correctly rendered.
website/static · high confidence
Reworked association sideloads to support public IDs and configurable resource ID rendering
The association sideloads (belongs\_to, has\_many, has\_one, many\_to\_many) have been rewritten to support public IDs, allowing database IDs to be hidden from clients. belongs\_to associations now render resource linkage by default, controlled by the new belongs\_to\_resource\_ids\_by\_default setting, while has\_many and many\_to\_many associations can link by public ID when configured. This change improves security by preventing accidental exposure of internal database IDs and enhances performance through optimized query loading and assignment logic.
lib/graphiti/sideload · high confidence
Support for offset-based pagination in link generation
The pagination link generation logic now supports the \page\[offset\]\ query parameter in addition to the existing \page\[number\]\ parameter. When an offset is provided in the request, the generated pagination links (self, first, last, prev, next) will correctly include this offset value, ensuring that navigation links preserve the user's current offset-based view rather than defaulting to or ignoring it.
lib/graphiti/delegates · high confidence
Update console environment to use Graphiti gem
The development console script now loads the 'graphiti' gem instead of 'jsonapi\_compliable', allowing developers to interact with the renamed library directly in the REPL. Additionally, new helper scripts were added: 'appraisal' and 'rspec' wrappers for running tests and appraisal tasks, and 'cut-docs-version' to freeze documentation versions for the Docusaurus site.
bin · high confidence
Updated resource and controller generation templates
The generator templates for ApplicationResource, Resource, and Controllers have been updated to use a declarative DSL for settings (such as adapter and base\_url) and to default to explicit JSON:API rendering instead of relying on the Responders gem. Additionally, request and resource spec templates now utilize FactoryBot for generating test data and include comprehensive error-code locale files to aid in debugging.
lib/generators/graphiti/templates · high confidence
Test coverage
Added Rails request spec support helpers; Added concurrency and stress tests for sideloading, debugger, and memory retention; Added performance measurement and visualization tooling; Added test coverage for Graphiti 2.0 core features and configuration; Added test fixtures for Employee Directory, Legacy, and PORO domains; Added tests for pagination delegate behavior; Added tests for the Stats DSL and Payload components; Added unit tests for Graphiti utility classes; Expanded integration test coverage for Rails and ActiveRecord features; Removed spec/dummy Rails application scaffold; Updated test support infrastructure with concurrency and pagination helpers.
Dependencies
Added Appraisal configurations for Rails 7.1, 7.2, 8.0, and 8.1
The gemfiles directory now includes new Appraisal configuration files for Rails 7.1, 7.2, 8.0, and 8.1, enabling the library to be tested against these specific Rails versions. Each generated gemfile pins the corresponding Rails version (e.g., \\~\> 7.1.0\, \\~\> 8.1.0\) and includes necessary dependencies like \rspec-rails\, \responders\, and \sqlite3\ (with version adjustments for newer Rails releases), along with standard test tooling such as \database\_cleaner\, \pry\, and \guard\. This allows developers to run the test suite against multiple Rails versions to ensure compatibility.
gemfiles · high confidence
Initial release of Graphiti gem with dependency and build configuration
This change introduces the Graphiti gem (formerly jsonapi\_compliable), establishing its core dependency manifest (graphiti.gemspec) which requires Ruby 3.2+, Rails 7.1+, and libraries like jsonapi-serializable and dry-types. It also adds example applications for Plain Ruby and Sinatra, configures the release pipeline via semantic-release (package.json), and updates the website to use Docusaurus 3.10.2 with React 19.
(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
Baseline
- First survey — no prior run to compare against. CAI 64.
Lenses
- Code Health 91
- Architecture 90
- Maturity 65
- Readiness 65
- Security 55
- Domain Modelling 100
Changes since last survey
- 300 commits — 222 feature/other, 78 fixes
By area
- lib/graphiti — 122 commits
- (root) — 99 commits
- .github/workflows — 19 commits
- docs/concepts — 8 commits
- docs/upgrading.md — 7 commits
- lib/generators — 7 commits
- (repo) — 6 commits
- spec/performance — 5 commits
- website/docusaurus.config.js — 5 commits
- spec/integration — 4 commits
- lib/graphiti.rb — 3 commits
- spec/no_rails_spec.rb — 2 commits
- website/static — 2 commits
- docs/intro.md — 1 commit
- docs/topics — 1 commit
- examples/sinatra — 1 commit
- spec/configuration_spec.rb — 1 commit
- spec/fixtures — 1 commit
- spec/schema_diff_spec.rb — 1 commit
- spec/sideloading_spec.rb — 1 commit
Notable commits
- fix: ci: fix no rails spec and lint error
- fix: fix(generators): stop injecting a routes host into config/application.rb
- fix: fix: Ensure RequestValidator validates resource relationships
- fix: fix: Enum should allow the conventionally case-sensitive operators (#434)
- fix: fix: Fixes error in version check for ActiveRecord adapter introduced in #478 (#479)
- fix: fix: GQL name chaining (#415) [skip ci]
- fix: fix: Gem version check (#483)
- fix: fix: Remove thread pool executor logic until we get a better handle on what's causing thread pool hangs. refs #469
- fix: fix: Update some missing sections and terms after renames, register unsupported pagination error
- fix: fix: a filter you declare by hand always beats the one an attribute generates
- fix: fix: a subclass redeclaring a relationship reaches its serializer
- fix: fix: accept a single value for array filters (#517)
- fix: fix: accept a single value for array filters (#517)
- fix: fix: always render included when the client asked to include
- fix: fix: apply sideloads at definition once setup! has run
- fix: fix: attribute :id declared on an abstract resource is inherited instead of failing on the missing serializer
- fix: fix: autolink = true no longer clobbers an inherited :on_demand
- fix: fix: bridge the last 1.x names that died with a bare NameError
- fix: fix: build the entity map when the root query is, not on first use
- fix: fix: change class attribute behavior on endpoint method to work in ruby 3.2+ (#493)
- …and 280 more
Architecture
- 0 containers · 1 bounded contexts · 0 dependency edges (baseline)
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
graphiti-api/graphiti 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 20 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 3ec8ec0b0590470e156d9fe8e3192224b60f398d — 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-b51f968c9b10.