Core: Swagger 2.0 embedded documents not supported

Created on 14 Jul 2016  ยท  11Comments  ยท  Source: api-platform/core

When embedding documents (non-apiplatform resources) swagger is not able to process them.
These embedded docs can be MongoDB docs for example:

/**
* @ApiResource(
 *     iri="https://schema.org/Product",
 * )
*/
class Product {
/**
     * @ApiProperty(iri="https://schema.org/offer")
     *
     * @var Offer 
     */
    protected $offer;
}
/**
 * {@inheritdoc}
 */
class Offer
{
....
}

Problem:

if (!$this->resourceClassResolver->isResourceClass($className)) {
  return [];
}

This will fail because Offer is not a registered api resource.

enhancement โญ EU-FOSSA Hackathon

Most helpful comment

Almost 2 years old but still open. Any progress on this issue?

The current DocumentationNormalizer just stops here.

The normalizer is currently missing a metadataFactory to add definitions for any object that is not a resource.
Is it possible to use Symfony's Serializer ClassMetadata for this purpose?

All 11 comments

Thanks for using Api-Platform and testing this out !

We are generating the doc based on resources,

What do you suggest to do that ?

Well the nelmio docs generated docs based off the serializer if i'm not mistaken.
We could maybe use this:

return ['complex' => true, 'value' => sprintf('#/definitions/%s', $this->embeddedMetadataFactory->create($className)->getShortName())];

And then figure out which properties we can use. This is an example of an embedded document:

/**
 * {@inheritdoc}
 */
class Offer implements OfferInterface
{
    use TimestampableDocument;

    /**
     * @ApiProperty(identifier=true)
     */
    protected $id;

    /**
     * @ApiProperty(iri="https://schema.org/availability")
     */
    protected $availability;

    /**
     * @ApiProperty(iri="https://schema.org/inventoryLevel")
     */
    protected $inventoryLevel;

    /**
     * @ApiProperty(iri="https://schema.org/priceSpecification")
     */
    protected $priceSpecification;

    /**
     * NOTE: This can be a reference to an Api platform resource (In this case "Product")
     * @ApiProperty(iri="https://schema.org/itemOffered")
     */
    protected $itemOffered;

Are you sure that the Nelmio bridge is able to handle such cases?
Maybe that a temporary fix can be to allow any value for this property: { "type": [ "object", "any" ] }

This will just give an empty model. Imo there are 2 solutions.

  1. Add support for embedded documents in the IriConverter -> Means embedded docs should have @ApiResource annotation (either with custom property "embedded"=true or all operations manually disabled since embedded docs cannot be exposed through it's own url.
    The serializer should then simple ignore the @id and @iri if the iriconverter fails.
  2. Create a workaround in the swagger docs

Correct me if I'm wrong but, by definition, an embedded document doesn't have its own IRI (it is embedded). So it's weird to use the IriConverter for that.

What we can do in the Swagger generator is:

  1. Try to guess the schema of this non-resource object using the Symfony PropertyInfo Component
  2. If it fails, add an any definition (for instance if the field accept any structure, like when using https://github.com/dunglas/doctrine-json-odm)

Dunglas, that is indeed the point. I expressed myself incorrectly. The IriConverter should keep throwing an expection since it cant generate an iri. The serializer however should catch it and dont set the @id and serialize the embedded document.
IMO the serializer solution required tagging your embedded docs as a resource which i think is not correct. For swagger you need to add the embedded document to the $definitions array i believe in order for the javascript to correctly parse it. Maybe @Simperfit has any suggestions?

Using the PropertyInfo Component does not force us to tag them as a resource, and this is what you need right ? I'd like to go this way :).

This seems related to the larger issue of embedded resources (in a loose sense) not being well supported. Perhaps we might want to have a meta issue tracking the quality of embedded resource support (especially the DX).

Almost 2 years old but still open. Any progress on this issue?

The current DocumentationNormalizer just stops here.

The normalizer is currently missing a metadataFactory to add definitions for any object that is not a resource.
Is it possible to use Symfony's Serializer ClassMetadata for this purpose?

Any news ?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kate-kate picture kate-kate  ยท  3Comments

rockyweng picture rockyweng  ยท  3Comments

tezvi picture tezvi  ยท  3Comments

dematerializer picture dematerializer  ยท  3Comments

gustawdaniel picture gustawdaniel  ยท  3Comments