Objetivo
O doctrine é um Orm dos mais usados no ecossistema do php, nele nós conseguimos armazenar e tratar os dados das nossas aplicações de uma forma segura e além disso ele traz várias facilidades que nos ajudam no trabalho. A forma de trabalhar nele é muito semelhante ao que é feito no Hibernate do java e no TypeOrm do nodejs.Para isso nós vamos criar uma api com uma vitrine de vídeo games com uma tabela com os nomes deles uma data de criação do registro e um campo para guardar a data da última alteração de cada registro da tabela.
Instalando a linha de comandos do symfony
Nas versões mais recentes o symfony trouxe um componente global para a linha de comando que traz várias facilidades entre elas comandos mais simples para baixar dependências e interagir com os projetos economizando a nossa tendinite.
Após seguir os passos mostrados acima basta inserir o symfony no path do sistema se for um linux basta rodar o comando abaixo.
Para zshsudo echo export PATH="$HOME/.symfony/bin:$PATH" >> .zshrcou se você usa o bashsudo echo export PATH="$HOME/.symfony/bin:$PATH" >> .bashrc
Siga a documentação para instalar corretamente, tem versões para todos os sistemas.
Como nós vemos na imagem facilita bastante, então vamos iniciar o projeto com o comando:
symfony new nomeProjeto
Com o projeto criado vamos instalar as dependências de annotations, o orm Doctrine e a linha de comando do maker-budler para auxiliar na criação de componentes.
composer require symfony/orm-pack
composer require --dev symfony/maker-bundle
composer require annotations
composer require symfony/maker-bundle --dev
Agora vamos criar os controllers de cada entidade da nossa tabela usando o comando abaixo onde basta digitar o nome do controller (ex: VideoGameController), mais se você preferir pode fazer na mão.
php bin/console make:controller
Com os controllers criados vamos conectar a nossa api com o banco de dados por padrão o doctrine vem com o drive do MySql e é o que vamos usar, mais você pode usar outro (ex: PostgreSql, Oracle, Sql Server).
Na pasta raiz do projeto o arquivo .env foi alterado para conter a configuração do banco com a variável DATABASE_URL, nela vamos colocar o nosso usario e senha para poder acessar o banco e o nome da base de dados que vamos usar. Caso você não tenha um banco de dados na sua máquina eu recomendo fortemente que você instale pelo docker porque é mais simples, funciona em todos os sistemas e o processo de instalação é o mesmo em todos os sistemas depois de ter o docker instalado.
O seu arquivo env deve ficar parecido com esse abaixo e caso o nome da base de dados que você digitou lá não exista ainda (no exemplo nossa base chama vitrineGames) daqui a pouco nós vamos criá la.
Para criar essa base de dados rode esse comando abaixo no seu terminal.
php bin/console doctrine:database:create
Vamos criar agora a nossa entidade do videoGame que vai conter os campos name, created_at e updated_at usando a linha de comando do symfony.
php bin/console make:entity
Veja que foi criada a nossa entidade e um repositório para ela. Um ponto interessante para notarmos é que o mapeamento feito pelo doctrine é realizado através de anotações é muito parecido com o que é feito no nodeJs com o TypeOrm e com o Hibernate do Java.
Para podermos mandar essas entidades nas respostas json dos nossos controller precisamos implementar a interface JsonSerializable, que vai nos obrigar a implementar o método jsonSerializer onde vamos retornar um array com os dados do nosso objeto usando os métodos getters dele para que na response da chamada no postman o symfony mande a nossa entidade como um objeto json.
Com base nessa entidade gerada vamos criar uma migration, o symfony usa a classe que nós montamos para montar a query que vai criar a tabela na nossa base de dados. Então o primeiro comando vai criar a migration e o segundo vai rodar a migration criando a tabela.
php bin/console make:migration
php bin/console doctrine:migrations:migrate
Dentro do nosso controller de videoGame criar a rota da nossa api que vai inserir um novo video game. O controller vem com um método index e com a anotação da rota em cima do método nós vamos criar uma anotação de rota acima da classe também com a rota videoGame, com isso nos métodos a gente não precisa especificar a rota completa nesse exemplo o método create ficaria apenas com o nome create na anotação e quando nós formos acessá la ela ficará assim videoGame/create.
Obs: para rodar a aplicação em modo dev basta rodar o comando a baixo usando a linha de comando do framework.
symfony serve
Para testar as rotas da nossa api vamos usar o Postman que é gratuito e inserindo a url dessa nossa primeira rota você deve ter um resultado como esse abaixo.
Para testar as rotas da nossa api vamos usar o Postman que é gratuito e inserindo a url dessa nossa primeira rota você deve ter um resultado como esse abaixo.
Na anotação que fica acima do método create podemos especificar qual tipo de requisição aquele endpoint vai receber se será do tipo POST, GET, PUT entre outras.
Mais como é um método de criação vamos deixar esse endpoint respondendo a chamadas do tipo POST.
Usando essa mesma chamada do postman vamos mandar o parâmetro name com o nome do nosso primeiro video game.
Salvando os dados na tabela — Create
Em nosso método create vamos receber como parâmetro os dados da request que vão conter o nome do nosso vídeo game. No symfony esses dados chegam pela Request e quando nós os acessamos eles estão no formato de um array com chave e valor, onde a chave vai ser o nome do parâmetro que nós colocamos no postman.
Agora para salvar o nosso vídeo game vamos chamar a nossa entidade de videoGame vamos passar o nome do console e os timestamp da data de criação e atualização do registro. Em seguida vamos chamar o doctrine e mandar ele salvar os dados na nossa tabela.
Mandando novamente a requisição novamente já podemos ver os dados salvos no postman.
Buscar os registros — GetAll
Nesse novo método index que só vai aceitar chamadas do tipo Get nós vamos buscar os registros que salvamos na tabela, para isso vamos usar a nossa classe de repositório que foi criada junto com a entidade. Nele vamos passar o VideoGameRepository como argumento do método e chamar o método finAll que busca todos os registros desta tabela e retornar o resultado como um objeto json. Uma coisa interessante é que quando uma classe é passada como argumento o symfony usa a injeção de dependência para instanciar essa classe para nós.
Dentro do Postman nós vamos criar uma nova requisição do tipo Get para chamar o método index que vai nos retornar todos os registros da tabela em um array.
Atualizando os dados da base de dados — Update
Para atualizar os dados da tabela temos que buscar o registro que nós acabamos de inserir na tabela através do seu id que será passado pela url e como parâmetro do método será passado a entidade VideoGame onde o symfony vai fazer a mágica de buscar os dados dessa entidade no banco de dados.
Nós também vamos mandar no corpo da nossa requisição o campo name com a nossa alteração do nome do video game.
Vamos agora para o Postman criar uma requisição do tipo Put passando o parâmetro name com fizemos na criação do registro e passando também o id na rota para o symfony buscar e atualizar o registro.
Deletando um registro — Delete
Para deletar um registro da tabela é muito parecido com o que foi feito no método de update as diferenças são que nós não mandamos nenhum parâmetro no corpo da requisição e o método só aceitará requisições do tipo Delete.
Espero que esse conteúdo tenha te ajudado, caso eu tenha errado em algum ponto comente e me ajude a melhorar.
Link do repositório com os codigos desenvolvidos aqui: