You can build a CRUD API in Laravel 13 on MongoDB with the official mongodb/laravel-mongodb package. It adds a MongoDB database driver and an Eloquent-style base model, so your controller code looks almost the same as with MySQL. In this tutorial you will connect Laravel to MongoDB, create a Book model and expose create, read, update and delete endpoints.
Targets: Laravel 13 (PHP 8.3 to 8.5), the MongoDB PHP extension, a running MongoDB server or Atlas cluster and the mongodb/laravel-mongodb package. Before installing, open the package's compatibility table and confirm which package version supports Laravel 13; Composer will refuse to install an incompatible version.
Step 1: Install the MongoDB PHP extension
The package needs the mongodb PHP extension. Install it with PECL or your platform's package, enable it in php.ini (extension=mongodb) and confirm:
php -m | grep mongodb On Windows tools such as Laragon or Herd, enable the extension from the PHP extensions menu or add the DLL that matches your PHP version.
Step 2: Install the Laravel MongoDB package
composer require mongodb/laravel-mongodb The package's quick start shows a version constraint such as ^5.12; use the constraint that the compatibility table lists for your Laravel version.
Step 3: Configure the connection
Add a mongodb connection to config/database.php inside the connections array:
'mongodb' => [ 'driver' => 'mongodb', 'dsn' => env('DB_URI'), 'database' => env('DB_DATABASE', 'library'), ], Then set the connection string in .env. A local server and an Atlas cluster look like this:
DB_URI=mongodb://127.0.0.1:27017 # or: DB_URI=mongodb+srv://USER:PASSWORD@cluster0.example.mongodb.net DB_DATABASE=library Keep real credentials only in .env, never in committed files.
Step 4: Create the model
A MongoDB model extends the package's Model class instead of Laravel's. Set the connection on the model so it does not use your default database:
<?php namespace App\Models; use MongoDB\Laravel\Eloquent\Model; class Book extends Model { protected $connection = 'mongodb'; protected $fillable = ['title', 'author', 'price']; protected function casts(): array { return [ 'price' => 'float', ]; } } MongoDB creates the collection (the equivalent of a table) the first time you insert a document, so there is no migration to run. The primary key is _id, an ObjectId that the package exposes as a string.
Step 5: Add the API routes
If your project has no routes/api.php yet, run php artisan install:api. Then register a resource route:
use App\Http\Controllers\BookController; use Illuminate\Support\Facades\Route; Route::apiResource('books', BookController::class); Step 6: Write the controller
php artisan make:controller BookController --api <?php namespace App\Http\Controllers; use App\Models\Book; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; class BookController extends Controller { public function index(): JsonResponse { return response()->json(Book::latest()->paginate(10)); } public function store(Request $request): JsonResponse { $data = $request->validate([ 'title' => ['required', 'string', 'max:255'], 'author' => ['required', 'string', 'max:255'], 'price' => ['required', 'numeric', 'min:0'], ]); return response()->json(Book::create($data), 201); } public function show(Book $book): JsonResponse { return response()->json($book); } public function update(Request $request, Book $book): JsonResponse { $data = $request->validate([ 'title' => ['sometimes', 'string', 'max:255'], 'author' => ['sometimes', 'string', 'max:255'], 'price' => ['sometimes', 'numeric', 'min:0'], ]); $book->update($data); return response()->json($book); } public function destroy(Book $book): JsonResponse { $book->delete(); return response()->json(null, 204); } } Route model binding works because the model's route key is its primary key, _id. Validation uses the normal Laravel rules. Do not use the exists or unique rules against MongoDB collections unless you have checked how the package handles them for your version.
Step 7: Test the endpoints
curl -X POST http://localhost:8000/api/books \ -H "Accept: application/json" -H "Content-Type: application/json" \ -d '{"title":"Clean Code","author":"Robert Martin","price":29.5}' curl -H "Accept: application/json" http://localhost:8000/api/books curl -X PUT http://localhost:8000/api/books/PASTE_ID_HERE \ -H "Accept: application/json" -H "Content-Type: application/json" \ -d '{"price":24}' curl -X DELETE http://localhost:8000/api/books/PASTE_ID_HERE Always send Accept: application/json so validation errors come back as JSON instead of a redirect.
How do I check the data in MongoDB?
Open MongoDB Compass or mongosh, switch to the library database and run db.books.find(). You should see the document you created, with an _id field and the three fields from the request.
Common mistakes
- Extension missing: Laravel reports that the MongoDB driver class is not found. Enable
extension=mongodbfor the same PHP the web server uses. - Using the default Eloquent Model: it queries your SQL connection. Extend
MongoDB\Laravel\Eloquent\Model. - Missing $connection: the model falls back to your default database unless the default connection is MongoDB.
- Assuming an auto-increment id: IDs are ObjectIds, not integers.
- Atlas network access: add your IP address to the Atlas allowlist or connections will time out.
FAQ
Do I need migrations with MongoDB?
No. Collections are created automatically on first insert. The package does provide schema helpers if you want indexes.
Can I mix MySQL and MongoDB in one Laravel app?
Yes. Keep your default connection on MySQL and set $connection = 'mongodb' only on the models that live in MongoDB.
Is this package official?
Yes. It is published by MongoDB under the mongodb/laravel-mongodb name.
References
- Laravel MongoDB documentation
- Laravel MongoDB: Get Started
- Laravel 13 Eloquent
- Laravel 13 controllers
Originally published on yasiramin.dev.
