Core: disallow extra field when denormalization

Created on 30 Jun 2017  ยท  14Comments  ยท  Source: api-platform/core

i think it would be great if api-platform has built in validation to allow/disallow extra fields when user POST / PUT data

so if user submit data that the property does not exist or the property does not include in denormalization context group, it will be throw validation error like Symfony form type http://symfony.com/doc/current/reference/forms/types/form.html#allow-extra-fields

question โญ EU-FOSSA Hackathon

Most helpful comment

For those who wonder how to disable extra fields

/**
 * @ApiResource(
 *     denormalizationContext={"allow_extra_attributes"=false}
 * )
 */

All 14 comments

The symfony serializer has an Option to check extra props. though not for missing Attributes, which makes the current PUT more like a PATCH

you're right, but allow_extra_attributes context key was introduced in Symfony 3.3. https://symfony.com/doc/current/components/serializer.html#deserializing-an-object and current api-platform not support extra resource attribute key

i also needed required attributes. i solved the problem by using a flag within my model that is initialied to false per default and then set to true, if the setter is called. you can then use a Callback validator and a custom method to produce validation errors, if the setter is not called.

its not a beauty but it works.

This is more a feature request than a question, basically

Support allow_extra_attributes=false in API Platform

Is it not?

allow_extra_attributes is supported, I just did the test.

@meyerbaptiste Great, can you paste a short sample?

allow_extra_attributes does indeed work, although the error message could use some work (I guess that should be fixed in Symfony).

But, how to enable it? I just it from a SerializerContextBuilderInterface, but it would be cool to be able to enable it from app-wide config and override in resource metadata.

I agree. Having a global config flag to populate ร  base normalization and denormalization context would be a nice DX improvement.

Would you mind opening a PR?

Would you mind opening a PR?

I knew somebody would say that. :) But yes, I'll do it. :+1:

@dunglas quickly looking at this, most proper way would be ContextTrait? How would you inject the value, adding a setter in the trait? Or rename to ConfigurationAwareContextTrait where we're able to inject a config hash?

I agree. Having a global config flag to populate ร  base normalization and denormalization context would be a nice DX improvement.

Coming soon with symfony default context configuration (I hope) + duplicate of #1526

For those who wonder how to disable extra fields

/**
 * @ApiResource(
 *     denormalizationContext={"allow_extra_attributes"=false}
 * )
 */

Disallowing extra fields for the whole project:

<?php

declare(strict_types=1);

namespace App\Serializer;

use ApiPlatform\Core\Serializer\SerializerContextBuilderInterface;
use Symfony\Component\HttpFoundation\Request;

final class DisallowExtraAttributesContextBuilder implements SerializerContextBuilderInterface
{
    private SerializerContextBuilderInterface $decorated;

    public function __construct(SerializerContextBuilderInterface $decorated)
    {
        $this->decorated = $decorated;
    }

    public function createFromRequest(Request $request, bool $normalization, array $extractedAttributes = null): array
    {
        $context = $this->decorated->createFromRequest($request, $normalization, $extractedAttributes);

        if (!$normalization && \in_array($request->getMethod(), ['PUT', 'PATCH', 'POST'], true)) {
            $context['allow_extra_attributes'] = false;
        }

        return $context;
    }
}

and service definition:

# app/config/services.yaml

services:
    # ...
    App\Serializer\DisallowExtraAttributesContextBuilder:
        decorates: 'api_platform.serializer.context_builder'
        arguments: [ '@App\Serializer\DisallowExtraAttributesContextBuilder.inner' ]
        autoconfigure: false

@api-platform/core what do you think about adding per-service and project-wide examples to documentaiton? (last 2 comments)

For the record, this option can now be enabled globally: https://github.com/api-platform/core/pull/3151

3151

How exactly?

Was this page helpful?
0 / 5 - 0 ratings