Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

La potente especificación OpenAPI

Video not working?

It looks like your browser may not support the H264 codec. If you're using Linux, try a different browser or try installing the gstreamer0.10-ffmpeg gstreamer0.10-plugins-good packages.

Thanks! This saves us from needing to use Flash or encode videos in multiple formats. And that let's us get back to making more videos :). But as always, please feel free to message us.

Antes he dicho que estos documentos interactivos proceden de una biblioteca de código abierto llamada Swagger UI. Y siempre que tengas alguna configuración que describa tu API, como qué rutas tiene y qué campos se utilizan en cada ruta, puedes generar automáticamente estos documentos Swagger enriquecidos.

Dirígete a https://petstore3.swagger.io. Esto está muy bien: es un proyecto de demostración en el que se utiliza la interfaz de usuario Swagger en una API de demostración. Además, ¡tiene un enlace al archivo de configuración de la API que lo hace posible!

¡Hola OpenAPI!

Vamos... ¡a ver qué aspecto tiene! ¡Woh! Sí, este archivo JSON describe completamente la API, desde la información básica sobre la propia API, hasta las diferentes URL, como actualizar una mascota existente, añadir una nueva mascota a la tienda, las respuestas... todo. Si tienes uno de estos archivos, puedes obtener Swagger al instante.

El formato de este archivo se llama OpenAPI, que no es más que un estándar sobre cómo deben describirse las API.

De vuelta a nuestros documentos, debemos tener el mismo tipo de archivo de configuración, ¿verdad? Pues sí, visita /api/docs.json para ver nuestra versión. ¡Yup! Se parece mucho. Tiene rutas, describe las distintas operaciones... todo. Lo mejor es que API Platform lee nuestro código y genera este archivo gigante para nosotros. Entonces, como tenemos este archivo gigante, obtenemos Swagger UI.

De hecho, si haces clic en "Ver fuente de la página", puedes ver que esta página funciona incrustando el documento JSON real directamente en el HTML. Luego, hay algo de JavaScript Swagger que lee eso y arranca las cosas.

OpenAPI y herramientas gratuitas

La idea de tener una especificación OpenAPI que describa tu API es poderosa... porque cada vez hay más herramientas que pueden utilizarla. Por ejemplo, vuelve a la documentación de la API Platform y haz clic en "Generador de esquemas". Esto es bastante salvaje: puedes utilizar un servicio llamado "Stoplight" para diseñar tu API. Eso te dará un documento de especificación OpenAPI... y luego puedes utilizar el Generador de Esquemas para generar tus clases PHP a partir de eso. No vamos a utilizarlo, pero es una idea genial.

También hay un generador de admin integrado en React -jugaremos con él más adelante- e incluso formas de ayudar a generar JavaScript que hable con tu API. Por ejemplo, puedes generar un frontend Next.js haciendo que lea de tu especificación OpenAPI.

La cuestión es que la interfaz Swagger es impresionante. Pero aún más impresionante es el documento de especificaciones OpenAPI que hay detrás... y que puede utilizarse para otras cosas.

Modelos / Esquemas en OpenAPI

Además de las rutas en Swagger, también tiene algo llamado "Esquemas". Éstos son tus modelos... y hay dos: uno para JSON-LD y otro normal. Hablaremos de JSON-LD en un minuto, pero son básicamente lo mismo.

Si abres uno, vaya, esto es inteligente. Sabe que nuestro id es un entero,name es una cadena, coolFactor es un entero y isPublished es un booleano. Toda esta información procede, una vez más, de este documento de especificaciones. Si buscamos isPublished aquí... ¡sí! Ahí está el modelo que describe isPublished comotype boolean . Lo mejor es que API Platform genera esto... ¡sólo con mirar nuestro código!

Por ejemplo, ve que coolFactor tiene un tipo entero:

... lines 1 - 11
class DragonTreasure
{
... lines 14 - 28
private ?int $coolFactor = null;
... lines 30 - 112
}

así que lo anuncia como un entero en OpenAPI. Pero la cosa se pone aún mejor. Fíjate en id. Se establece como readOnly. ¿Cómo lo sabe? Bueno, id es una propiedad privada y no existe el método setId():

... lines 1 - 11
class DragonTreasure
{
... lines 14 - 16
private ?int $id = null;
... lines 18 - 36
public function getId(): ?int
{
return $this->id;
}
... lines 41 - 112
}

Por tanto, deduce correctamente que id debe ser readOnly.

También podemos ayudar a API Platform. Encuentra la propiedad $value... ahí está... y añade un poco de documentación encima para que la gente sepa que This is the estimated value of this treasure, in gold coins.

... lines 1 - 11
class DragonTreasure
{
... lines 14 - 24
/**
* The estimated value of this treasure, in gold coins.
*/
#[ORM\Column]
private ?int $value = null;
... lines 30 - 115
}

Dirígete, actualiza... y comprueba el modelo aquí abajo. En value... ¡aparece! La cuestión es: si haces un buen trabajo escribiendo tu código PHP y documentándolo, vas a obtener una rica documentación de la API gracias a OpenAPI, con cero trabajo extra.

A continuación: Hablemos de esos extraños campos @, como @id, @type, y @context. Provienen de algo llamado JSON-LD: una potente adición a JSON que API Platform aprovecha.

Leave a comment!

2
Login or Register to join the conversation
davidmintz Avatar
davidmintz Avatar davidmintz | posted hace 6 meses

I would like to be able to interact with the database using the shell but I'm having trouble figuring out the magic words to say to docker-compose. Any hints? thanks.

Reply

Hey David,

I suppose you can connect to the container with:

$ sudo docker exec –it mysql-container /bin/bash

Just use the correct container name instead "mysql-container" in my example.

Another workaround would be to interact with the DB via Symfony CLI - you can leverage the next command:

symfony console doctrine:query:sql "SELECT * FROM table"

Or, you can expose MySQL container ports to your host machine and connect directly to the MySQL via the new (exposed) port - just use your favorite MySQL GUI or just do it via mysql CLI command, you just need to pass correct credentials to connect to the Docker MySQL.

I hope at least one option will work for you ;)

Cheers!

Reply
Cat in space

"Houston: no signs of life"
Start the conversation!

What PHP libraries does this tutorial use?

// composer.json
{
    "require": {
        "php": ">=8.1",
        "ext-ctype": "*",
        "ext-iconv": "*",
        "api-platform/core": "^3.0", // v3.0.8
        "doctrine/annotations": "^1.0", // 1.14.2
        "doctrine/doctrine-bundle": "^2.8", // 2.8.0
        "doctrine/doctrine-migrations-bundle": "^3.2", // 3.2.2
        "doctrine/orm": "^2.14", // 2.14.0
        "nelmio/cors-bundle": "^2.2", // 2.2.0
        "nesbot/carbon": "^2.64", // 2.64.1
        "phpdocumentor/reflection-docblock": "^5.3", // 5.3.0
        "phpstan/phpdoc-parser": "^1.15", // 1.15.3
        "symfony/asset": "6.2.*", // v6.2.0
        "symfony/console": "6.2.*", // v6.2.3
        "symfony/dotenv": "6.2.*", // v6.2.0
        "symfony/expression-language": "6.2.*", // v6.2.2
        "symfony/flex": "^2", // v2.2.4
        "symfony/framework-bundle": "6.2.*", // v6.2.3
        "symfony/property-access": "6.2.*", // v6.2.3
        "symfony/property-info": "6.2.*", // v6.2.3
        "symfony/runtime": "6.2.*", // v6.2.0
        "symfony/security-bundle": "6.2.*", // v6.2.3
        "symfony/serializer": "6.2.*", // v6.2.3
        "symfony/twig-bundle": "6.2.*", // v6.2.3
        "symfony/ux-react": "^2.6", // v2.6.1
        "symfony/validator": "6.2.*", // v6.2.3
        "symfony/webpack-encore-bundle": "^1.16", // v1.16.0
        "symfony/yaml": "6.2.*" // v6.2.2
    },
    "require-dev": {
        "doctrine/doctrine-fixtures-bundle": "^3.4", // 3.4.2
        "symfony/debug-bundle": "6.2.*", // v6.2.1
        "symfony/maker-bundle": "^1.48", // v1.48.0
        "symfony/monolog-bundle": "^3.0", // v3.8.0
        "symfony/stopwatch": "6.2.*", // v6.2.0
        "symfony/web-profiler-bundle": "6.2.*", // v6.2.4
        "zenstruck/foundry": "^1.26" // v1.26.0
    }
}
userVoice