OpenAPI: Support for JSON-LD Only APIs
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 5/5
- Tiempo estimado
- Más de una semana
- Aptitud para principiantes
- 38/100
- Tipo de issue
- Nueva funcionalidad
- Claridad
- Bastante claro
- Estado de actividad
- Tranquilo
- Área
- api, documentation
Línea de trabajo
Empieza por src/Symfony/Bundle/DependencyInjection/Configuration.php y src/OpenApi/Factory/OpenApiFactory.php, especialmente por el punto de entrada getMimeTypes(). Compara los enfoques propuestos de prefer_format, formats y deduplicación automática antes de concretar el alcance. Se considerará terminado cuando la configuración elegida produzca una salida OpenAPI con solo los esquemas y tipos de contenido previstos, sin cambiar los formatos en tiempo de ejecución.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Context
When building a JSON-LD only API (no plain JSON format), the OpenAPI specification still generates duplicate schemas and content types. Users have to create custom OpenApiFactory decorators to filter these out.
Current Behavior
With this configuration:
api_platform:
formats:
jsonld: ['application/ld+json']
error_formats:
jsonld: ['application/ld+json']
jsonproblem: ['application/problem+json']
The OpenAPI export still produces:
- Duplicate schemas:
EmailMessageANDEmailMessage.jsonld - Multiple content types in responses:
application/ld+json,application/problem+json,application/json
Workaround We Implemented
We created an OpenApiFactory decorator that:
1. Filters non-JSON-LD content types from responses
private const NON_JSONLD_MIME_TYPES = [
'text/html',
'application/problem+json',
'application/json',
];
private function filterNonJsonContentTypes(PathItem $pathItem): PathItem
{
foreach (PathItem::$methods as $method) {
$operation = $pathItem->{"get" . ucfirst(strtolower($method))}();
if (null === $operation) continue;
foreach ($operation->getResponses() as $status => $response) {
$content = $response->getContent();
if ($content) {
$filteredContent = new \ArrayObject();
foreach ($content as $mimeType => $mediaType) {
if (!in_array($mimeType, self::NON_JSONLD_MIME_TYPES, true)) {
$filteredContent[$mimeType] = $mediaType;
}
}
// ... update response
}
}
}
return $pathItem;
}
2. Removes duplicate schemas (keeps only .jsonld versions)
private function filterNonJsonSchemas(OpenApi $openApi): OpenApi
{
$schemas = $openApi->getComponents()->getSchemas();
// Collect base names that have .jsonld versions
$jsonldSchemas = [];
foreach ($schemas as $name => $schema) {
if (str_ends_with($name, '.jsonld')) {
$jsonldSchemas[substr($name, 0, -7)] = true;
}
}
$filteredSchemas = new \ArrayObject();
foreach ($schemas as $name => $schema) {
$baseName = preg_replace('/\.jsonld$/', '', $name);
// Skip non-.jsonld version when .jsonld exists
if (!str_ends_with($name, '.jsonld') && isset($jsonldSchemas[$baseName])) {
continue;
}
$filteredSchemas[$name] = $schema;
}
return $openApi->withComponents($components->withSchemas($filteredSchemas));
}
Proposed Framework Enhancement
Option A: openapi.prefer_format Configuration
Add a configuration option to specify the preferred format for OpenAPI documentation:
api_platform:
openapi:
prefer_format: jsonld # Only show jsonld schemas and content types
Implementation:
In OpenApiFactory, when prefer_format is set:
- Only generate schemas for that format (skip others even if configured)
- Only include that format's content type in responses
- Remove duplicate schemas that exist in multiple format variants
Option B: openapi.formats Configuration
Allow explicit control over which formats appear in OpenAPI (separate from runtime formats):
api_platform:
formats:
jsonld: ['application/ld+json']
json: ['application/json'] # Available at runtime
openapi:
formats:
jsonld: ['application/ld+json'] # Only this in docs
Implementation:
In OpenApiFactory::getMimeTypes():
private function getMimeTypes(HttpOperation $operation): array
{
// Use openapi.formats if configured, otherwise fall back to operation formats
$responseFormats = $this->openapiFormats
?? $operation->getOutputFormats()
?? [];
// ... rest of method
}
Option C: Automatic Deduplication
When multiple formats produce equivalent schemas (same structure, different naming), automatically deduplicate:
// In OpenApiFactory::collectPaths() or a new dedicated method
private function deduplicateSchemas(\ArrayObject $schemas): \ArrayObject
{
$dominated = [];
// jsonld dominates json (more specific)
foreach ($schemas as $name => $schema) {
if (str_ends_with($name, '.jsonld')) {
$baseName = substr($name, 0, -7);
if (isset($schemas[$baseName])) {
$dominated[$baseName] = true;
}
}
}
// Remove dominated schemas
foreach ($dominated as $name => $_) {
unset($schemas[$name]);
}
return $schemas;
}
Recommendation
Option A (prefer_format) is the cleanest because:
- Simple, single configuration option
- Clear intent: "I want my OpenAPI docs in this format"
- Doesn't affect runtime behavior
- Easy to understand and document
Example implementation location:
- Configuration:
src/Symfony/Bundle/DependencyInjection/Configuration.php - Logic:
src/OpenApi/Factory/OpenApiFactory.php
Additional Consideration: Accept/Content-Type Headers
Our decorator also adds Accept and Content-Type header parameters to all operations, showing available formats as an enum. This is useful documentation that API Platform could generate automatically.
parameters:
- name: Accept
in: header
schema:
type: string
enum: ['application/ld+json']
default: 'application/ld+json'
This could be another configuration option:
api_platform:
openapi:
document_content_negotiation_headers: true
- Lenguaje dominante
- PHP
- Estrellas
- 2.6k
- Forks
- 989
- Merge medio
- 1 d 17 h
- PR fusionados (30 d)
- 81
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de api-platform/core
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
api-platform/core#8665 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
api-platform/core#8660 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
DeserializeProvider calls PartialDenormalizationException::getErrors(), deprecated in Symfony 8.1Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
api-platform/core#8650 ·
Los mantenedores suelen responder en 1 día
-
`OrderExtension` and `OrderFilter` pass string sort directions, deprecated since `doctrine/orm` 3.7Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
api-platform/core#8648 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
[Laravel] Optional BelongsTo relation cannot be set to null (500 on POST/PATCH)Posiblemente ocupada Un pull request vinculado a esta issue está abierto o ya se fusionó. Abierto
Dificultad 4/5 3-5 días Aptitud para principiantes 54/100
api-platform/core#8664 ·
Los mantenedores suelen responder en 1 día
Todos los issues de api-platform/core
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
scanaislop/aislop#482 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
Los mantenedores suelen responder en 1 día
-
documentation
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
humanmade/publication-checklist#73 · 1 comentario ·
-
Do not throw `WordPress.Security.EscapeOutput.OutputNotEscaped` on `apply_shortcodes()`Posiblemente ocupada @tbradsha la tomó hoy. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100