Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to expose a property which depends on a serialization group from API-Platform to react-admin?

I use Changing the Serialization Context Dynamically in my application to apply the admin:write group when the user is an admin. So that an user on the admin will be able to update this property.

The context builder has this configuration:

<?php

namespace App\Serializer;

use ApiPlatform\Core\Serializer\SerializerContextBuilderInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;

final class AdminContextBuilder implements SerializerContextBuilderInterface
{
    private $decorated;
    private $authorizationChecker;

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

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

        if (isset($context['groups']) && $this->authorizationChecker->isGranted('ROLE_ADMIN') && false === $normalization) {
            $context['groups'][] = 'admin:write';
        }
        if (isset($context['groups']) && $this->authorizationChecker->isGranted('ROLE_ADMIN') && true === $normalization) {
            $context['groups'][] = 'admin:read';
        }

        return $context;
    }
}

I want to show this property to the admin:

abstract class User implements UserInterface
{
   /**
     * @ORM\Column(name="account_status", type="string", length=8)
     * @Groups({"read", "admin:write"})
     */
    protected $accountStatus;
}

The data is returned successfully and I can see the string on table view or item view in the admin.

But the documentation generated by API-Platform on …/api/docs.jsonld does not expose this property: the property is not writable:

{
    "@type": "hydra:SupportedProperty",
    "hydra:property": {
        "@id": "#User/accountStatus",
        "@type": "rdf:Property",
        "rdfs:label": "accountStatus",
        "domain": "#User",
        "range": "xmls:string"
    },
    "hydra:title": "accountStatus",
    "hydra:required": false,
    "hydra:readable": true,
    "hydra:writable": false
},

I think that it prevents showing the field in the administration.

How can I add this property to the documentation and ultimately to react-admin?

I tried any configuration I could think of:

abstract class User implements UserInterface
{
    /**
     * @ORM\Column(name="account_status", type="string", length=8)
     * @Groups({"read", "admin:write"})
     * @ApiProperty(writable=true)
     */
    protected $accountStatus;
}
like image 741
A.L Avatar asked Dec 10 '18 16:12

A.L


1 Answers

For me the docs are shown as expected when I do this entirely with annotations.

/**
* "admin_edit"={
*     "method"="PUT", "path"="/api/users/{id}",
*     "normalization_context"={"groups"={"admin:write"}},
*     "access_control"="is_granted('ROLE_ADMIN')"
* }
*/

Essentially, you are adding a new route for the admin, but it's simpler than using the serialisation mechanism.

like image 200
Mundi Avatar answered Nov 09 '22 17:11

Mundi