Skip to content

JSON:API sparse fieldsets break include relationships - included section missing #7267

Open
@cay89

Description

@cay89

API Platform version(s) affected: 4.1.3 (Laravel)

Description
When using JSON:API sparse fieldsets (fields[ResourceType]=field1,field2) in combination with include relationships (include=relationName), the included section is completely missing from the response. The include parameter works correctly when used alone, but any sparse fieldset parameter (even for unrelated resources) causes the included relationships to disappear.

How to reproduce

  1. Set up two related models with ApiResource annotations:
// ListItem model
#[ApiResource(
    uriTemplate: '/list/items',
    operations: [
        new GetCollection(
            parameters: [
                new QueryParameter(key: 'include'),
                new QueryParameter(key: 'fields', filter: SparseFieldset::class),
            ],
        ),
    ],
)]
class ListItem extends AbstractModel
{
    public function translations(): HasMany
    {
        return $this->hasMany(ItemTranslation::class, 'item_id');
    }
}

// ItemTranslation model  
#[ApiResource(/* ... */)]
class ItemTranslation extends AbstractModel
{
    // fields: locale, value, etc.
}
  1. Test these API calls:

Working (include only):

GET /api/list/items?include=translations

Response includes included section with translation data.

Not working (include + sparse fieldsets):

GET /api/list/items?include=translations&fields[ListItem]=id,data&fields[ItemTranslation]=locale,value

Response missing included section entirely.

Also not working (include + any sparse fieldset):

GET /api/list/items?include=translations&fields[ListItem]=id,data
GET /api/list/items?include=translations&fields[ItemTranslation]=locale,value

Both missing included section.

Expected behavior: When both include and fields parameters are used, the response should contain the included section with only the specified fields for each included resource type.

Example request:

GET /api/list/items?include=translations&fields[ListItem]=id,data&fields[ItemTranslation]=locale,value

Expected response:

{
  "links": {"self": "/api/list/items?include=translations&fields[ListItem]=id,data&fields[ItemTranslation]=locale,value"},
  "meta": {"totalItems": 3, "itemsPerPage": 20, "currentPage": 1},
  "data": [
    {
      "id": "/api/list_items/1ae0ddf1-d361-465e-9ff7-cdabecf82cb2",
      "type": "ListItem",
      "attributes": {
        "id": "1ae0ddf1-d361-465e-9ff7-cdabecf82cb2",
        "data": {"validation": {"regex": "^[0-9]{8}-[1-5]-[0-9]{2}$"}}
      },
      "relationships": {
        "translations": {
          "data": [{"type": "ItemTranslation", "id": "/api/item_translations/e57d9880-a064-4352-85a0-29391d0e5b5f"}]
        }
      }
    }
  ],
  "included": [
    {
      "id": "/api/item_translations/e57d9880-a064-4352-85a0-29391d0e5b5f",
      "type": "ItemTranslation",
      "attributes": {
        "locale": "en",
        "value": "Tax number format"
      }
    }
  ]
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions