Modern web applications rely heavily on real-time database interactions and efficient management of large datasets. However, developers often face challenges in handling dynamic, unstructured data while maintaining performance, scalability, and flexibility. Combining Symfony's API Platform with MongoDB simplifies the process of building robust, flexible, and secure REST APIs.
In this project, we demonstrate how to:
- Build REST APIs using Symfony's API Platform.
- Perform CRUD (Create, Read, Update, Delete) operations.
- Connect the application to MongoDB Atlas.
By the end of this tutorial, you’ll have a working application capable of efficiently managing database interactions using the API Platform with MongoDB.
Before starting, ensure you have the following:
- A free MongoDB Atlas cluster: Register and create your first free cluster.
- PHP 8.x or higher.
- Docker installed for containerized development.
- Create a new GitHub repository for your project.
- Clone the repository locally:
git clone <repository_url>
- Generate a Symfony project with the API Platform:
composer create-project symfony/skeleton my_project cd my_project composer require api
- Add a MongoDB service to your
docker-compose.yml
file:services: mongodb: image: mongo container_name: mongodb ports: - "27017:27017" environment: MONGO_INITDB_ROOT_USERNAME: root MONGO_INITDB_ROOT_PASSWORD: example
- Start the Docker containers:
docker-compose up -d
- Create a free Atlas cluster and retrieve your connection string.
- Update your
.env
file:MONGODB_URL=<your_atlas_connection_string> MONGODB_DB=<database_name>
- Install the MongoDB ODM bundle:
docker compose exec php composer require doctrine/mongodb-odm-bundle
Create a document class to map the MongoDB schema. For example, a Restaurant document might look like this:
<?php
namespace App\Document;
use ApiPlatform\Metadata\ApiResource;
use Doctrine\ODM\MongoDB\Mapping\Annotations\Document;
use Doctrine\ODM\MongoDB\Mapping\Annotations\Field;
use Doctrine\ODM\MongoDB\Mapping\Annotations\Id;
#[ApiResource]
#[Document]
class Restaurant
{
#[Id]
public string $id;
#[Field]
public string $name;
#[Field]
public string $address;
#[Field]
public string $borough;
#[Field]
public string $cuisine;
}
Define a POST endpoint in the RestaurantController
:
public function create(Request $request): JsonResponse
{
$data = json_decode($request->getContent(), true);
$restaurant = new Restaurant();
$restaurant->name = $data['name'];
$restaurant->address = $data['address'];
$restaurant->borough = $data['borough'];
$restaurant->cuisine = $data['cuisine'];
$this->documentManager->persist($restaurant);
$this->documentManager->flush();
return new JsonResponse(['status' => 'Restaurant created!'], JsonResponse::HTTP_CREATED);
}
Retrieve a document by ID:
public function read(string $id): JsonResponse
{
$restaurant = $this->repository->find($id);
if (!$restaurant) {
return new JsonResponse(['error' => 'Not found'], JsonResponse::HTTP_NOT_FOUND);
}
return new JsonResponse($restaurant);
}
Modify an existing document:
public function update(string $id, Request $request): JsonResponse
{
$restaurant = $this->repository->find($id);
if (!$restaurant) {
return new JsonResponse(['error' => 'Not found'], JsonResponse::HTTP_NOT_FOUND);
}
$data = json_decode($request->getContent(), true);
$restaurant->name = $data['name'];
$restaurant->address = $data['address'];
$restaurant->borough = $data['borough'];
$restaurant->cuisine = $data['cuisine'];
$this->documentManager->flush();
return new JsonResponse(['status' => 'Restaurant updated!']);
}
Remove a document by ID:
public function delete(string $id): JsonResponse
{
$restaurant = $this->repository->find($id);
if (!$restaurant) {
return new JsonResponse(['error' => 'Not found'], JsonResponse::HTTP_NOT_FOUND);
}
$this->documentManager->remove($restaurant);
$this->documentManager->flush();
return new JsonResponse(['status' => 'Restaurant deleted']);
}
- Start the application:
docker-compose up
- Access the API documentation at:
http://localhost:8080/docs
- Test the endpoints using tools like Postman, cURL, or the interactive API docs.
Example of a restaurant document:
{
"name": "Spice of India",
"address": "73-10 Grand Ave, Maspeth, NY 11378",
"borough": "Queens",
"cuisine": "Indian"
}
By using Symfony's API Platform and MongoDB, you can efficiently manage RESTful APIs for dynamic and unstructured data. This combination provides:
- Scalability.
- Simplified CRUD operations.
- Seamless integration with MongoDB Atlas or Docker-based MongoDB setups.
Explore the repository for more advanced features like query optimization and schema evolution. Feel free to extend this project to suit your application's needs!