Créer une app Symfony faisant du CRUD avec un dashboard admin et exposant une api RES. On va donc :
- Créer un projet Symfony 4
- Ajouter Sonata Admin bundle
- Créer 2 entités : Company + User (1 relation many to 1 vers company)
- Faire un CRUD User
- Faire un CRUD Company
- Exposer API User
- Exposer API Company avec pagination
- Quelques lectures sur l'env php, composer, symphony, doctrine ...
- Recherche d'une stack docker de dev pour éviter de poluer sa machine et être proche d'un déploiement réel
- Tester l'utilisation un simple conteneur docker PHP7 pour la creation du projet via composer
J'utilise docker pour ne pas perdre de temps dans l'installation d'un environnement php/composer/symfony
Créons une image php7 + composer qui nous servira à ceer le projet et manipuler les dépendantes.
FROM php:7.2-cli
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
RUN php composer-setup.php
WORKDIR /app
- Build de l'image
php_composer
en local
docker build -t php_composer .
- Création du projet en utilisant l'image
php_composer
docker run -it --rm -v $(pwd):/app php_composer composer create-project symfony/skeleton symfony-app
- Installation de dépendances : On lance un conteneur éphémère
php_composer
en ayant monté un volume pontant sur notre répertoire projet.
docker run -it --rm -v $(pwd)/symfony-app:/app php_composer sh
composer require sonata-project/admin-bundle sonata-project/doctrine-orm-admin-bundle annotations migrations symfony/translation
composer require symfony/maker-bundle --dev
- Configuration des paramètres d'accès à la base de données:
Il suffit de remplacer la ligne suivante (section DOCTRINE) dans le fichier .env
à la racine du répertoire du projet symfony :
DATABASE_URL="mysql://symfony:symfony@db:3306/symfony"
Avec dans cette chaine de connexion :
symfony / symfony
: user / password de la base de données mysqlsymfony
: nom de la base de donnéedb
: le database host
Pour développer et exécuter le code de notre projet on va utiliser encore un fois docker mais avec une stack un peu plus élaborée.
Après une rapide recherche (mots clé docker+symfony
), la stack docker-compose docker-symfony de @eko sur Github semble répondre au besoin (DANGER: Ne jamais utiliser des images docker de sources non maîtrisées en PROD).
Elle se compose de 4 services (conteneurs quiseront lancés cf docker.compose.yaml
) :
- db : A partir de l'image officielle mysql pour la base de donnée. ATTENTION :
db
est aussi le nom hôte que nous avons rensigné dans la configuration de notre projet symfony. - php : A partir de l'image custom définie dans le répertoire
./php-fpm
. C'est l'environnement d'exécution de notre projet, le code est monté dans ce contener via un volume. - nginx : A partir de l'image custom définie dans le répertoire
./nginx
. C'est le web server qui va exposer notre application. - elk : Exécute une stack ELK créée à partir de l'image willdurand/elk pour collecter et visualiser les logs.
- Récupération de la stack docker : elle contient des définitions pour les images bdd mysql, php, nginx, elk.
On clone cette stack et on y place notre répertoire projet symfony-app
que l'on renomme en symfony
. Selon la configuration de docker sur le poste il est possible que ledossier projet symfony-app
soit la propriété du root user. Il sera nécessaire de changer les doits du dossier projet symfony-app
avec un sudo chown <username> symfony-app
git clone https://github.com/eko/docker-symfony.git symfony-docker-dev
mv ./symfony-app ./symfony-docker-dev/symfony
Voici l'abrorescence de notre stack docker-symfony
à ce stade:
├── docker-compose.travis.yml
├── docker-compose.yml
├── elk/
├── LICENSE.md
├── logs/
├── nginx/
├── php-fpm/
├── README.md
└── symfony/
C'est le moment d'ouvrir un IDE php avec comme cible le dossier symfony-docker-dev/symfony
.
- Mise à jour de la configution locale :
symfony.localhost
sera ajouté comme url de notre projet symfony conformémet aux instructions de docker-symfony.
echo "127.0.0.1 symfony.localhost" >> /etc/hosts
sudo service networking restart
- Démarrer la stack docker
Depuis la racine du dossier symfony-docker-dev
on éxécute :
docker-compose up
Dans la suite ce ce billet, les commandes commençant pas php ...
seront exécutés dans le conteneur php (pour rappel notre environnement de dev est sous docker). Ainsi on peut par exemple ouvrir un terminal sur le conteneur php via la commande docker exec -it <nom_conteneur_php> /bin/sh
et ensuite exécuter les commande que l'on souhaite.
Dans le dossier src
du projet on a le répertoire Entity
qui sert à stocker les entités pour l'ORM.
On va utiliser le générateur Symfony MakerBundle installé plus haut via composer.
- Exécuter pour chaque entité la commande
php bin/console make:entity
php bin/console make:crud
La commande est interractive et permet de génerer une entité pour l'ORM Doctrine
- Exemple entité créée :
src/Entity/Company.php
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @ORM\Entity
* @ORM\Table(name="company")
*/
class Company
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string")
*/
private $name;
//... suite de la classe
}
- Mise à jour de la base
Une fois les modèles créé on udate la base (Atention en DEV uniquement utiliser l'incremental update sinon)
php bin/console doctrine:schema:update --force
Pour ce la on va utiliser la commande
php bin/console make:sonata:admin
Optionels : Sauf nécessité de surcharge.
Pour créer notre API on va utiliser JMSSerializerBundle et FOSRestBundle.
On commence par rajouter ces dépendances.
composer require symfony/serializer
composer require friendsofsymfony/rest-bundle
Configurations
- FOSRestBundle :
packages/fos_rest.yaml
fos_rest:
view:
view_response_listener: true
format_listener:
rules:
- { path: ^/api, prefer_extension: true, fallback_format: json, priorities: [ json, html ] }
- { path: '^/', priorities: [ 'text/html', '*/*'], fallback_format: html, prefer_extension: true }
- Annotations :
config/routes/anotations.yaml
controllers:
resource: ../../src/Controller/
type: annotation
rest_controller:
resource: ../../src/ControllerRest/
type: annotation
prefix: /api
- Avec un client http ex. Postman ou cURL
curl -X GET \
http://symfony.localhost/api/users \
-H 'cache-control: no-cache' \
-H 'content-type: application/json' \
Réponse
[
{
"id": 1,
"firstname": "Mike",
"lastname": "PAMBO",
"company": {
"id": 2,
"name": "Symfony",
"city": "Paris",
}
}
//...
]
- https://github.com/eko/docker-symfony
- https://sonata-project.org
- https://www.patricelaurent.net/symfony-creer-une-administration-avec-sonata
- https://symfony.com/doc/current/setup/file_permissions.html
- https://www.thinktocode.com/2018/03/26/symfony-4-rest-api-part-1-fosrestbundle
- https://openclassrooms.com/fr/courses/4087036-construisez-une-api-rest-avec-symfony
- https://github.com/JeffreyVerreckt/Symfony4-REST-API