function JsonApiDocumentTopLevelNormalizer::getNormalizationSchema

Overrides SchematicNormalizerTrait::getNormalizationSchema

File

core/modules/jsonapi/src/Normalizer/JsonApiDocumentTopLevelNormalizer.php, line 344

Class

JsonApiDocumentTopLevelNormalizer
Normalizes the top-level document according to the JSON:API specification.

Namespace

Drupal\jsonapi\Normalizer

Code

public function getNormalizationSchema(mixed $object, array $context = []) : array {
    // If we are providing a schema based only on an interface, we lack context
    // to provide anything more than a ref to the JSON:API top-level schema.
    $fallbackSchema = [
        '$ref' => JsonApiSpec::SUPPORTED_SPECIFICATION_JSON_SCHEMA,
    ];
    if (is_string($object)) {
        return $fallbackSchema;
    }
    assert($object instanceof JsonApiDocumentTopLevel);
    if ($object->getData() instanceof OmittedData) {
        // A top-level omitted data object is a bit weird but it will only contain
        // information in the 'links' property, so we can fall back.
        return $fallbackSchema;
    }
    $schema = [
        'allOf' => [
            [
                '$ref' => JsonApiSpec::SUPPORTED_SPECIFICATION_JSON_SCHEMA,
            ],
        ],
    ];
    // Top-level JSON:API documents may contain top-level data or an error
    // collection.
    $data = $object->getData();
    if ($data instanceof ErrorCollection) {
        // There's not much else to state here, because errors are a known schema.
        $schema['required'] = [
            'errors',
        ];
    }
    // Relationship data - "resource identifier object(s)"
    if ($data instanceof RelationshipData) {
        if ($data->getCardinality() === 1) {
            $schema['properties']['data'] = [
                '$ref' => JsonApiSpec::SUPPORTED_SPECIFICATION_JSON_SCHEMA . '#/definitions/relationship',
            ];
        }
        else {
            $schema['properties']['data'] = [
                'type' => 'array',
                'items' => [
                    '$ref' => JsonApiSpec::SUPPORTED_SPECIFICATION_JSON_SCHEMA . '#/definitions/relationship',
                ],
                'unevaluatedItems' => FALSE,
            ];
            if ($data->getCardinality() !== FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED) {
                $schema['properties']['data']['maxContains'] = $data->getCardinality();
            }
            // We can't do a minContains with the data available in this context.
        }
    }
    if ($data instanceof IncludedData) {
        if ($data instanceof NullIncludedData) {
            $schema['properties']['included'] = [
                'type' => 'array',
                'maxContains' => 0,
            ];
        }
        else {
            $schema['properties']['included'] = [
                // 'included' member is always an array.
'type' => 'array',
                'items' => [
                    'oneOf' => $this->getSchemasForDataCollection($data->getData(), $context),
                ],
            ];
        }
    }
    if ($data instanceof ResourceObjectData) {
        if ($data->getCardinality() === 1) {
            assert($data->count() === 1);
            $schema['properties']['data'] = [
                'oneOf' => [
                    $this->getSchemasForDataCollection($data->getData(), $context),
                    [
                        'type' => 'null',
                    ],
                ],
            ];
        }
        else {
            $schema['properties']['data'] = [
                'type' => 'array',
                'items' => [
                    'oneOf' => $this->getSchemasForDataCollection($data->getData(), $context),
                ],
            ];
            if ($data->getCardinality() !== FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED) {
                $schema['properties']['data']['maxContains'] = $data->getCardinality();
            }
        }
    }
    return $schema;
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.