Cómo crear una API RESTful en la plataforma Symfony 5 + API para un proyecto MODX


De esta lección aprenderá cómo crear rápidamente una API RESTful para cualquier sitio en cualquier CMS, MODX es solo un ejemplo.


Para crear la API, usaré:



El resultado está aquí:
https://github.com/andchir/modx2-api


Hice todo lo descrito en Linux, pero creo que en Windows la diferencia en los comandos no será grande. Preinstalé Composer y la utilidad Symfony .


Crear un proyecto y clases de usuario


Creo un proyecto:


composer create-project symfony/skeleton modx2-api 

Instale los paquetes necesarios para crear la API:


 cd modx2-api composer req api composer req migrations composer req form composer req maker --dev 

Comienzo el servidor local.
Si la utilidad Symfony está instalada:


 symfony server:start 

más o menos:


 php -S 127.0.0.1:8000 -t public 

Abro la dirección en el navegador para verificar que todo funciona:
http://127.0.0.1:8000/


Abro el archivo .env y edito la cadena de conexión a la base de datos del proyecto en MODX :


 DATABASE_URL=mysql://db_user:db_password@127.0.0.1:3306/db_name 

Ahora debe crear un usuario y configurar el sistema de autorización mediante inicio de sesión y contraseña.


Instalar paquetes adicionales:


 composer req jwt-auth composer req orm-fixtures --dev composer req profiler --dev 

Las nuevas opciones del paquete .jvt-autenticación-paquete han aparecido en el archivo .env .


Creo la entidad y las clases de repositorio (Doctrine ORM) del usuario:


 php bin/console make:user 

Aparecieron dos archivos:


 src/Entity/User.php src/Repository/UserRepository.php 

Creo la tabla "usuario" en la base de datos:


 bin/console doctrine:schema:create 

Configuro la autorización del usuario de acuerdo con las instrucciones:



Código de controlador App \ Controller \ SecurityController
 <?php namespace App\Controller; use App\Entity\User; use App\Form\Type\LoginType; use App\Form\Type\UpdateProfileType; use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface; use Symfony\Component\Security\Http\Authentication\AuthenticationUtils; use Symfony\Component\Validator\Validator\ValidatorInterface; class SecurityController extends AbstractController { /** * @Route("/login", name="app_login") * @param AuthenticationUtils $authenticationUtils * @return Response */ public function loginAction(AuthenticationUtils $authenticationUtils): Response { if ($this->getUser()) { return $this->redirectToRoute('api_entrypoint'); } $form = $this->createForm(LoginType::class); $error = $authenticationUtils->getLastAuthenticationError(); $lastUsername = $authenticationUtils->getLastUsername(); return $this->render('security/login.html.twig', [ 'form' => $form->createView(), 'last_username' => $lastUsername, 'error' => $error ]); } } 

Genero una clase para crear usuarios:


 php bin/console make:fixtures 

Más detalles aquí: https://symfony.com/doc/current/security.html#a-create-your-user-class


Aplicación de código de clase \ DataFixtures \ UserFixtures
 <?php namespace App\DataFixtures; use App\Entity\User; use Doctrine\Bundle\FixturesBundle\Fixture; use Doctrine\Common\Persistence\ObjectManager; use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface; class UserFixtures extends Fixture { private $passwordEncoder; public function __construct(UserPasswordEncoderInterface $passwordEncoder) { $this->passwordEncoder = $passwordEncoder; } public function load(ObjectManager $manager) { $user = new User(); $user ->setEmail('admin@admin.com') ->setRoles(['ROLE_USER', 'ROLE_ADMIN']); $user->setPassword($this->passwordEncoder->encodePassword( $user, 'admin'//  )); $manager->persist($user); $manager->flush(); } } 

Creo un administrador con la dirección de correo electrónico "admin@admin.com" y la contraseña "admin" :


 php bin/console doctrine:fixtures:load --append --group=UserFixtures 

Más tarde, estos datos se pueden cambiar.


Genero las claves en la carpeta config / jwt / :


 jwt_passhrase=$(grep ''^JWT_PASSPHRASE='' .env | cut -f 2 -d ''='') echo "$jwt_passhrase" | openssl genpkey -out config/jwt/private.pem -pass stdin -aes256 -algorithm rsa -pkeyopt rsa_keygen_bits:4096 echo "$jwt_passhrase" | openssl pkey -in config/jwt/private.pem -passin stdin -out config/jwt/public.pem -pubout setfacl -R -mu:www-data:rX -mu:"$(whoami)":rwX config/jwt setfacl -dR -mu:www-data:rX -mu:"$(whoami)":rwX config/jwt 

Comprobación de la creación del token:


 curl -X POST -H "Content-Type: application/json" http://localhost:8000/authentication_token -d '{"email":"admin@admin.com","password":"admin"}' 

Creo una migración:


 php bin/console make:migration 

Ahora la parte divertida.


API y generación de documentación


Genero clases de entidad para todas las tablas de la base de datos:


 php bin/console doctrine:mapping:import "App\Entity" annotation --path=src/Entity 


Genero getters y setters para clases:


 php bin/console make:entity --regenerate App 

Abro el código de una clase, por ejemplo src / Entity / ModxSiteContent.php . Agregue la anotación @ApiResource :


La API para ModxSiteContent está lista.


Abro la página http: // localhost: 8000 / api



Tomo el token, hago clic en el botón "Autorizar", inserto la línea con el token:


 Bearer MY_TOKEN 


Hago clic en el botón "Probar" y luego en el botón "Ejecutar" . Me sale este resultado:


Relaciones de tabla


No describiré cómo se crean los filtros para no duplicar la documentación , pero daré un ejemplo de cómo puede crear relaciones para tablas, porque Es un poco más complicado.


En el caso de MODX, los datos del usuario se almacenan en una tabla separada "atributos_usuario" . Por ejemplo, necesito agregar su correo electrónico, nombre, número de teléfono, etc. a una muestra de usuarios por solicitud GET. Abro el código de clase App \ Entity \ ModxUsers , agrego la propiedad privada $attributes y describo la conexión con la clase App \ Entity \ ModxUserAttributes en la anotación "@ORM \ OneToOne":


 /** * @var ModxUserAttributes * * @ORM\OneToOne(targetEntity="ModxUserAttributes", mappedBy="user") * @Groups({"read", "attributes"}) */ private $attributes; 

Nuevamente agrego los captadores y setters que faltan:


 php bin/console make:entity --regenerate App\\Entity\\ModxUsers 

Tenga en cuenta que agregué el grupo "atributos" a la anotación @ApiResource


Imagen


Abro el código de la clase App \ Entity \ ModxUserAttributes , agrego la anotación @ApiResource y la conexión con la clase App\Entity\ModxUsers :


 /** * @var ModxUsers * * @ORM\OneToOne(targetEntity="ModxUsers", mappedBy="attributes") * @ORM\JoinColumn(name="internalKey", referencedColumnName="id") */ private $user; 

Para todas las propiedades que deben agregarse a la selección, inserto la anotación @Groups({"attributes"}) .


Imagen


Resultado:


Como resultado, para la autorización en su aplicación, primero debe enviar un inicio de sesión (correo electrónico) y una contraseña a la URL "/ autenticación_token" , obtener un token y luego enviar este token en cada solicitud en el encabezado "Autorización" :


Si el proyecto https://github.com/andchir/modx2-api es interesante para los usuarios, se desarrollará. También estoy esperando relaciones públicas de todos los que quieran ayudar.

Source: https://habr.com/ru/post/479168/


All Articles