OpenAPI: Non-JSON formats should not generate JSON schemas
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 45/100
Direzione di ricerca
Inizia da src/OpenApi/Factory/OpenApiFactory.php e src/Symfony/Bundle/Resources/config/openapi.php, quindi esamina come viene calcolato jsonschema_formats in ApiPlatformExtension.php. Aggiorna il comportamento di OpenAPI per i formati di risposta non JSON e aggiungi il caso di regressione in tests/OpenApi/Factory/OpenApiFactoryTest.php; il lavoro è concluso quando i formati non JSON non ricevono più schemi JSON generati.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Issue Description
When an API Platform operation defines non-JSON output formats (e.g., text/html, text/xml), the OpenAPI factory generates JSON schemas for these formats, which is semantically incorrect.
Example
#[ApiResource(
operations: [
new Get(
uriTemplate: '/unsubscribe/{token}',
formats: [
'jsonld' => ['application/ld+json'],
'json' => ['application/json'],
'html' => ['text/html'], // This causes the issue
],
),
],
)]
class UnsubscribedEmail {}
Current Behavior
The OpenAPI export generates:
paths:
/api/unsubscribe/{token}:
get:
responses:
'200':
content:
application/ld+json:
schema:
$ref: '#/components/schemas/UnsubscribedEmail.jsonld'
application/json:
schema:
$ref: '#/components/schemas/UnsubscribedEmail'
text/html:
schema:
$ref: '#/components/schemas/UnsubscribedEmail.html' # Makes no sense
components:
schemas:
UnsubscribedEmail.html: # JSON schema for HTML format - meaningless
type: object
properties:
status:
type: string
Expected Behavior
Non-JSON formats should either:
- Not have a
schemareference in OpenAPI - Or be excluded from the OpenAPI spec entirely (content negotiation still works at runtime)
Root Cause
In src/OpenApi/Factory/OpenApiFactory.php, the getMimeTypes() method returns ALL output formats, and the schema generation loop creates schemas for each:
// Lines 267-273
foreach ($responseMimeTypes as $operationFormat) {
$operationOutputSchema = $this->jsonSchemaFactory->buildSchema(
$resourceClass,
$operationFormat, // <-- Includes 'html', 'xml', etc.
Schema::TYPE_OUTPUT,
$operation,
$schema,
null,
$forceSchemaCollection
);
$operationOutputSchemas[$operationFormat] = $operationOutputSchema;
}
Proposed Fix
Use the existing jsonschema_formats configuration parameter to filter which formats get JSON schemas in OpenAPI.
Step 1: Inject jsonschema_formats into OpenApiFactory
In src/Symfony/Bundle/Resources/config/openapi.php:
$services->set('api_platform.openapi.factory', OpenApiFactory::class)
->args([
// ... existing args ...
'%api_platform.jsonschema_formats%', // Add this parameter
]);
Step 2: Update OpenApiFactory constructor
public function __construct(
// ... existing parameters ...
private readonly array $jsonSchemaFormats = [],
) {
// ...
}
Step 3: Filter formats in schema generation loop
// Around line 267
foreach ($responseMimeTypes as $mimeType => $operationFormat) {
// Skip formats that don't have JSON schema support
if (!isset($this->jsonSchemaFormats[$operationFormat])) {
continue;
}
$operationOutputSchema = $this->jsonSchemaFactory->buildSchema(
$resourceClass,
$operationFormat,
Schema::TYPE_OUTPUT,
$operation,
$schema,
null,
$forceSchemaCollection
);
$operationOutputSchemas[$operationFormat] = $operationOutputSchema;
}
Step 4: Update buildContent to handle missing schemas
private function buildContent(array $responseMimeTypes, array $operationSchemas): \ArrayObject
{
$content = new \ArrayObject();
foreach ($responseMimeTypes as $mimeType => $format) {
// Only add content entry if we have a schema for this format
if (isset($operationSchemas[$format])) {
$content[$mimeType] = new MediaType(
schema: new \ArrayObject($operationSchemas[$format]->getArrayCopy(false))
);
}
// Non-JSON formats without schemas are simply not included in OpenAPI content
}
return $content;
}
Alternative Consideration
The buildContent method could instead add the content type without a schema reference:
if (isset($operationSchemas[$format])) {
$content[$mimeType] = new MediaType(schema: new \ArrayObject($operationSchemas[$format]->getArrayCopy(false)));
} else {
// Include the content type but without a schema (valid in OpenAPI 3.1)
$content[$mimeType] = new MediaType();
}
This preserves the information that the endpoint supports HTML responses, just without a JSON schema.
Testing
Add a test case to tests/OpenApi/Factory/OpenApiFactoryTest.php:
public function testNonJsonFormatsDoNotGenerateSchemas(): void
{
// Create a resource with html format
// Assert that UnsubscribedEmail.html schema does not exist
// Assert that text/html content type either has no schema or is not present
}
Configuration Reference
The jsonschema_formats is already computed in ApiPlatformExtension.php:
$jsonSchemaFormats = $config['jsonschema_formats'];
if (!$jsonSchemaFormats) {
foreach (array_merge(array_keys($formats), array_keys($errorFormats)) as $f) {
// Only JSON-based formats get schemas by default
if (str_starts_with($f, 'json')) {
$jsonSchemaFormats[$f] = true;
}
}
}
This logic already correctly identifies JSON formats - it just needs to be used in OpenApiFactory.
- Lingua principale
- PHP
- Stelle
- 2.6k
- Fork
- 984
- Merge medio
- 1g 10h
- PR unite (30g)
- 88
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
-
Symfony 8.2: object mapper feature probe loads deprecated translation commandForse già presa @tacman l’ha presa 4 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
api-platform/core#8626 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 88/100
api-platform/core#8612 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 48/100
api-platform/core#8634 ·
I maintainer di solito rispondono entro 1 giorno
-
HTTP cache purgers error handling and performance issuesForse già presa Una pull request collegata a questa issue è aperta o già unita. Aperta
Difficoltà 4/5 3-5 giorni Idoneità per principianti 38/100
api-platform/core#8591 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 48/100
api-platform/core#8535 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di api-platform/core
Issue simili
-
Talk Review
Difficoltà 2/5 1-3 ore Idoneità per principianti 66/100
socallinuxexpo/scale-drupal#351 ·
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
code4romania/cpc#47 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 90/100
mautic/api-library#351 · 1 commento ·
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 74/100
nunomaduro/collision#371 ·
-
Lead create/update: a product row without a "product_id" key passes LeadForm validation and fails in the database (500)Forse già presa @Arslan-TR l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
krayin/laravel-crm#2681 ·
I maintainer di solito rispondono entro 2 giorni