create-client icon indicating copy to clipboard operation
create-client copied to clipboard

Typescript: how to handle arrays or toMany relations

Open luca-nardelli opened this issue 6 years ago • 1 comments

Hey,

while I was working on an Angular generator I noticed that the current implementation of the typescript interface generator does not take into account toMany relations (or simple arrays as well).

I had a look at the fields property inside resource, however I can't seem to find any difference between single fields and array fields. I hoped that the maxCardinality property would help me, but it seems properly populated only for reference types.

Here is an example of what I mean:

Resource definition

    /**
     * @ORM\Column(type="text", nullable=true)
     * @Groups({"producerRead","userRead"})
     */
    private $name;

    /**
     * @ApiSubresource()
     * @ORM\OneToMany(targetEntity="App\Entity\Product", mappedBy="producer", orphanRemoval=true)
     * @Groups({"producerRead","userRead"})
     */
    private $products;

    /**
     * @ORM\OneToOne(targetEntity="App\Entity\Picture", cascade={"persist", "remove"})
     * @Groups({"producerRead","producerWrite"})
     */
    private $mainPicture;

    /**
     * @var array
     * @Groups({"producerRead","producerWrite"})
     */
    public $test;

Dump of resource.fields (part of id) inside the generate function

     Field {
       name: 'products',
       id: 'http://localhost:8080/api/docs.jsonld#Producer/products',
       range: 'http://localhost:8080/api/docs.jsonld#Product',
       reference: [Resource],
       required: false,
       description: '',
       maxCardinality: null,
       deprecated: false },
     Field {
       name: 'name',
       id: 'http://localhost:8080/api/docs.jsonld#Producer/name',
       range: 'http://www.w3.org/2001/XMLSchema#string',
       reference: null,
       required: false,
       description: '',
       maxCardinality: null,
       deprecated: false },
     Field {
       name: 'mainPicture',
       id: 'http://localhost:8080/api/docs.jsonld#Producer/mainPicture',
       range: 'http://localhost:8080/api/docs.jsonld#Picture',
       reference: [Resource],
       required: false,
       description: '',
       maxCardinality: 1,
       deprecated: false },
     Field {
       name: 'test',
       id: 'http://localhost:8080/api/docs.jsonld#Producer/test',
       range: null,
       reference: null,
       required: false,
       description: '',
       maxCardinality: null,
       deprecated: false },

In the swagger docs the property test is correctly picked up as a string array, however I can't seem to replicate the same thing for the typescript interfaces.

If we look at maxCardinality, it seems it is correct (if we assume null means 'collection') for reference fields (mainPicture is a OnetoOne and products is a ToMany), however this is not the case for name (string) and test (string array).

I'm asking here because there might be another field that helps me find out if I'm dealing with a collection or not and I'm missing it, but this issue might be related to doc-parser as well.

I'll gladly create a PR for the typescript generator if we find out how to fix this. Thanks!

luca-nardelli avatar May 17 '19 07:05 luca-nardelli

Upon further inspection, I reached DocumentationNormalizer.php in api-platform/core

https://github.com/api-platform/core/blob/master/src/Hydra/Serializer/DocumentationNormalizer.php#L469

It seems to me that if we change the if condition from

if (null !== $type && !$type->isCollection() && (null !== $className = $type->getClassName()) && $this->resourceClassResolver->isResourceClass($className)) {
            $propertyData['owl:maxCardinality'] = 1;
        }

To

if (null !== $type && !$type->isCollection()) {
            $propertyData['owl:maxCardinality'] = 1;
        }

We should obtain a correct value for the maxCardinality property: null for collections and 1 for scalar values/objects, even if they are primitive types.

If this is the case, we should probably move this issue to the core repo.

luca-nardelli avatar May 17 '19 15:05 luca-nardelli