-
Notifications
You must be signed in to change notification settings - Fork 890
Description
JSON:API RFC: Exluding fields with Sparse Fieldsets
- Version: 0.1
- Date: 18.06.2022
- Author: Thorsten Suckow-Homberg thorsten@suckow-homberg.de
- Status: Draft
- Versions affected: V1.0
Introduction
This RFC proposes an addition to the syntax used with Sparse Fieldsets, namely to add the asterisk character (U+002A ASTERISK, "*") to the fields[TYPE]
parameter, allowing for
- specifying a wildcard as a representative for ALL available fields of a resource object
and - specifying a list of fields to exclude in a resource object
GET /documents/1?fields[document]=*,title HTTP/1.1
Accept: application/vnd.api+json
The above example requests all fields to be included with the resource object, but not the field `title`.
Proposal
The following is defined in the JSON:API specification (V1.0, also upcoming V1.1) by the time of writing this RFC:
- The value of the fields parameter MUST be a comma-separated (U+002C COMMA, “,”) list that refers to the name(s) of the fields to be returned.
and
- An empty value indicates that no fields should be returned.
furthermore:
- If a client does not specify the set of fields for a given resource type, the server MAY send all fields, a subset of fields, or no fields for that resource type.
While the specifications gives the client a clear indication of how to define the fields included with the resource object in the response, it is not possible to fall back to a set of "default fields" that exclude a specific set of fields at the same time.
The only option to fall back to a predefined list of fields is by omitting the fields[TYPE]
parameter. The implementing API will then take care of computing the fields to return; this may also lead to no fields being returned at all, as per specification.
Drawbacks of the current specification
The current specification makes it hard to maintain large set of fields which are part of larger resource objects, specially DTOs/value objects that aggregate data without providing the option to query related resources for data.
Take for example a fictional document represented by a resource object that has a list of 20 fields, field_1 .. field_20
. The computing of the values for field_18 .. field_20
are costly and require complex operations that produce more load on the server: The client uses these fields only on some occasions, e.g. in master/detail views: A lean representation of the resource object in a grid vs. the resource object loaded in its entirety for the detail view. Instead of designing the API to use specifics of the represented entities and provide different resource locations for the resource object (Object A containing field_1 .. field_ 17
, Object B containing field_1 .. field_20
) , sparse fieldsets are used.
The current specifications require the following syntax to make sure field_18
, field_19
and field_20
are NOT included with the resource object in its response:
GET /documents/1?fields[document]=field_1,field_2,field_3,field_4,field_5,field_6,field_7,field_8,field_9,field_10,field_11,field_12,field_13,field_14,field_15,field_16,field_17 HTTP/1.1
Accept: application/vnd.api+json
The same could be achieved with the asterisk character (U+002A ASTERISK, "*") character by inversing the list of included fields, and providing a syntax for excluding fields:
GET /documents/1?fields[document]=*,field_18,field_19,field_20 HTTP/1.1
Accept: application/vnd.api+json
Changes that affect the current specification
This changes the specification of the JSON:API in its current version to the following:
BEGIN
The value of the fields
parameter MUST be a comma-separated (U+002C COMMA, ",") list that refers to the name(s) of the fields to be returned. An empty value indicates that no fields should be returned.
If the value of the fields
parameter is not a comma-separated list of fields, and it is not empty, it MUST be an asterisk (U+002A ASTERISK, "*"), or a comma-separated list of fields starting with an asterisk (U+002A ASTERISK, "*"). The asterisk MUST be treated as if the client had specified ALL fields of the requested resource object, optionally followed by the list of fields that MUST NOT be included with the resource object in its response.
END
The following lets the server decide which fields to return with the resource object as per current specification:
GET /documents/1 HTTP/1.1
Accept: application/vnd.api+json
The following extends the current specification by requesting ALL available fields of the resource object by using a wildcard with fields[TYPE]
GET /documents/1?fields[document]=* HTTP/1.1
Accept: application/vnd.api+json
The following extends the current specification to return the resource object with all available fields, excluding the title
field, which MUST NOT be included in the resource object in its response:
GET /documents/1?fields[document]=*,title HTTP/1.1
Accept: application/vnd.api+json
Additions
According to https://www.rfc-editor.org/rfc/rfc3986#appendix-A, it should be safe to use the asterisk character unencoded with the query string.