Limiting fields in API requests with fields parameterfor Drupal 11 , 10 , 9 , and 8

Last updated :  

The previous lesson controlled how much gets included and how many items come back. This one controls something more granular: for each individual resource in the response, exactly which fields actually get serialized — a full article node has dozens of fields, but a client building a headless listing page might genuinely need only three of them.

What you'll learn in this lesson

  • The fields[type] query parameter, precisely
  • Why this saves real server-side work, not just response size
  • Applying sparse fieldsets to included resources too

The fields parameter

# Without sparse fieldsets: every field on the article gets serialized.
GET /jsonapi/node/article

# With sparse fieldsets: only these three fields, for this resource type.
GET /jsonapi/node/article?fields[node--article]=title,field_summary,path

The key syntax is fields[<resource-type>] — note it's per resource type, which matters the moment includes are involved, since an included author resource needs its own separate fields[user--user] to be trimmed too.

This isn't just a smaller response — it's less work server-side. A field formatter's actual computation (a rendered entity-reference field recursively building its own nested render tree, an image field resolving a derivative URL) only runs for fields JSON:API actually needs to serialize. Requesting fewer fields means Drupal genuinely computes less, not just transmits less — this connects directly back to the "Reducing Field Rendering Overhead" lesson from the Entity and Field Optimization section, just triggered by an API request instead of a themed page.

Trimming included resources too

# Sparse fieldsets apply independently to the primary resource
# AND to anything pulled in via include.
GET /jsonapi/node/article?include=uid&fields[node--article]=title,uid&fields[user--user]=display_name

Without the second fields[user--user] restriction, including the author still returns their entire user resource — every field on the User entity — even though the client asked to trim the article. Sparse fieldsets need to be specified per resource type present in the response, not just for the "main" one.

A realistic headless-frontend pattern

# A listing page needs only title, summary, and image — nothing else.
GET /jsonapi/node/article?filter[status]=1&page[limit]=20&fields[node--article]=title,field_summary,field_image&include=field_image&fields[file--file]=uri,url

Combining everything from this section — pagination, includes, sparse fieldsets — produces exactly the shape a specific frontend view actually needs, no more.

Quick check: a request includes the author via include=uid but only specifies fields[node--article]=title,uid, with no fields[user--user] restriction. Does the author's response get trimmed too? If you said no — every field on the included User resource still gets returned in full, since sparse fieldsets apply per resource type independently — you've understood exactly the gotcha this lesson calls out.

Key takeaways

  • fields[<resource-type>]=field1,field2 restricts which fields get serialized for that specific resource type.
  • This saves real computation, not just response size — untrimmed field formatters simply don't run at all.
  • Sparse fieldsets apply per resource type — an included resource needs its own explicit fields[] restriction, or it returns unrestricted.
  • Combine sparse fieldsets with pagination and controlled includes to shape a response to exactly what a specific frontend view needs.

Coming up next

You've now trimmed what's fetched and what's serialized. Last in this section: compressing whatever's left before it goes over the wire at all.