> For the complete documentation index, see [llms.txt](https://docs.opensoutheners.com/oss/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.opensoutheners.com/oss/laravel-apiable/request-features/fields.md).

# Sparse Fieldsets

Select specific attributes per resource type using JSON:API sparse fieldsets.

Sparse fieldsets allow API consumers to request only the columns they need from each resource type. This reduces response payload size and limits the columns included in the `SELECT` query sent to the database.

This feature follows the [JSON:API sparse fieldsets specification](https://jsonapi.org/format/#fetching-sparse-fieldsets).

## URL format

```
GET /posts?fields[post]=title,body
GET /posts?fields[post]=title,body&fields[user]=name,email
```

The key inside `fields[]` is the JSON:API resource type (e.g. `post`, `user`). The value is a comma-separated list of attribute names.

{% hint style="info" %}
By default every comma splits a `fields[]` value into separate attribute names. Enable [`requests.strict_comma_encoding`](/oss/laravel-apiable/getting-started/configuration.md#requests-strict-comma-encoding) to allow a percent-encoded comma (`%2C`) inside a single attribute name.
{% endhint %}

## `AllowedFields::make()`

`AllowedFields::make()` takes a resource type and an array (or comma-separated string) of allowed column names:

```php
use OpenSoutheners\LaravelApiable\Http\AllowedFields;

AllowedFields::make('post', ['title', 'body', 'created_at'])
AllowedFields::make('user', ['name', 'email'])
```

Instead of a string resource type, you can pass the model class directly — the package resolves the type from your `resource_type_map` config:

```php
use App\Models\User;

AllowedFields::make(User::class, ['name', 'email'])
```

## Allowing fields

{% tabs %}
{% tab title="Using methods" %}
Pass `AllowedFields` instances to `allowing()`, or call `allowFields()` directly:

```php
use OpenSoutheners\LaravelApiable\Http\JsonApiResponse;
use OpenSoutheners\LaravelApiable\Http\AllowedFields;
use App\Models\User;

public function index()
{
    return JsonApiResponse::from(Post::class)
        ->allowing([
            AllowedFields::make('post', ['title', 'body', 'created_at']),
            AllowedFields::make('user', ['name', 'email']),
        ]);
}
```

Using `allowFields()` directly with a string type:

```php
return JsonApiResponse::from(Post::class)
    ->allowFields('post', ['title', 'body', 'created_at'])
    ->allowFields('user', ['name', 'email']);
```

Using a model class for the type argument:

```php
return JsonApiResponse::from(Post::class)
    ->allowFields(User::class, ['name', 'email']);
```

Shorthand — pass an array as the first argument to target the main resource type (in this case `post`):

```php
return JsonApiResponse::from(Post::class)
    ->allowFields(['title', 'body']);
```

{% endtab %}

{% tab title="Using attributes" %}

```php
use OpenSoutheners\LaravelApiable\Attributes\FieldsQueryParam;
use OpenSoutheners\LaravelApiable\Http\JsonApiResponse;
use App\Models\User;

#[FieldsQueryParam('post', ['title', 'body', 'created_at'])]
#[FieldsQueryParam(User::class, ['name', 'email'])]
public function index(JsonApiResponse $response)
{
    return $response->using(Post::class);
}
```

`FieldsQueryParam` accepts: `type` (string resource type or model class-string), `fields` (array of column names), and `description`.
{% endtab %}
{% endtabs %}

## Primary key behaviour

The primary key (`id` by default) is **always included** in the `SELECT` query even if the consumer does not request it. This ensures JSON:API `id` fields are always present and relationships can be resolved correctly.

## Applying fields to included resources

When a consumer requests both sparse fieldsets and includes, the package applies the column restriction to the eager-loaded relationship query as well:

```
GET /posts?include=author&fields[post]=title&fields[user]=name
```

Only `title` is selected for `post` records, and only `name` is selected for eagerly loaded `user` records.

{% hint style="info" %}
Fields limit which columns are fetched from the database at the query level. If you need to include computed values that are not database columns, use [Appends](/oss/laravel-apiable/request-features/appends.md) instead.
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.opensoutheners.com/oss/laravel-apiable/request-features/fields.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
