Eaí! Estava estudando mais sobre NoSQL com o MongoDB e decidi implementar o Mongo como banco de dados na API de um projeto que eu havia feito anteriormente com o Symfony.
Explicando rapidamente o projeto: é um compartilhador de arquivos. O usuário envia um arquivo e recebe um link de compartilhamento. Assim, qualquer pessoa com acesso a esse link pode visualizar o arquivo.
Nesse fluxo do projeto, o Mongo será utilizado para armazenar dados importantes do arquivo enviado pelo usuário, como id, nome, extensão e data de upload. Quando alguém acessar o link de compartilhamento, a API poderá recuperar o arquivo do serviço onde está armazenado (no caso, o Cloudflare R2) e retornar o arquivo correto para o usuário.
Requisitos
Antes de trabalhar com o Mongo no projeto, precisamos preparar o PHP para dar suporte ao Mongo. Para isso, a própria documentação do PHP tem instruções de como fazer isso: https://www.php.net/manual/en/mongodb.installation.php
Também precisamos de um servidor com o Mongo rodando. Existem várias formas de obter isso, e eu utilizei um serviço do próprio Mongo chamado MongoDB Atlas Cluster, que possui um tier gratuito para testes.
Importante
A implementação do Mongo em um projeto Symfony é bem simples, mas existem algumas considerações importantes:
- Não existe mais
ORM
, agora éODM
(sigla para Object-Document Mapper) - Por isso, não existe
EntityManager
, agora éDocumentManager
- Enfim, não existem mais Entidades, agora são Documentos, assim, criamos os documentos na pasta
src/Document
Implementação
Agora sim, vamos para a implementação.
-
Instale o módulo do mongo no projeto
composer require doctrine/mongodb-odm-bundle # Do you want to execute this recipe? 'yes'
-
Em
config/packages/doctrine_mongodb.yaml
, apague tudo e cole
doctrine_mongodb: auto_generate_proxy_classes: true auto_generate_hydrator_classes: true connections: default: server: "%env(resolve:MONGODB_URL)%" default_database: "%env(resolve:MONGODB_DB)%" document_managers: default: auto_mapping: true mappings: App: dir: "%kernel.project_dir%/src/Document" mapping: true type: attribute prefix: 'App\Document' is_bundle: false alias: App
Crie as variáveis de ambiente
MONGODB_URL
eMONGODB_DB
, depois coloque respectivamente a conexão com seu servidor MongoDB e o nome do Database que você criou para o projeto. Também comentei a conexão dosqlite
que havia antes.-
Crie os documentos do seu projeto. É bem parecido com criar uma entidade, exceto que:
- Invés de ORM é ODM
- Invés de "table" é "colletion"
- Invés de "Entity" é "Document"
- Invés de "Column" é "Field"
-
Meu exemplo:
<?php namespace App\Document; use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM; #[ODM\Document(collection: 'files')] class File { #[ODM\Id] public ?string $id = null; public function __construct( #[ODM\Field] private ?string $name = null, #[ODM\Field] private ?int $size = null, #[ODM\Field] private ?string $type = null, #[ODM\Field] private ?string $key = null, ) { } public function getId(): ?string { return $this->id; } }
-
Crie o repository do documento
<?php namespace App\Repository; use App\Document\File; use Doctrine\Bundle\MongoDBBundle\ManagerRegistry; use Doctrine\Bundle\MongoDBBundle\Repository\ServiceDocumentRepository; class FileRepository extends ServiceDocumentRepository { public function __construct(ManagerRegistry $registry) { parent::__construct($registry, File::class); } public function add(File $entity): File { $this->getDocumentManager()->persist($entity); $this->getDocumentManager()->flush(); return $entity; } }
Onde utilizava
App\Entity\File
troque paraApp\Document\File
-
A utilização do document para inserir, atualizar etc. é a mesma como era com as entidades. Pode ver um exemplo no método
upload
doFileController
:
// ... $file = new File($fileDTO->name, $fileDTO->size, $fileDTO->type, $fileKey); $file = $this->fileRepository->add($file);
Agora é só testar
Conclusão
Decidi utilizar o Mongo neste projeto mais por estudo. Tanto as tecnologias SQL quanto NoSQL serviriam para este projeto. No entanto, cada caso é um caso. É necessário avaliar qual tipo de banco é mais adequado para resolver o problema em questão. Às vezes os bancos relacionais são a opção certa, outras vezes armazenar em documentos é melhor. DEPENDE.
Top comments (0)