Comment créer une API RESTful sur la plate-forme Symfony 5 + API pour un projet MODX


À partir de cette leçon, vous apprendrez à créer rapidement une API RESTful pour n'importe quel site sur n'importe quel CMS, MODX n'est qu'un exemple.


Pour créer l'API, j'utiliserai:



Le résultat est ici:
https://github.com/andchir/modx2-api


J'ai fait tout ce qui est décrit sous Linux, mais je pense que sous Windows, la différence de commandes ne sera pas grande. J'ai préinstallé Composer et l'utilitaire Symfony .


Création d'un projet et de classes d'utilisateurs


Je crée un projet:


composer create-project symfony/skeleton modx2-api 

Installez les packages nécessaires pour créer l'API:


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

Je démarre le serveur local.
Si l'utilitaire Symfony est installé:


 symfony server:start 

ou alors:


 php -S 127.0.0.1:8000 -t public 

J'ouvre l'adresse dans le navigateur pour vérifier que tout fonctionne:
http://127.0.0.1:8000/


J'ouvre le fichier .env et édite la chaîne de connexion à la base de données du projet sur MODX :


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

Vous devez maintenant créer un utilisateur et configurer le système d'autorisation par identifiant et mot de passe.


Installez des packages supplémentaires:


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

De nouvelles options de package .jvt-authentication-bundle sont apparues dans le fichier .env .


Je crée les classes d'entité et de référentiel (Doctrine ORM) de l'utilisateur:


 php bin/console make:user 

Deux fichiers sont apparus:


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

Je crée la table "utilisateur" dans la base de données:


 bin/console doctrine:schema:create 

Je configure l'autorisation utilisateur conformément aux instructions:



Controller Code 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 ]); } } 

Je génère une classe pour créer des utilisateurs:


 php bin/console make:fixtures 

Plus de détails ici: https://symfony.com/doc/current/security.html#a-create-your-user-class


Code de classe App \ 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(); } } 

Je crée un administrateur avec l'adresse e-mail "admin@admin.com" et le mot de passe "admin" :


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

Plus tard, ces données peuvent être modifiées.


Je génère les clés dans le dossier 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 

Vérification de la création du token:


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

Je crée une migration:


 php bin/console make:migration 

Maintenant, la partie amusante.


API et génération de documentation


Je génère des classes d'entités pour toutes les tables de base de données:


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


Je génère des getters et setters pour les cours:


 php bin/console make:entity --regenerate App 

J'ouvre le code d'une classe, par exemple src / Entity / ModxSiteContent.php . Ajoutez l'annotation @ApiResource :


L'API pour ModxSiteContent est prête.


J'ouvre la page http: // localhost: 8000 / api



Je prends le token, clique sur le bouton "Autoriser", insère la ligne avec le token:


 Bearer MY_TOKEN 


Je clique sur le bouton "Try it out" puis sur le bouton "Execute" . J'obtiens ce résultat:


Relations de table


Je ne décrirai pas comment les filtres sont créés afin de ne pas dupliquer la documentation , mais je donnerai un exemple de la façon dont vous pouvez créer des relations pour les tables, car c'est un peu plus délicat.


Dans le cas de MODX, les données utilisateur sont stockées dans une table séparée "user_attributes" . Par exemple, je dois ajouter leur e-mail, nom, numéro de téléphone, etc. à un échantillon d'utilisateurs par demande GET. J'ouvre le code de classe App \ Entity \ ModxUsers , j'ajoute la propriété privée $attributes et décris la connexion avec la classe App \ Entity \ ModxUserAttributes dans l'annotation "@ORM \ OneToOne":


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

Encore une fois, j'ajoute les getters et setters manquants:


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

Veuillez noter que j'ai ajouté le groupe "attributs" à l'annotation @ApiResource


Image


J'ouvre le code de la classe App \ Entity \ ModxUserAttributes , j'ajoute l'annotation @ApiResource et la connexion avec la classe App\Entity\ModxUsers :


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

À toutes les propriétés qui doivent être ajoutées à la sélection, @Groups({"attributes"}) l'annotation @Groups({"attributes"}) .


Image


Résultat:


Par conséquent, pour l'autorisation dans votre application, vous devez d'abord envoyer un identifiant (e-mail) et un mot de passe à l'URL "/ authentication_token" , obtenir un jeton puis envoyer ce jeton à chaque demande dans l'en-tête "Autorisation" :


Si le projet https://github.com/andchir/modx2-api est intéressant pour les utilisateurs, il se développera. J'attends également les relations publiques de tous ceux qui veulent aider.

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


All Articles