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 mongodbOn 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-mongodbThe 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=libraryKeep 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_HEREAlways 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.



