DEV Community

Cover image for Implementando MongoDB no Symfony
Natanael Alves
Natanael Alves

Posted on

Implementando MongoDB no Symfony

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.

  1. Instale o módulo do mongo no projeto

    composer require doctrine/mongodb-odm-bundle
    # Do you want to execute this recipe? 'yes'
    
  2. 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
    
  3. Crie as variáveis de ambiente MONGODB_URL e MONGODB_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 do sqlite que havia antes.

  4. Crie os documentos do seu projeto. É bem parecido com criar uma entidade, exceto que:

    1. Invés de ORM é ODM
    2. Invés de "table" é "colletion"
    3. Invés de "Entity" é "Document"
    4. Invés de "Column" é "Field"
    5. 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;
        }
      }
      
  5. 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;
        }
    }
    
    
  6. Onde utilizava App\Entity\File troque para App\Document\File

  7. A utilização do document para inserir, atualizar etc. é a mesma como era com as entidades. Pode ver um exemplo no método upload do FileController:

    // ...
    $file = new File($fileDTO->name, $fileDTO->size, $fileDTO->type, $fileKey);
    $file = $this->fileRepository->add($file);
    
  8. 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.

Heroku

This site is built on Heroku

Join the ranks of developers at Salesforce, Airbase, DEV, and more who deploy their mission critical applications on Heroku. Sign up today and launch your first app!

Get Started

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay