Skip to content

Honor collection roots from namespaces and render - #107

Open
dblock wants to merge 1 commit into
ruby-grape:masterfrom
dblock:fix/array-root-options-81
Open

dblock wants to merge 1 commit into
ruby-grape:masterfrom
dblock:fix/array-root-options-81

Conversation

@dblock

@dblock dblock commented Oct 26, 2026 •

Copy link
Copy Markdown
Member

What this fixes

With the AMS JSON adapter, collections already have a root envelope. This PR fixes two ignored root overrides; it does not introduce collection wrapping or change its defaults.

  1. An explicit namespace root was ignored: the collection used the namespace name instead of the configured root.
  2. A root passed to render was not forwarded to AMS: the response kept the route or inferred root instead of the requested override.

For example:

namespace :users, root: 'members' do
  get('/')    { User.all }
  get('/:id') { User.find(params[:id]) }
end
Response with the JSON adapter Before After
Collection in the namespace above {"users": [...]} {"members": [...]}
Single user in that namespace {"user": {...}} Unchanged
Collection in namespace users without an explicit root {"users": [...]} Unchanged

Explicit collection roots follow inner namespace > outer namespace, route > namespace, and render > route precedence. Empty collections retain an explicit root too.

What stays unchanged

Namespace roots remain collection-only: the earlier draft unintentionally renamed single-object responses, and that regression is removed. Existing route-level roots continue to work. The attributes adapter still returns bare arrays; root:false does not remove the JSON adapter envelope; JSON:API retains its standard data structure. Grape format :json still does not select the AMS adapter.

The implementation reads only namespace root options for collections rather than broadly changing namespace-option handling. Documentation explains adapter selection and precedence, and nine request-level cases cover collection behavior and preservation of single-object roots.

Validation

All 84 examples and RuboCop pass locally with Grape 4 on Ruby 4.0. No dependency changes, new source exclusions, or increased lint limits.

Hosted CI passes the compatibility matrix and lint. Danger also passes.

Closes #81.

Created by Copilot, an AI, on behalf of @dblock.

@dblock
dblock force-pushed the fix/array-root-options-81 branch from 579c307 to fec16cd Compare October 26, 2026 13:15
@github-actions

github-actions Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

Danger Report

No issues found.

View run

@dblock
dblock requested a review from samsonjs October 26, 2026 13:28

@samsonjs samsonjs left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This changes behaviour of object responses in addition to collections. Previously a namespace root: was ignored and the response key was derived from the returned object's class. This isn't a feature that I use and I'm honestly unsure if this is intentional, but it seems at least worth documenting and adding to the changelog.

Merge serializer options from actual namespace scopes, preserving outer-to-inner precedence, and forward root through render. Document adapter selection, root precedence, empty collections, root:false behavior, and unwrapped arrays. Cover each documented response shape with request-level regressions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@dblock
dblock force-pushed the fix/array-root-options-81 branch from fec16cd to 81bac6b Compare October 27, 2026 02:32
@dblock

dblock commented Oct 27, 2026

Copy link
Copy Markdown
Member Author

Fixed in 81bac6b: namespace-root lookup is now collection-only, preserving the existing single-object response key. Added regression coverage and clarified the README/changelog.

Posted by Copilot, an AI, on behalf of @dblock.

@dblock

dblock commented Oct 27, 2026

Copy link
Copy Markdown
Member Author

Keeping this fix collection-only preserves compatibility. For example, with namespace :users, root: "members", a collection returns {"members": [...]}, while a single user continues to return {"user": {...}} rather than unexpectedly becoming {"members": {...}}. Individual routes can still choose an explicit root.

Applying namespace roots uniformly to collections and single objects could be a reasonable long-term API, but that would be a deliberate breaking change for a major release, not part of this collection-root fix.

Posted by Copilot, an AI, on behalf of @dblock.

@dblock dblock changed the title Fix namespace and render collection roots Honor collection roots from namespaces and render Oct 27, 2026
@dblock

dblock commented Oct 27, 2026

Copy link
Copy Markdown
Member Author

Major version bump and a consistent root handling in #111, your call @samsonjs !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Array root documentation

2 participants