Search code examples
api-platform.com

API Platform - Adding new entity with subresource


As far as I can see this isn't possible but I thought I'd ask in case I've missed something.

I have 2 entities, Rule and Condition

One Rule can have many Conditions

What I'm trying to achieve is adding a new Rule with one or more Conditions in a single request

I've tried the following via POST

{
  "property": "id",
  "conditions": [
    {
        "position": 1
    }
  ],
  "title": "getId",
  "position": 1
}

Conditions have a rule_id column, but I obviously can't set it at this point as it hasn't been created yet

That request gives me the error

Nested documents for attribute "conditions" are not allowed. Use IRIs instead.

Of course, I can't use an IRI because I haven't created the condition yet, and I can't create the condition first as it would fail foreign key checks

So am I right in thinking this isn't possible or am I just doing it wrong?

Thanks in advance


Solution

  • You need to add the same serialization group to both the Rule and Condition classes, as explained here.

    Also you must add the cascade={"persist"} attribute to the @OneToMany annotation of the Rule::conditions property.

    Something like that:

    // src/EntityRule.php
    
    #[ORM\Entity(repositoryClass: RuleRepository::class)]
    #[ApiResource(
        collectionOperations: [
            "post" => [
                "denormalization_context" => [ "groups" => ["write:rule"]]
            ]
        ]
    )]
    class Rule
    {
        // ...
        
        #[ORM\OneToMany(mappedBy: "rule", targetEntity: Condition::class, cascade: ["persist"])]
        #[Groups(["write:rule"])]
        /**
         * @var Condition[]
         */
        private Collection $conditions;
    
        // ...
    }
    
    // src/Entity/Condition.php
    
    #[ORM\Entity(repositoryClass: ConditionRepository::class)]
    #[ApiResource(
        collectionOperations: [
            "post" => [
                "denormalization_context" => ["groups" => ["write:condition"]
                ]
            ]
        ]
    )]
    class Condition
    {
        // ...
    
        #[ORM\Column(nullable=false, unique=false)]
        #[Groups(["write:condition", "write:rule"])]
        private int $position;
    
        // ...
    }