A Voyage AI se une ao MongoDB para impulsionar aplicativos de AI mais precisos e confiáveis no Atlas.

Explore o novo chatbot do Developer Center! O MongoDB AI chatbot pode ser acessado na parte superior da sua navegação para responder a todas as suas perguntas sobre o MongoDB .

Construindo APIs REST com API Platform e MongoDB

Aasawari Sahasrabuddhe9 min read • Published Jan 09, 2025 • Updated Jan 14, 2025
APLICATIVO COMPLETO
Facebook Icontwitter iconlinkedin icon
Classifique este artigo
star-empty
star-empty
star-empty
star-empty
star-empty
Os aplicativos web de hoje dependem de grandes conjuntos de dados e exigem interação com o banco de dados em tempo real. Os desenvolvedores geralmente enfrentam o desafio de gerenciar e dimensionar com eficiência as operações CRUD (Create, Read, Update, Delete) e, ao mesmo tempo, manter a flexibilidade, o desempenho e a segurança. No entanto, a criação de uma API padrão geralmente vem com desafios significativos: documentar endpoints, mapeá-los para o banco de dados, lidar com a transformação de dados e garantir a validação - tudo enquanto mantém o desempenho, a escalabilidade e a segurança.
Criar um aplicação com a API Platform fornece uma solução robusta, flexível e fácil de usar para criar APIs modernas. Quando perfeitamente integrado ao MongoDB, ele habilita os desenvolvedores a lidar com eficiência com operações CRUD, mantendo a escalabilidade e a facilidade de uso.
Neste tutorial, usaremos a API Platform com Symfony para construir APIs REST que executam operações CRUD no banco de dados MongoDB . Para conectar o aplicação ao MongoDB, usaremos o MongoDB Atlas.

Pré-requisitos

  • Um cluster gratuito do Atlas —registre-se para criar seu primeiro cluster gratuito
  • Docker instalado

Criando um projeto Symfony

Para começar com o projeto Symfony usando a API Platform, siga as etapas descritas abaixo:
  1. Crie o projeto modelo , que gera todos os arquivos necessários para você. Para fazer isso, gere um repositório do Github com sua escolha de nome usando o modelo de api-platform repositório. Você pode consultar a captura de tela abaixo para preencher as entradas.
Image showing steps to clone the GitHUb repository figura 1: imagem mostrando as etapas para clonar o repositório do Github 2. Depois que o repositório for criado, você pode cloná-lo usando o comando abaixo.
1git clone <URL to your repository>
Depois de ter o código em sua máquina local, editaremos o aplicação para se conectar ao MongoDB.
Para saber mais, você pode seguir as etapas mencionadas na documentação de Introdução à API Platform para o Symfony.
Na próxima seção, entenderemos como conectar seu aplicação ao cluster MongoDB Atlas e executar as operações CRUD nas coleções dentro do cluster.

Conectando seu aplicação com o MongoDB Atlas

Depois que seu aplicação de amostra estiver sendo executado corretamente, a próxima etapa é se conectar ao MongoDB Atlas. Para fazer isso, primeiro precisaremos criar um Atlas cluster gratuito e obter a string de conexão.
Para obter a string de conexão, clique em Conectar e selecione o driver apropriado com a versão correta. Você verá uma tela como a abaixo; copie a string de conexão e mantenha-a segura com você.
Image showing steps to get the Atlas connection String figura 2: imagem mostrando etapas para obter a connection string do Atlas
Depois de ter a string de conexão, a próxima etapa é atualizar o Dockerfile e instalar as extensões PHP. O Dockerfile para instalar as extensões está disponível dentro da pasta API/.
Atualize o arquivo com o código abaixo para instalar extensões PHP.
  1. Adicione as alterações de código abaixo ao Dockerfile que você precisará atualizar:
1RUN apt-get update && apt-get install --no-install-recommends -y \
2 libcurl4-openssl-dev \
3 libssl-dev \
4 && pecl install mongodb \
5 && docker-php-ext-enable mongodb
Após a atualização, execute o comando a partir da pasta raiz do projeto para instalar as extensões. Nesse caso, vá para <location where="" git="" clone="" was="" done="" repository="" name="">.</location>
1docker compose build --no-cache
  1. Atualize o .env com a string de conexão e o nome do banco de dados .
1MONGODB_URL=<Atlas URI>
2MONGODB_DB=Test
  1. Atualize o arquivo compose.yaml com a string de conexão como:
1services:
2 php:
3 image: ${IMAGES_PREFIX:-}app-php
4 depends_on:
5 - pwa
6 environment:
7 MONGODB_URL: <Atlas URI>
  1. Depois que as extensões forem instaladas, precisamos iniciar os contêineres e instalar o pacote ODM.
1docker compose up --wait
Quando os contêineres estiverem ativos e prontos, execute os comandos abaixo para instalar o pacote ODM.
1docker compose exec php \
2 composer require doctrine/mongodb-odm-bundle api-platform/doctrine-odm
O mongodb-odm-bundle é um pacote (um pacote modular de código) que integra o MongoDB ODM ao Symfony. Esta biblioteca fornece uma funcionalidade de mapeamento de objeto PHP para MongoDB.

Executando operações CRUD

Quando estiver pronto para fazer as conexões do MongoDB Atlas , a próxima etapa é criar APIs REST para executar operações CRUD.
Neste tutorial, estamos usando uma coleção simples chamada Restaurantes, que terá os seguintes valores de campo :
1{
2 "name": "The Gourmet Spot",
3 "address": {
4 "building": "123",
5 "street": "Elm Street",
6 "zipcode": "12345"
7 },
8 "borough": "Manhattan",
9 "cuisine": "Italian"
10}
Depois que a estrutura do documento for definida, a próxima etapa será criar o Documento e a classe Controlador.
A classe Documento é criada em API/src/Document/Restaurant.php.
Copie o código abaixo na classe Restaurant.php. Esta classe tem todos os valores de campo com todos os métodos de getter e setter.
1<?php
2
3namespace App\Document;
4
5use ApiPlatform\Metadata\ApiResource;
6use App\Repository\RestaurantRepository;
7use Doctrine\ODM\MongoDB\Mapping\Annotations\Document;
8use Doctrine\ODM\MongoDB\Mapping\Annotations\Field;
9use Doctrine\ODM\MongoDB\Mapping\Annotations\Id;
10
11#[ApiResource]
12#[Document(collection: 'restaurants')]
13class Restaurant
14{
15 #[Id]
16 public string $id;
17
18 #[Field]
19 public string $name;
20
21 #[Field]
22 public array $address;
23
24 #[Field]
25 public string $borough;
26
27 #[Field]
28 public string $cuisine;
29}
O endereço.php será parecido com:
1<?php
2
3namespace App\Document;
4
5use Doctrine\ODM\MongoDB\Mapping\Annotations\EmbeddedDocument;
6use Doctrine\ODM\MongoDB\Mapping\Annotations\Field;
7
8#[EmbeddedDocument]
9class Address
10{
11 #[Field]
12 public string $building;
13
14 #[Field]
15 public string $street;
16
17 #[Field]
18 public string $zipcode;
19}
Depois que o código estiver definido, execute o comando abaixo para executar o aplicação completo.
1HTTP_PORT=8080 HTTPS_PORT=8443 docker-compose up

Testando as operações CRUD

A próxima etapa é acessar as APIs de acesso que foram criadas. O URI abaixo leva você até a plataforma da API para testar as chamadas da API REST.
1https://localhost:8443/docs
A API Platform oferece suporte nativo ao formato de documentação da API Open API (anteriormente Atlas). Ele também integra uma versão personalizada da UI do MongoDB, uma boa ferramenta para exibir a documentação da API de forma amigável.
Esta página no URI abaixo terá a seguinte aparência:
Image showing screenshot for the API platform swagger figura:3 imagem mostrando captura de tela para a plataforma de API sando
Vamos testar essas APIs REST.

criar

Para testar a API CREATE, vá para o método POST e coloque o JSON como:
1{
2 "name": "The Gourmet Spot",
3 "address": {
4 "building": "123",
5 "street": "Elm Street",
6 "zipcode": "12345"
7 },
8 "borough": "Manhattan",
9 "cuisine": "Italian"
10}
Clique em "Try it out" e você verá que o documento abaixo foi inserido na coleção:
Screenshot of the swagger representing the POST request Personagem 4: captura de tela do presumido que representa a solicitação POST
Para verificar, navegue até o cluster do Atlas e verifique se os dados foram inseridos na coleção test.Restaurants. A captura de tela abaixo mostra que os dados foram inseridos no banco de dados.
Screenshot of Atlas UI representing that data has been inserted Imagem 5: captura de tela da UI do Atlas representando que os dados foram inseridos

Leia

Para obter todos os documentos da coleção, você pode simplesmente usar a API GET para obter todos os documentos. Para obter um documento específico da coleta, execute a API GET conforme especificado.
Screenshot of swagger representing GET request Imagem 6: captura de tela do swigger representando a solicitação GET

Atualização

Há duas operações para atualizar um documento existente. O PUT substitui o documento completo e o PATCH atualizará apenas as propriedades enviadas. Normalmente, apenas o PATCH é usado, e é por isso que a operação PUT está desabilitada por padrão. Para obter mais informações, você pode consultar a documentação de Operações de plataforma API.
Para testar essa API, atualizamos o documento JSON acima como:
1{
2 "name": "The Gourmet Spot",
3 "address": {
4 "building": "123",
5 "street": "Elm Street",
6 "zipcode": "12345"
7 },
8 "borough": "New York",
9 "cuisine": "Spanish"
10}
A API resulta em:
Screenshot of swagger representing PUT request Personagem 7: captura de tela do presumido representando a solicitação PUT
O documento também é atualizado no Atlas cluster.
Screenshot of Atlas UI representing the update of the document Imagem 8: captura de tela da UI do Atlas representando a atualização do documento

Excluir

Por fim, para excluir informações específicas de um restaurante com um _id, executamos a chamada API como:
Screenshot of swagger representing DELETE request Personalidade 9: captura de tela do swigger representando a solicitação DELETE
Os testes acima abrangem as operações CRUD básicas: Criar, Ler, Atualizar, Excluir. Mas a plataforma de API vai muito além disso. Ele possui muitos recursos que permitem criar APIs mais poderosas e dinâmicas com o mínimo de trabalho.
Vamos ver cada um deles em detalhes na próxima seção.

Além do CRUD com a API Platform

A plataforma de API simplifica a criação e a aplicação de validações para que suas regras de integridade de dados sejam aplicadas de forma consistente sem a necessidade de escrever muito código personalizado. E também é ótimo na pesquisa avançada, para que você possa executar queries complexas com facilidade. Ele também permite que você aplique filtros, execute validações de regex e muito mais.

Executando validações no campo

Se você deseja colocar validações no campo como valores obrigatórios, definimos os valores de campo como #[Assert\NotBlank] antes dos valores de campo . Por exemplo, no código abaixo, marcamos o nome, bairro e localidade como os valores obrigatórios.
1class Restaurant
2{
3 #[Id]
4 public string $id;
5
6 #[Field]
7 #[Assert\NotBlank]
8 #[Assert\Length(max: 255)]
9 public string $name;
10
11 #[EmbedOne(targetDocument: Address::class)]
12 #[Assert\Valid]
13 public ?Address $address;
14
15 #[Field]
16 #[Assert\NotBlank]
17 public string $borough;
18
19 #[Field]
20 #[Assert\NotBlank]
21 public string $cuisine;
22}
Como resultado, se uma solicitação for enviada com qualquer um dos valores ausentes, um erro de HTTP será retornado. A captura de tela abaixo mostra um exemplo de um nome ausente na solicitação POST.
Screenshot of swagger representing POST request with required field as empty Personagem 10: captura de tela do presumido representando a solicitação POST com o campo obrigatório como vazio
Precisamos adicionar o código aos Validadores para adicionar essa validação. Esse código deve estar disponível na pasta API/src/Validator/Constraints/ .
1<?php
2
3namespace App\Validator\Constraints;
4
5use Symfony\Component\Validator\Constraint;
6use Symfony\Component\Validator\ConstraintValidator;
7
8final class MinimalPropertiesValidator extends ConstraintValidator
9{
10 public function validate($value, Constraint $constraint): void
11 {
12 if (array_diff(['name', 'cuisine', 'bourough'], $value)) {
13 $this->context->buildViolation($constraint->message)->addViolation();
14 }
15 }
16}
E:
1<?php
2
3namespace App\Validator\Constraints;
4
5use Symfony\Component\Validator\Constraint;
6
7#[Attribute]
8class MinimalProperties extends Constraint
9{
10 public $message = 'The product must have the minimal properties required ("name", "cuisine", "bourough")';
11}
Este código define uma lógica de validação personalizada no Symfony. A classeMinimalPropertiesValidator é responsável por validar se uma array contém as chaves necessárias: nome, cozinha e bairro.
O métodovalidate verifica se alguma dessas chaves está ausente usando array_diff e, se a validação falhar, dispara uma violação com uma mensagem de erro.
A classeMinimalProperties atua como a restrição personalizada, com sua propriedade de mensagem mantendo o texto de erro exibido em caso de falha.
Da mesma forma, se você deseja adicionar o validador para o CEP fornecido nos valores do campo Endereço, adicione o código abaixo na pasta API/src/Validator/Constraints/ como:
1<?php
2
3namespace App\Validator\Constraints;
4
5use Symfony\Component\Validator\Constraint;
6use Symfony\Component\Validator\ConstraintValidator;
7
8final class ValidZipcodeValidator extends ConstraintValidator
9{
10 public function validate($value, Constraint $constraint): void
11{
12 if (!$constraint instanceof ValidZipCode) {
13 throw new InvalidArgumentException(sprintf('Expected instance of %s, got %s.', ValidZipCode::class, get_class($constraint)));}
14
15 if (!preg_match('/^[0-9]{5}$/', $value)) {
16 $this->context->buildViolation($constraint->message)
17 ->setParameter('{{ value }}', $value)
18 ->addViolation();}
19 }
20}
E:
1<?php
2
3namespace App\Validator\Constraints;
4
5use Symfony\Component\Validator\Constraint;
6
7#[Attribute]
8class ValidZipCode extends Constraint
9{
10 public $message = 'The zipcode "{{ value }}" is not valid. It must be exactly 5 digits.';
11}
No código acima, oValidZipcodeValidator cria a validação de que o CEP só pode ser numérico e apenas cinco caracteres serão permitidos. Para qualquer outro CEP, ele deve lançar o erro conforme mencionado na classeValidZipCode.
Você também precisa declarar a função no Endereço.php como:
1 #[Field]
2 #[ValidZipCode]
3 public string $zipcode;
Para testar isso, podemos enviar a solicitação POST como:
1{
2 "name": "Dim Sum Express",
3 "address": {
4 "building": "404",
5 "street": "Chinatown Blvd",
6 "zipcode": "abcnn"
7 },
8 "borough": "Manhattan",
9 "cuisine": "Chinese"
10 }
A solicitação acima deve resultar em um erro de HTTP com código 422 e uma mensagem informando:
1The zipcode \"abcnn\" is not valid. It must be exactly 5 digits
A captura de tela abaixo exibe a mensagem de erro com a solicitação POST.
Screenshot of swagger representing POST request invalid ZipCode value Personagem 11: captura de tela do swigger representando o valor ZipCode inválido da solicitação POST

Adicionar filtros usando a API Platform

A plataforma API permite aplicar filtros e critérios de classificação nas coleções. O filtro de pesquisa suporta estratégias de correspondência exatas, parciais, iniciais, finais e word_start. Você pode ler mais sobre filtros na documentação da plataforma API em filtros de pesquisa.
Em nosso caso, aplicaremos filtros de pesquisa aos campos nome e cozinha usando o código abaixo dentro da classe Documento.
1#[ApiFilter(
2 SearchFilter::class,
3 properties: [
4 'name' => 'ipartial', The "ipartial" strategy will use a case-insensitive partial match
5 'cuisine' => 'exact', The "exact" strategy will use an exact match
6 ])
7]
Como o comentário sugere, temos um filtro parcial que diferencia maiúsculas de minúsculas para o nome e um filtro de correspondência exata nos campos de gastronomia.
Para testar isso, temos dados de amostra já sendo armazenados dentro da coleção como:
1db.restaurants.find()
2[
3 {
4 _id: ObjectId('6750aa7acda8e992af0c97b4'),
5 name: 'The Gourmet Spot',
6 address: { building: '123', street: 'Elm Street', zipcode: '12345' },
7 borough: 'Manhattan',
8 cuisine: 'Italian'
9 },
10 {
11 _id: ObjectId('6750b8406868c9f4fb012be5'),
12 name: 'Burger Bliss',
13 address: { building: '789', street: 'Main Street', zipcode: '54321' },
14 borough: 'Queens',
15 cuisine: 'American'
16 },
17 {
18 _id: ObjectId('6750b8516868c9f4fb012be8'),
19 name: 'Curry Delight',
20 address: { building: '202', street: 'Spice Lane', zipcode: '45678' },
21 borough: 'Staten Island',
22 cuisine: 'Indian'
23 },
24 {
25 _id: ObjectId('6750b85e6868c9f4fb012beb'),
26 name: 'Pasta Paradise',
27 address: { building: '303', street: 'Olive Way', zipcode: '11223' },
28 borough: 'Manhattan',
29 cuisine: 'Italian'
30 },
31 {
32 _id: ObjectId('6750b86e6868c9f4fb012bee'),
33 name: 'Pizza Kingdom',
34 address: { building: '606', street: 'Pizza Lane', zipcode: '77889' },
35 borough: 'Queens',
36 cuisine: 'Italian'
37 }
38]
Agora, para aplicar o filtro de pesquisa, enviamos a solicitação GET com o nome da cozinha Italiana e devemos ver todos os restaurantes com cuisine: 'Italian'.
Screenshot of swagger representing GET request with filtered values only for Cuisine as Italian figura 12: captura de tela do presumido representando a solicitação GET com valores filtrados apenas para cozinha como italian
Da mesma forma, enviamos uma solicitação GET com um nome parcial como "nome": "Macarrão ...", e devemos ter um restaurante com o nome “Pasta Paradise.”
Screenshot of swagger representing GET request with partial name as only Pasta Personagem 13: captura de tela do presumido representando a solicitação GET com nome parcial como apenas Massa
Você pode criar mais chamadas de API com base no requisito, estendendo o código disponível no repositório do Github e seguindo a documentação da API Platform.

Conclusão

Concluindo, vimos como a API Platform permite criar rapidamente uma API REST para executar operações CRUD em um banco de dados MongoDB . Essa estrutura também permite adicionar recursos à API, como validação de dados e filtros de query, mantendo o código altamente abrangente e escalável. Os programadores podem trabalhar em um ambiente local usando Docker e Atlas.
O tutorial também demonstra como estabelecer a conexão, configurar o ambiente e executar operações CRUD básicas usando um exemplo simples, destacando a flexibilidade e a facilidade de trabalhar com a plataforma API do Symfony.
Para explorar mais, considere mergulhar nos recursos avançados da API Platform, otimizar queries do MongoDB ou experimentar operações CRUD adicionais para atender às necessidades específicas do seu aplicação . Se quiser saber mais, visite a documentação da API Platform e do MongoDB.
Em caso de dúvidas, entre em contato com o Fórum da MongoDB Community e, para saber mais, consulte o Centro de desenvolvedores do MongoDB para obter mais artigos interessantes.
Principais comentários nos fóruns
Ainda não há comentários sobre este artigo.

Facebook Icontwitter iconlinkedin icon
Classifique este artigo
star-empty
star-empty
star-empty
star-empty
star-empty
Relacionado
Tutorial

Dimensionamento com base na demanda: Implantação de aplicativos Python usando o MongoDB Atlas no Azure App Service


Apr 02, 2024 | 12 min read
Artigo

Java x Kotlin: sintaxe diferente, mesmas possibilidades


Nov 25, 2024 | 5 min read
Tutorial

Construa uma plataforma de boletim de notícias com Flask e MongoDB


Sep 04, 2024 | 11 min read
Artigo

Sincronização inicial retomável no MongoDB 4.4


Sep 11, 2024 | 5 min read