Chapters
-
Course Code
Subscribe to download the code!
Subscribe to download the code!
-
This Video
Subscribe to download the video!
Subscribe to download the video!
-
Subtitles
Subscribe to download the subtitles!
Subscribe to download the subtitles!
-
Course Script
Subscribe to download the script!
Subscribe to download the script!
Scroll down to the script below, click on any sentence (including terminal blocks) to jump to that spot in the video!
Estamos a punto de construir una API para la importantísima tarea de permitir que los dragones muestren su tesoro. Ahora mismo, nuestro proyecto no tiene ni una sola entidad de base de datos... pero vamos a necesitar una para almacenar todo ese tesoro.
Generar nuestra primera entidad
Busca tu terminal y ejecuta primero
composer require maker --dev
para instalar Maker Bundle. Luego ejecuta:
php bin/console make:entity
¡Perfecto! Llamemos a nuestra entidad DragonTreasure
. Entonces nos hace una pregunta que quizá no hayas visto antes: Mark this class as an API platform resource
? Pregunta porque la API Platform está instalada. Di no
porque vamos a hacer este paso manualmente dentro de un momento.
Bien, empecemos a añadir propiedades. Empieza con name
como cadena, con una Longitud por defecto de 255, y haz que no sea anulable. Después, añade description
con un tipo text
, y haz que no sea anulable. También necesitamos un value
, como... cuánto vale el tesoro. Eso será un integer
no anulable. Y simplemente debemos tener un coolFactor
: los dragones necesitan especificar lo impresionante que es este tesoro. Eso será un número del 1 al 10, así que que sea un integer
no anulable. Luego, createdAt
datetime_immutable
que no sea anulable... y por último, añade una propiedad isPublished
, que será de tipo boolean
, también no anulable. Pulsa "intro" para terminar.
¡Uf! Hasta ahora no hay nada muy especial. Esto ha creado dos clases: DragonTreasureRepository
(de la que no nos vamos a preocupar), y la propia entidad DragonTreasure
con $id
, $name
, $description
, $value
, etc junto con los métodos getter y setter. Maravillosamente aburrido. Sin embargo, hay un pequeño error en esta versión de MakerBundle. Ha generado un método isIsPublished()
. Cambiémoslo por getIsPublished()
.
Configurar la base de datos
Muy bien, ya tenemos nuestra entidad. Ahora necesitamos una migración para su tabla... ¡pero eso puede ser un poco difícil ya que aún no tenemos configurada nuestra base de datos! Voy a utilizar Docker para esto. La receta de DoctrineBundle nos dio un bonito archivo docker-compose.yml
que arranca Postgres, así que... ¡vamos a usarlo! Ve a tu terminal y ejecuta:
docker-compose up -d
Si no quieres utilizar Docker, siéntete libre de arrancar tu propio motor de base de datos y luego, en .env
o .env.local
, configura DATABASE_URL. Como estoy utilizando Docker además del binario symfony
, no necesito configurar nada. El servidor web Symfony verá automáticamente la base de datos de Docker y configurará la variable de entorno DATABASE_URL
por mí.
Bien, para hacer la migración, ejecuta:
symfony console make:migration
Este symfony console
es igual que ./bin/console
excepto que inyecta la variable de entorno DATABASE_URL
para que el comando pueda hablar con la base de datos Docker. ¡Perfecto! Gira y comprueba el nuevo archivo de migración... sólo para asegurarte de que no contiene ninguna sorpresa extraña. ¡Tiene buena pinta! Así que vuelve a girar y ejecuta esto con:
symfony console doctrine:migrations:migrate
¡Listo!
Exponiendo nuestro primer recurso API
Ahora tenemos una entidad y una tabla de base de datos. Pero si vas y actualizas la documentación... todavía no hay nada. Lo que tenemos que hacer es decirle a la API Platform que exponga nuestra entidad DragonTreasure
como un recurso API. Para ello, ve encima de la clase y añade un nuevo atributo llamado ApiResource
. Pulsa "tab" para añadir la declaración use
.
¡Listo! En cuanto hagamos eso... y actualicemos... ¡guau! ¡La documentación está viva! Ahora muestra que tenemos seis rutas diferentes: Uno para recuperar todos los recursos DragonTreasure
, uno para recuperar un DragonTreasure
individual, uno para crear un DragonTreasure
, dos que editan un DragonTreasure
y uno para eliminarlo. Y esto es algo más que documentación. Estas rutas funcionan.
Ve y haz clic en "Probar", y luego en "Ejecutar". En realidad no devuelve nada porque nuestra base de datos está vacía, pero nos da un código de estado 200 con algo de JSON vacío. En breve hablaremos de todas las demás claves extravagantes de la respuesta.
Pero quiero mencionar una cosa. Como acabamos de ver, la forma más sencilla de crear un conjunto de rutas API es añadir este atributo ApiResource
sobre tu clase de entidad. Pero en realidad puedes añadir este atributo sobre cualquier clase: no sólo entidades. Es algo de lo que hablaremos en un futuro tutorial: puede ser una buena forma de separar el aspecto de tu API del de tu entidad, especialmente en las API más grandes. Pero, de nuevo, eso es para más adelante. Ahora mismo, utilizar ApiResource
sobre nuestra entidad va a funcionar de maravilla.
Descubramos un poco más esta genial documentación interactiva. ¿De dónde ha salido esto? ¿Cómo es que nuestra aplicación tiene por arte de magia un montón de rutas nuevas? ¿Y de verdad les gustan los tacos a los dragones? ¡Averigüémoslo a continuación!
25 Comments
Hey Szymon!
I know this error! If you're using the code from the course, then we're using Postgres. The error means that you need to install the pgsql
php extension - e.g. like described here (the exact setup instructions will depend on your operating system): https://stackoverflow.com/questions/10085039/postgresql-pdoexception-with-message-could-not-find-driver#answer-48858539
Or, if you'd rather use Mysql, you can skip the migrations and run doctrine:schema:update --force
instead (after configuring your app to talk to your mysql database).
Let me know if this helps!
Cheers!
yeah, that's right. I am using Windows, and I just removed semicolon in xampp/php/php.ini
extension=pdo_pgsql
...
extension=pgsql
and it's running good.
But it's kind weird for me, because I am not using XAMPP, I installed php directly in my computer, but most important is that working anyway :)
additional query: what is the difference between using MySQL and PostgreSQL in this tutorial? I remember in Symfony5 tutorial we used MySQL.
Is chance to see this database tables in friendly environemnt like phpMyAdmin or something similar? does it require a more difficult setup?
Hey Szymon,
In this tutorial, the only difference you'll find if you use MySQL instead of PostgreSQL is the migration files. The queries generated by Doctrine will be specific to MySQL, but besides that, nothing else will be different.
Is chance to see this database tables in friendly environemnt like phpMyAdmin or something similar? does it require a more difficult setup?
I found this tool for Postgres. However, I don't know how hard it might be to set it up. https://github.com/phppgadmin/phppgadmin
Cheers!
Hello,
I've created a first entity, a migration, migrated the migration. After adding #[ApiResource]
to the new entity, I'm getting
unable to fetch the response from the backend: unexpected EOF
What did I do wrong?
I changed the "api-platform/core" version in the composer from 3.2.2 to 3.2.0, now the error is gone, https://127.0.0.1:8000/api is loading. But when I try to execute a get request, I still get the response:
Symfony Local Web Server: unable to fetch the response from the backend: unexpected EOF
Hey @Elena
That's unexpected, I believe there's something odd with your vendors, try re-installing them rm -r vendor/
and run composer install
again. Oh, and restart the web server just in case
Cheers!
Hello,
When I run symfony console make:migration then:
An exception occurred in the driver: SQLSTATE[08006] [7] SCRAM authentication requires libpq version 10 or above
And as I'm not a docker nor postgreSQL expert, I have a hard time.
I just (normally) followed your tutorial.
How to fix it ?
Thanks in advance.
Eric
Hey @Eric-J!
Ah! That's not a friendly error :). From what I can tell... this looks like something weird and/or annoying :/. There are various solutions here - https://stackoverflow.com/questions/62807717/how-can-i-solve-postgresql-scram-authentication-problem - and none of them look great.
My advice: change the DATABASE_URL
to use mysql or sqlite - something you're more familiar with. Then turn OFF the docker container and follow the tutorial. There's no need to get stopped by a silly detail like this. The tutorial will work 100% the same with pgsql, mysql or sqlite.
Cheers!
Hello,
Thanks for your help.
It seems that I had 2 Symfony local server running from 2 project at the same time and on the same database.
Anyhow, I got the error handled and could proceed on.
Kind regards
Good debugging Eric! The Docker container names are based on your directory name (not the full directory path, just the final name). So if you have 2 Symfony projects in directories named my_app
, then they'll share the same containers... which isn't ideal :p. I hit this issue sometimes as well.
Cheers!
How can I get apiPlatform working on an entity in a different namespace?
I updated the autoloaded in composer.json and doctrine.yaml
mappings:
App:
is_bundle: false
dir: '%kernel.project_dir%/src/Entity'
prefix: 'App\Entity'
alias: App
VisFour\SholGeneratr\Entity:
is_bundle: false
dir: '%kernel.project_dir%/lib/SholGeneratr/Entity'
prefix: 'VisFour\SholGeneratr\Entity'
alias: VisFourSholGeneratr
but the resource still doesn't show up in url: /api
it was exhausting , but I found it:
api_platform.yml:
mapping:
paths:
- '%kernel.project_dir%/src/Entity'
- '%kernel.project_dir%/lib/SholGeneratr/Entity'
Hey Cameron,
I'm happy to hear you were able to find the solution yourself, well done! And thanks for sharing it with others
Cheers!
Are there anyway to create custom API such as api/hello-world without entity
Hey @Ken
Yes, APIPlatform does not force you to create entities for your resources, you can do the exact same thing with data model classes
Here are the docs: https://api-platform.com/docs/core/dto/#using-data-transfer-objects-dtos
Cheers!
Hi !
Thanks for the tutorial :)
I have some trouble about the symfony console make:migration
part.
Without modifing docker-compose.yml
file, when I try to apply the migrations (after boot the container with docker compose up -d
) i get the next error :
SQLSTATE[08006] [7] connection to server at "127.0.0.1", port 5432 failed: Connection refused
Is the server running on that host and accepting TCP/IP connections?
Do you have a solution ?
For information, I'm working on Windows with WSL.
Thank you !
Hey @Yorane
I'm afraid I cannot help you with your Docker setup because I don't use it under WSL, but I have a question, does it only happens when you try to load the migrations?
Hi MolloKhan,
It's OK, I resolved my problem :)
Not only, every time my server try to connect to the container database.
To resolve the problem, we have to change the IP address in the .env
file with the container IP.
Oh cool, well done @Yorane
Tip: when you use Docker, you need to run any command through the Symfony CLI, so it can inject the correct env var valuessymfony console app:foo
Cheers!
Thank's a lot dude!!!
My line is now like that and it works :D
DATABASE_URL="postgresql://app:!ChangeMe!@0.0.0.0:52327/app?serverVersion=15&charset=utf8"
Hey i always get this
500
Undocumented
Error: Internal Server Error.
This is my docker-compose.yaml regarding the mysql container
database:
container_name: database
image: mysql
command: --default-authentication-plugin=mysql_native_password
environment:
MYSQL_ROOT_PASSWORD: dsv
MYSQL_DATABASE: dsv_db
MYSQL_USER: dsv
MYSQL_PASSWORD: dsv
ports:
- '4306:3306'
#to avoid lower versions/ or existing install / conflicts
# this volume will create new mysql8 folder
volumes:
- ./mysql:/var/lib/mysql``
and my .env
DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=8&charset=utf8mb4"
and response body:
{
"@context": "/api/contexts/Error",
"@type": "hydra:Error",
"hydra:title": "An error occurred",
"hydra:description": "An exception occurred in the driver: could not find driver",
"trace": [
... more log below
I am sure i have the drivers i need but..any suggestion would be welcomed. Thank you!
Hey @Kev!
Well that's annoying! You're using Mysql, so the "could not find driver" is referring to the PHP pdo_mysql driver. Exactly HOW you install this depends on your system - e.g. with Ubuntu, it's often something like apt install php-mysql
. Also, remember to restart your web server (e.g. the symfony binary) after installing the driver. And FINALLY. if you have multiple php binaries installed and you're not sure which one the symfony
binary is using, you can always run symfony local:php:list
to find out.
Cheers!
Hey @weaverryan ,
Thanks for your answer, the general idea is that i already have the php-mysql driver installed. I have it as a docker-compose procedure script for a container, AND i have it on my local ubuntu machine installed.
The default .env build with the default postrgres variable is the same result.
Weirdish issue really!
Cheers!
That IS weird. That usually means that some different, unexpected PHP binary is being used (that doesn't have the driver installed).... but these are a pain to figure out!
"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
}
}
Hello,
When I run
symfony console make:migration
then:How to fix it? I am working with PHP8.2 and Symfony6...