How to embed nullable relations in ApiPlatform using GraphQL

How to embed nullable relations in ApiPlatform using GraphQL


0

I am creating an API with ApiPlatform v3.2.1 and make use of the GraphQL features to query the API. How can I make it possible to use nullable embedded relations?

For example I have an entity "Ordering" and nullable one-to-one related entities "ProductFoo" and "ProductBar". "ProductFoo" and "ProductBar" relation to "Ordering" is not nullable for them.

Now I want to create an Order and maybe embed ProductFoo but not ProductBar. But php bin/console api:graphql:export gives me a graphql schema indicating that createProductFooNestedInput and createProductBarNestedInput are required …

"Creates a Ordering."
createOrdering(input: createOrderingInput!): createOrderingPayload

"Creates a Ordering."
input createOrderingInput {
  comment: String
  productFoo: createProductFooNestedInput!
  productBar: createProductBarNestedInput!
  clientMutationId: String
}

"Creates a Ordering."
type createOrderingPayload {
  ordering: Ordering
  clientMutationId: String
}

Sending something like

{
    "ordering" : {
      "productFoo": {
          "someFooProp": "999999"
      }
    }
}

omitting the productBar then of course gives me an error like: "Field "productBar" of required type "createProductBarNestedInput!" was not provided."

Here are my sample entities …

<?php

namespace AppEntity;

use ApiPlatformMetadataApiResource;
use ApiPlatformMetadataGraphQlMutation;
use ApiPlatformMetadataGraphQlQueryCollection;
use DoctrineORMMapping as ORM;
use SymfonyComponentSerializerAnnotationGroups;

#[ORMEntity]
#[ApiResource(
    normalizationContext: ['groups' => ['ordering:read']],
    denormalizationContext: ['groups' => ['ordering:write']],
    graphQlOperations: [
        new QueryCollection(),
        new Mutation(name: 'create'),
    ],
)]
class Ordering
{
    #[ORMId]
    #[ORMGeneratedValue]
    #[ORMColumn]
    private ?int $id = null;

    #[Groups(['ordering:read', 'ordering:write'])]
    #[ORMOneToOne(mappedBy: 'ordering', cascade: ['persist', 'remove'])]
    private ?ProductFoo $productFoo = null;

    #[Groups(['ordering:read', 'ordering:write'])]
    #[ORMOneToOne(mappedBy: 'ordering', cascade: ['persist', 'remove'])]
    private ?ProductBar $productBar = null;

    // ... 
    
}

<?php

namespace AppEntity;

use ApiPlatformMetadataApiResource;
use DoctrineDBALTypesTypes;
use DoctrineORMMapping as ORM;
use SymfonyComponentSerializerAnnotationGroups;

#[ORMEntity]
#[ApiResource]
class ProductFoo
{
    #[ORMId]
    #[ORMGeneratedValue]
    #[ORMColumn]
    private ?int $id = null;

    #[ORMOneToOne(inversedBy: 'productFoo', cascade: ['persist', 'remove'])]
    #[ORMJoinColumn(nullable: true)]
    private ?Ordering $ordering = null;

    #[Groups(['ordering:write'])]
    #[ORMColumn(type: Types::BIGINT, nullable: true)]
    private ?string $sommeFooProp = null;

    // ...
}
<?php

namespace AppEntity;

use ApiPlatformMetadataApiResource;
use DoctrineDBALTypesTypes;
use DoctrineORMMapping as ORM;
use SymfonyComponentSerializerAnnotationGroups;

#[ORMEntity]
#[ApiResource]
class ProductBar
{
    #[ORMId]
    #[ORMGeneratedValue]
    #[ORMColumn]
    private ?int $id = null;

    #[ORMOneToOne(inversedBy: 'productBar', cascade: ['persist', 'remove'])]
    #[ORMJoinColumn(nullable: false)]
    private ?Ordering $ordering = null;

    #[Groups(['ordering:write'])]
    #[ORMColumn(type: Types::BIGINT, nullable: true)]
    private ?string $sommeBarProp = null;

    // ...
}

I tried to apply #[ApiProperty(required: false)] or #[ApiProperty(security: 'is_granted("ROLE_USER")')] to the productBar and productFoo fields which usually makes the property nullable, but without success.

Any idea on how i could get this working?


Load 6 more related questions


Show fewer related questions

0



Leave a Reply

Your email address will not be published. Required fields are marked *