api-platform: GraphQL: @ApiProperty(required=false) does not work

In my Entity, I have a property:

/**
 * @var int The account balance
 *
 * @ORM\Column(type="integer")
 * @ApiProperty(required=false)
 * @Assert\Type(type="integer")
 */
private $balance = 0;

I want this property to be optional in my GraphQL query, but not in database.

So I added the required=false attributes, but it doesn’t work.

About this issue

  • Original URL
  • State: open
  • Created 6 years ago
  • Reactions: 4
  • Comments: 15 (2 by maintainers)

Most upvoted comments

So this is still an issue? Is there at least a workaround? For example I am trying to add a property to an entity that does not need to persist to the db at all. But it’s still a required field for graphql. At least when creating. when updating this does not seam to be a problem (since the values already exist and just get rehydrated into the entity already).

I am using a boolean with a default, which also should be a case where the GraphQL input is not required.

    /**
     * @ORM\Column(type="boolean",  options={"default": false})
     */

In the docs at https://api-platform.com/docs/core/graphql/#securing-properties-including-associations a note says:

“Note: adding the ApiProperty security expression to a GraphQL property will automatically make the GraphQL property type nullable (if it wasn’t already). This is because null is returned as the property value if access is denied via the security expression.”

So a workaround may be to add some dummy security via ApiProperty-Annotation to the property which would make it optional in GraphQL:

#[ApiProperty(security: "is_granted('ROLE_USER')")]

I had a look and it seems this forces the nullable field via $forceNullable param at https://github.com/api-platform/core/blob/v3.0.9/src/GraphQl/Type/FieldsBuilder.php#L250

private function getResourceFieldConfiguration(?string $property, ?string $fieldDescription, ?string $deprecationReason, Type $type, string $rootResource, bool $input, Operation $rootOperation, int $depth = 0, bool $forceNullable = false): ?array { ... } 

This method is called a little bit up at https://github.com/api-platform/core/blob/v3.0.9/src/GraphQl/Type/FieldsBuilder.php#L216

if ($fieldConfiguration = $this->getResourceFieldConfiguration($property, $propertyMetadata->getDescription(), $propertyMetadata->getDeprecationReason(), $propertyType, $resourceClass, $input, $operation, $depth, null !== $propertyMetadata->getSecurity())) {
   $fields['id' === $property ? '_id' : $this->normalizePropertyName($property, $resourceClass)] = $fieldConfiguration;
}

So maybe just passing null !== $propertyMetadata->getSecurity() || null !== $propertyMetadata->getDefault() instead of just null !== $propertyMetadata->getSecurity() would already be enough but needs to be further investigated …

+1

+1

while @ORM\Column(nullable=true) sets the default for a field being nullable (or not) it should be configurable as well.