Skip to content

feat: add per-type API transformer sparse fieldsets#10285

Open
michalsn wants to merge 1 commit into
codeigniter4:4.8from
michalsn:feat/api-transformer-sparse-fieldsets
Open

feat: add per-type API transformer sparse fieldsets#10285
michalsn wants to merge 1 commit into
codeigniter4:4.8from
michalsn:feat/api-transformer-sparse-fieldsets

Conversation

@michalsn
Copy link
Copy Markdown
Member

@michalsn michalsn commented Jun 7, 2026

Description
This PR adds per-type sparse fieldsets for API transformers via fields[<type>].

Transformers can opt in by defining $resourceType, allowing nested resources to apply their own field filters without inheriting the root fields parameter.

Ref: #10278 (comment)

Checklist:

  • Securely signed commits
  • Component(s) with PHPDoc blocks, only if necessary or adds value (without duplication)
  • Unit testing, with >80% coverage
  • User guide updated
  • Conforms to style guide

@michalsn michalsn added enhancement PRs that improve existing functionalities 4.8 PRs that target the `4.8` branch. labels Jun 7, 2026
protected mixed $resource = null;

public function __construct(
private ?IncomingRequest $request = null,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

To allow reusing the same transformer for multiple relations (like posts and comments) with independent fieldsets, we should add an $overrideResourceType parameter to the constructor.

Comment on lines +102 to +132
/**
* Resolves the requested field list for this transformer from the request.
*
* Supports both the flat `?fields=a,b` form and the per-type sparse
* fieldset form `?fields[<type>]=a,b`. The flat form is only honored when
* $allowFlat is true (i.e. for the root transformer); a type-specific
* fieldset is matched against this transformer's $resourceType at any
* nesting level.
*
* @return list<string>|null
*/
private function resolveFields(bool $allowFlat): ?array
{
$fields = $this->request->getGet('fields');

// Sparse fieldsets: ?fields[posts]=id,slug -> ['posts' => 'id,slug']
if (is_array($fields)) {
$scoped = ($this->resourceType !== null && is_string($fields[$this->resourceType] ?? null))
? $fields[$this->resourceType]
: null;

return $scoped !== null ? $this->splitList($scoped) : null;
}

// Flat fieldset: ?fields=id,slug (applies to the root only)
if ($allowFlat && is_string($fields)) {
return $this->splitList($fields);
}

return null;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

In resolveFields(), mixing fields[x]=... and fields=... in the URL causes PHP to natively overwrite the array and break the filters,we need to manually parse the QUERY_STRING to prevent this bug.

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

Labels

4.8 PRs that target the `4.8` branch. enhancement PRs that improve existing functionalities

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants