Installation Add the package via Composer:
composer require api-platform/doctrine-odm
Ensure doctrine/doctrine-mongodb-odm-bundle and api-platform/core are also installed.
Configuration
Update config/packages/doctrine_mongodb_odm.yaml to include:
doctrine_mongodb:
connections:
default:
server: "%env(MONGODB_URL)%"
options: {}
document_managers:
default:
auto_mapping: true
mappings:
App:
is_bundle: false
dir: "%kernel.project_dir%/src/Document"
prefix: "App\Document"
alias: App
First Use Case
Define a MongoDB document (e.g., src/Document/Book.php):
namespace App\Document;
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
#[ApiResource]
#[MongoDB\Document(collection: "books")]
class Book
{
#[MongoDB\Id]
private ?string $id = null;
#[MongoDB\Field(type: "string")]
public string $title;
#[MongoDB\Field(type: "string")]
public string $author;
}
Run migrations:
php bin/console doctrine:mongodb:schema:update --force
CRUD Operations Leverage API Platform’s built-in controllers for RESTful endpoints:
php bin/console make:entity --entity=Book --no-interaction
Use @ApiResource annotations to auto-generate endpoints (e.g., /api/books).
Data Transformation
Customize serialization/deserialization with ApiResource options:
#[ApiResource(
operations: [
new Get(),
new Post(
normalizationContext: ['groups' => ['book:write']],
denormalizationContext: ['groups' => ['book:write']]
)
]
)]
Querying with Filters
Use API Platform’s built-in filters (e.g., SearchFilter, DateFilter) or create custom ones:
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\SearchFilter;
#[ApiResource(
filters: [new SearchFilter(fields: ['title^', 'author^'])]
)]
MongoDB-Specific Features
ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGenerator for custom queries.@MongoDB\ReferenceOne/@MongoDB\ReferenceMany.Event Subscribers
Hook into lifecycle events (e.g., prePersist, postRemove) via API Platform’s event system:
use ApiPlatform\Core\EventListener;
use Symfony\Component\HttpKernel\Event\ViewEvent;
class BookSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [
KernelEvents::VIEW => ['onView', 10],
];
}
public function onView(ViewEvent $event)
{
$book = $event->getControllerResult();
if ($book instanceof Book) {
$book->setUpdatedAt(new \DateTime());
}
}
}
Schema Migrations
doctrine:mongodb:schema:update without --force may fail if the schema is out of sync.--force cautiously in development; avoid in production. Prefer manual schema updates.Idempotency
_id is auto-generated but may conflict with API Platform’s id field if not handled.@MongoDB\Id and ensure it’s not overridden in ApiResource.Circular References
Author ↔ Book).#[Groups] or #[SerializedName] to control which fields are exposed.Pagination
ApiPlatform\Core\Bridge\Doctrine\Orm\Pagination\MongoDbPagination in config/packages/api_platform.yaml:
api_platform:
pagination:
enabled: true
client_enabled: true
items_per_page: 30
Transaction Handling
doctrine_mongodb_odm.event_listeners.transaction or implement compensating transactions.Debugging Queries
Enable MongoDB logging in config/packages/monolog.yaml:
handlers:
mongodb:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.mongodb.log"
level: debug
channels: ["doctrine"]
Testing
Use mongodb:drop-db and mongodb:create-db in phpunit.xml.dist:
<env name="MONGODB_URL" value="mongodb://localhost:27017/test_db"/>
Run tests with:
php bin/console doctrine:mongodb:drop-db --force
php bin/console doctrine:mongodb:create-db
Performance
@MongoDB\Index annotations to critical fields (e.g., title).hydrationMode: "CUSTOM" in ApiResource to fetch only required fields.Hybrid Projects For projects using both SQL and MongoDB:
doctrine/doctrine-bundle and doctrine-mongodb-odm-bundle side-by-side.api_platform to route entities to the correct data provider:
api_platform:
formats:
jsonld: ['application/ld+json']
json: ['application/json']
html: ['text/html']
patch_formats:
json: ['application/merge-patch+json']
jsonapi: ['application/vnd.api+json']
Extensions
use ApiPlatform\Core\Annotation\ApiProperty;
#[ApiResource(
operations: [
new GetCollection(),
new Post(),
new ApiPlatform\Core\Annotation\ApiResource\Get(
uriTemplate: '/books/{id}/reviews',
requirements: ['id' => '\w+'],
normalizationContext: ['groups' => ['review:read']]
)
]
)]
How can I help you explore Laravel packages today?