[GraphQL] Custom Query args: referencing another resource's derived enum type crashes schema build ("The type ... was not resolved")
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 48/100
Direzione di ricerca
Riproduci il problema con la configurazione Symfony/API Platform GraphQL descritta eseguendo bin/console api:graphql:export. Inizia da vendor/api-platform/graphql/Type/TypeConverter.php e FieldsBuilder::resolveResourceArgs(), quindi segui SchemaBuilder::getSchema() per vedere quando i tipi enum entrano in typesContainer. Il lavoro è completato quando la compilazione dello schema non va più in crash per l’argomento di query personalizzato, oppure fallisce prima con un messaggio chiaro relativo all’uso non supportato.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
API Platform version(s) affected: 4.3.17 (also reproduces on 4.3.4)
Description
A custom #[GraphQl\Query]'s args: entry that names a GraphQL enum type by string — one that only exists in the schema because another resource has a property typed with that backed enum — crashes the entire schema build with:
The type "WidgetStatus!" was not resolved.
thrown from TypeConverter::resolveType(). The root cause: typesContainer only gets WidgetStatus registered as a side effect of building Widget's own GraphQL fields, which has not necessarily happened yet when FieldsBuilder::resolveResourceArgs() eagerly resolves this custom query's arg type. Because schema build is a single pass over the whole Query type, this takes down every /graphql request, not just the one query that declared the bad arg — there is no partial-schema fallback.
This looks like the same root cause as #8068 ("Type ... is not present in the types container", nested mutation input, still open) and #3651 (a custom ObjectType referencing an entity type too early, closed wontfix) — different trigger, same underlying typesContainer-populated-lazily-and-incompletely problem.
How to reproduce
Minimal Symfony 7 + api-platform/symfony + api-platform/graphql project, no Doctrine, no database. Two plain resources:
src/Enum/WidgetStatus.php:
enum WidgetStatus: string
{
case DRAFT = 'draft';
case PUBLISHED = 'published';
case ARCHIVED = 'archived';
}
src/ApiResource/Widget.php — property typed with the enum, which is what registers the WidgetStatus GraphQL type:
#[ApiResource(
operations: [],
graphQlOperations: [new Query(resolver: WidgetQueryResolver::class)],
)]
final class Widget
{
#[ApiProperty(identifier: true)]
public string $id = '1';
public WidgetStatus $status = WidgetStatus::DRAFT;
}
src/ApiResource/WidgetStatusOptions.php — an unrelated resource whose custom query's arg names that enum:
#[ApiResource(
operations: [],
graphQlOperations: [
new Query(
name: 'widgetStatusOptions',
resolver: WidgetStatusOptionsQueryResolver::class,
args: ['status' => ['type' => 'WidgetStatus!']],
read: false,
),
],
)]
final class WidgetStatusOptions
{
#[ApiProperty(identifier: true)]
public string $id = '1';
/** @var list<string> */
public array $allowedNext = [];
}
(Resolvers just return new Widget() / new WidgetStatusOptions() — happy to push the full minimal project to a repo on request.)
Running bin/console api:graphql:export (or hitting /api/graphql) throws immediately:
In TypeConverter.php line 134:
[ApiPlatform\Metadata\Exception\InvalidArgumentException]
The type "WidgetStatus!" was not resolved.
Exception trace:
TypeConverter->resolveType() at vendor/api-platform/graphql/Type/TypeConverter.php:134
FieldsBuilder->resolveResourceArgs() at vendor/api-platform/graphql/Type/FieldsBuilder.php:307
FieldsBuilder->getItemQueryFields() at vendor/api-platform/graphql/Type/FieldsBuilder.php:91
SchemaBuilder->getSchema() at vendor/api-platform/graphql/Type/SchemaBuilder.php:63
GraphQlExportCommand->execute() at vendor/api-platform/symfony/Bundle/Command/GraphQlExportCommand.php:69
Possible Solution
Either resolve the type regardless of resource-processing order (e.g. force-build every resource's fields, or at least every resource that contributes a type referenced from args:, before resolving custom-query arg types), or fail at attribute-declaration time with a clear message saying a custom query's args: cannot reference a resource-derived type — rather than crashing the whole schema at request time with a message that doesn't say why the type wasn't found.
Workaround we're using in the meantime: declare the arg as 'type' => 'String!' and match the incoming value against WidgetStatus::cases() by hand inside the resolver. This is presumably why every other custom-query-with-a-typed-arg example in the docs/tests only uses String/Int/Float.
Additional Context
- Confirmed this is not fixed by upgrading: reproduces identically on both v4.3.4 and v4.3.17 (the latest release on the 4.3 line as of this report).
- Environment: PHP 8.4.10 (ZTS), Symfony 7.4.16 (framework-bundle), api-platform/graphql v4.3.17, api-platform/symfony v4.3.17, no Doctrine/database involved.
- Related: #8068, #3651 — same
typesContainer-populated-lazily root cause, different trigger.
- Lingua principale
- PHP
- Stelle
- 2.6k
- Fork
- 982
- Merge medio
- 1g 16h
- PR unite (30g)
- 59
Guida per i contributori
Apri 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
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 85/100
api-platform/core#8573 ·
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
api-platform/core#8571 ·
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
api-platform/core#8564 ·
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
api-platform/core#8495 ·
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
api-platform/core#8471 ·
Tutte le issue di api-platform/core
Issue simili
-
tooling
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
-
UX
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
ProfessionalWiki/NeoWiki#1525 ·
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 90/100
OpenConext/OpenConext-engineblock#2122 ·
-
Bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
Automattic/safe-publish#594 ·