Add polymorphism support (based on discriminator)
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Idoneità per principianti
- 25/100
- Tipo di issue
- Funzionalità
- Chiarezza
- Abbastanza chiara
- Stato di attività
- Ferma
- Ambito
- api, backend, backend-api-design
Direzione di ricerca
Inizia leggendo PropertyNameCollectionFactory e PropertyMetadataFactory, quindi segui i percorsi del normalizer di Serializer e del generatore di schemi descritti nell’issue. Il lavoro è completato quando le sottoclassi basate su discriminator serializzano e deserializzano le proprie proprietà e viene considerato il supporto richiesto per il polimorfismo OpenAPI.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Description
This was already closed in https://github.com/api-platform/core/issues/2931, but I would like you to reconsider.
Since it's quite limiting not being able to use Doctrine's Inheritance mapping and OpenAPI has nowadays quite good polymorphism support thanks to discriminator, oneOf, anyOf etc, I believe it makes sense to reconsider support of this. At beginning, I think most people would be fine if APIP at least allowed serialization/deserialization of properties in subclasses. Schema generator could be adjusted later to generate things like this
Main issue I would like to solve is that serializer does not see properties from subclasses. After further debugging I found that PropertyNameCollectionFactory and PropertyMetadataFactory are responsible. However, these factories only accept $resourceClassand not an actual class that Serializer is serializing/deserializing, hence it's not possible to simply add own implementation of these factories.
Example
#[ApiResource()]
#[Doctrine\ORM\Mapping\Entity()]
#[Doctrine\ORM\Mapping\InheritanceType('SINGLE_TABLE')]
#[Doctrine\ORM\Mapping\DiscriminatorColumn('type', 'string')]
#[Doctrine\ORM\Mapping\DiscriminatorMap(self::DISCRIMINATOR_MAPPING)]
#[Symfony\Component\Serializer\Attribute\DiscriminatorMap('type', self::DISCRIMINATOR_MAPPING)]
abstract class DatasyncConnector {
private const array DISCRIMINATOR_MAPPING = ["SCIM" => SCIMConnector::class, "JSON" => JSONConnector::class];
public string $type;
}
{}
#[ORM\Entity()]
class SCIMConnector extends DatasyncConnector {
public ?string $foo = null;
}
#[ORM\Entity()]
class JSONConnector extends DatasyncConnector {
public ?string $bar = null;
}
Here, I expect serialization will result in
{"type": "SCIM", "foo": "string"}
or
{"type": "JSON", "bar": "string"}
Similarly, deserialization should accept (and write to) these properties
Further context
Currently, I have added support for this in application I'm maintaining by enabling allow_extra_attributes and implementing custom normalizer:
#[AutoconfigureTag('serializer.normalizer', ['priority' => 1])]
class DatasyncConnectorNormalizer implements NormalizerInterface, DenormalizerInterface
{
public function __construct(
#[Autowire(service: 'serializer.normalizer.object')]
private ObjectNormalizer $normalizer,
#[Autowire(service: 'api_platform.jsonld.normalizer.item')]
private AbstractNormalizer $jsonldNormalizer,
) {}
public function denormalize(mixed $data, string $type, ?string $format = null, array $context = []): mixed
{
return $this->normalizer->denormalize(
$data,
$type,
$format,
[
AbstractNormalizer::OBJECT_TO_POPULATE => $this->jsonldNormalizer
->denormalize($data, $type, $format, $context),
] + $context,
);
}
public function supportsDenormalization(
mixed $data,
string $type,
?string $format = null,
array $context = [],
): bool {
return true;
}
public function normalize(
mixed $data,
?string $format = null,
array $context = [],
): null|array|\ArrayObject|bool|float|int|string {
\assert($data instanceof DatasyncConnector);
$context['uri_variables'] = ['id' => $data->id];
return $this->jsonldNormalizer->normalize($data, $format, $context)
+ $this->normalizer->normalize($data, $format, $context);
}
public function supportsNormalization(mixed $data, ?string $format = null, array $context = []): bool
{
return true;
}
public function getSupportedTypes(?string $format): array
{
return [DatasyncConnector::class => true];
}
}
Even OpenAPI schema is adjusted thanks to implementing own OpenApiFactory which generates definitions for subclasses, then linking to them from resource like so
new GetCollection(openapi: new OpenApiOperation(responses: [
200 => new Response(content: new \ArrayObject(['application/ld+json' => [
'schema' => [
'type' => 'array',
'items' => [
'oneOf' => [
['$ref' => self::SCHEMA_PATH_PREFIX.'.jsonld-connector.output'],
['$ref' => self::SCHEMA_PATH_PREFIX.'.jsonld-connector.output_MS_GRAPH'],
],
'discriminator' => [
'propertyName' => 'type',
'mapping' => [
DatasyncConnectorType::SCIM->value
=> self::SCHEMA_PATH_PREFIX.'.jsonld-connector.output',
DatasyncConnectorType::JSON->value
=> self::SCHEMA_PATH_PREFIX.'.jsonld-connector.output',
DatasyncConnectorType::MS_GRAPH->value
=> self::SCHEMA_PATH_PREFIX.'.jsonld-connector.output_MS_GRAPH',
],
],
],
],
]])),
])),
- Lingua principale
- PHP
- Stelle
- 2.6k
- Fork
- 989
- Merge medio
- 2g 1h
- PR unite (30g)
- 104
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di api-platform/core
-
JSON:API: resource schemas (`*.jsonapi`) have `properties` but no `type: object`Forse già presa @ousamabenyounes l’ha presa 1 giorno fa. Aperta
Difficoltà 2/5 Meno di un'ora Idoneità per principianti 80/100
api-platform/core#8701 ·
I maintainer di solito rispondono entro 1 giorno
-
JSON:API: `JsonApiCollectionBaseSchemaNoPagination` declares `data` as `type: array` without `items`Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
api-platform/core#8699 ·
I maintainer di solito rispondono entro 1 giorno
-
api:openapi:export --spec-version=3.0.0 outputs `webhooks`, which is invalid in OpenAPI 3.0Forse già presa Una pull request collegata a questa issue è aperta o già unita. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
api-platform/core#8690 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 85/100
api-platform/core#8680 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 3/5 1-2 giorni Idoneità per principianti 68/100
api-platform/core#8725 ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di api-platform/core
Issue simili
-
create:theme --tailwind scaffolds version.yaml at 1.0.0 while the LESS variant scaffolds 1.0.1Aperta
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 80/100
I maintainer di solito rispondono entro 1 giorno
-
PHP workflow streaming requests buffer the full SSE responseForse già presa @Winoren l’ha presa oggi. Apertareview: medium
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
langgenius/dify#44270 · 1 commento · 1 reazione ·
I maintainer di solito rispondono entro 1 giorno
-
bug customer-reported
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 90/100
MagnaCapax/PMSS#1085 ·
I maintainer di solito rispondono entro 5 giorni
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 83/100
nunomaduro/collision#375 ·