nelmio / NelmioApiDocBundle

Generates documentation for your REST API from annotations
MIT License
2.22k stars 833 forks source link

Problem due to fix of #1756 #1843

Open tteze opened 3 years ago

tteze commented 3 years ago

I'm actually facing a problem due to this lines in ObjectModelDescriber (line 93) My model attributes using '_' are not displayed in schemas description. due to fix of https://github.com/nelmio/NelmioApiDocBundle/issues/1756

// Fix for https://github.com/nelmio/NelmioApiDocBundle/issues/1756

// The SerializerExtractor does expose private/protected properties for some reason, so we eliminate them here

$propertyInfoProperties = array_intersect($propertyInfoProperties, $this->propertyInfo->getProperties($class, []) ?? []);

it seems $this->propertyInfo->getProperties($class, []) ?? []) return properties as camel case because of ReflectionExtractor but $this->propertyInfo->getProperties($class, $context) return properties as snake case because it's SerializerExtractor.

GuilhemN commented 3 years ago

I'm not able to reproduce. The SerializerExtractor is supposed to return the property names and not the normalized names, and that's indeed what I observed in my tests. Configuring the snake case converter works seamlessly with NelmioApiDocBundle in my app.

Could you provide more information about your configuration, the entity that is incorrectly documented and the arguments you try to document it with (parameters of your @Model annotation).

tteze commented 3 years ago

This is an example of one of my model created with entity maker from fresh symfony install. When I generate a schema for @Model(type=Analyse::class, groups={"list_demandes"}) all attributes with _ are not displayed (lien_1, lien_2, created_at).

  /**
   * @ORM\Entity(repositoryClass=AnalyseRepository::class)
   * @ORM\HasLifecycleCallbacks()
   */
  class Analyse
  {
      /**
       * @ORM\Id
       * @ORM\GeneratedValue
       * @ORM\Column(type="integer")
       * @Groups({"list_demandes", "show_demande"})
       */
      private $id;

      /**
       * @ORM\Column(type="text", nullable=true)
       * @Groups({"list_demandes", "show_demande"})
       * @Assert\NotBlank()
       */
      private $description;

      /**
       * @ORM\ManyToOne(targetEntity=Lien::class)
       * @ORM\JoinColumn(nullable=true)
       * @Groups({"list_demandes", "show_demande"})
       */
      private $lien_1;

      /**
       * @ORM\ManyToOne(targetEntity=Lien::class)
       * @ORM\JoinColumn(nullable=true)
       * @Groups({"list_demandes", "show_demande"})
       */
      private $lien_2;

      /**
       * @ORM\Column(type="datetime")
       * @Groups({"list_demandes", "show_demande"})
       */
      private $created_at;
  }

And I've just this in my nelmio config :

nelmio_api_doc:
    documentation:
        info:
            title: EXAMPLE
            description: API EXAMPLE
            version: 1.0.0
    areas: # to filter documented areas
        path_patterns:
            - ^/api(?!/doc$) # Accepts routes under /api except /api/doc
p-golovin commented 1 year ago

I have the similar problem with ODM Documents, where properties names are in snake case.

#[ODM\EmbeddedDocument]
class SectionFlags
{
    #[Groups(['category'])]
    #[ODM\Field(type: 'int')]
    private bool $is_active;

    public function isActive(): bool
    {
        return $this->is_active;
    }
}

SerializerExtractor returns array of fields: ['is_active']. ReflectionExtractor returns array of fields: ['isActive'] and there is no way to configure it: vendor/symfony/property-info/Extractor/ReflectionExtractor.php:130

if ($reflectionClass->hasProperty($lowerCasedPropertyName = lcfirst($propertyName)) || (!$reflectionClass->hasProperty($propertyName) && !preg_match('/^[A-Z]{2,}/', $propertyName))) {
    $propertyName = $lowerCasedPropertyName;
}

So intersection is empty here: vendor/nelmio/api-doc-bundle/ModelDescriber/ObjectModelDescriber.php:117

Symfony version - 6.1.4 ApiDocBundle version - 4.10.2

tteze commented 1 year ago

If I remember well, I get around this problem with the @SerializedName annotation on the getter. I hope it may help you...