Laravel API Documentation with Scramble: Best Practices and Tutorial

Andre Elmustanizar
4 min readOct 27, 2024

--

Hello everyone, I will share my experience in creating Laravel application documentation using Scramble in this article.

Before we start, let’s get to know Laravel and Scramble first.

https://laravel.com

Laravel is a web application framework with expressive, elegant syntax. A web framework provides a structure and starting point for creating your application, allowing you to focus on creating something amazing while you sweat the details.

Laravel strives to provide an amazing developer experience while providing powerful features such as thorough dependency injection, an expressive database abstraction layer, queues, and scheduled jobs, unit and integration testing, and more.

https://scramble.dedoc.co/

Scramble is an OpenAPI (Swagger) documentation generator for Laravel. It automatically generates API documentation for your project without requiring you to write PHPDoc annotations manually.

Let’s start…

First, Installing Laravel.

composer create-project laravel/laravel laravel_scramble

cd laravel_scramble

Installing & Publish Scramble.

composer require dedoc/scramble

php artisan vendor:publish --provider="Dedoc\Scramble\ScrambleServiceProvider" --tag="scramble-config"

When Scramble is installed, 2 routes are added to your application:

  • /docs/api - UI viewer for your documentation
  • /docs/api.json - Open API document in JSON format describing your API.

And that’s it! You can now visit /docs/api to see your API documentation.

By default, these routes are available only in local the environment. You can change this behavior by defining viewApiDocs a gate.

After publish, This will allow you to customize API routes resolution and OpenAPI document’s details. Location file config/scramble.php

Create Book Model, Migration, and Controller.

php artisan make:model Book -mc

Open the migration file in database/migrations/xxxx_xx_xx_create_books_table.php and define the table structure:

public function up(): void
{
Schema::create('books', function (Blueprint $table) {
$table->ulid('id')->primary();
$table->string('title');
$table->text('description');
$table->string('author');
$table->date('publication_date')->nullable();
});
}

In this case I use ULID for primary key the table.
You can see my article about ULID: Choosing Between ID or ULID in Laravel: A Comparative Analysis.

Run the migration to create the table:

php artisan migrate

Next, open the controller to handle CRUD operations for books, In app/Http/Controllers/BookController.php, add the following methods:

<?php

namespace App\Http\Controllers;

use App\Models\Book;
use Illuminate\Http\Request;
use App\Http\Resources\BookResource;

class BookController extends Controller
{
/**
* Display a listing of data books.
*/
public function index()
{
$books = Book::paginate(10);
return response()->json($books);
}

/**
* Created new book.
*/
public function store(Request $request)
{
$data = $request->validate([
'title' => ['required', 'max:255', 'string'],
'description' => ['required', 'string'],
'author' => ['required', 'max:255', 'string'],
'publication_date' => ['required', 'date'],
]);

$book = Book::create($data);

return new BookResource($book);
}

/**
* Display the specified book.
*/
public function show($id)
{
return Book::findOrFail($id);
}

/**
* Update the specified book in storage.
*/
public function update(Request $request, $id)
{
$data = $request->validate([
'title' => ['required', 'max:255', 'string'],
'description' => ['required', 'string'],
'author' => ['required', 'max:255', 'string'],
'publication_date' => ['required', 'date'],
]);

$book = Book::findOrFail($id);
$book->update($data);

return new BookResource($book);
}

/**
* Remove the specified book from storage.
*/
public function destroy($id)
{
$book = Book::findOrFail($id);
$book->delete();
return response()->json(null, 204);
}
}

Don’t forget to add the fillable attributes to the Book model in app/Models/Book.php:

class Book extends Model
{
use HasFactory, HasUlids;

protected $table = 'books';
protected $primaryKey = 'id';
public $incrementing = false;

protected $fillable =
[
'title',
'description',
'author',
'publication_date',
];
}

The final step is to define the route.

Open the file route in routes/api.php

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\BookController;

Route::prefix('v1')->group(function () {
Route::resource('books', BookController::class);
});

In this route, I implement versioning in my API.

Let’s test…

Open your browser and access url http://127.0.0.1:8000/docs/api

Conclusion

Congratulations! You have successfully set up a CRUD API for a book database in Laravel and documented it using Scramble. With this approach, your API documentation will always stay in sync with your Laravel project, making it easier for developers to interact with your application’s API.

Using Scramble with Laravel:

  • Ensures that your documentation is always up to date.
  • Helps other developers understand your API endpoints.
  • Reduces the burden of manually maintaining documentation.

Additional Resources

To dive deeper into Laravel and Scramble for effective API documentation, check out these resources:

  • 📘 Laravel Official Documentation: Learn more about Eloquent and CRUD operations in Laravel from the official Laravel documentation here.
  • 📄 Scramble Official Website: Discover how to get started with Scramble for auto-generated API documentation here.
  • 🛠️ Project GitHub Repository: Access the complete source code for this tutorial on GitHub here. Feel free to fork, star, and contribute to the project!

If you found this guide helpful, don’t forget to share it, and stay tuned for more Laravel tutorials. Happy coding!

--

--

Andre Elmustanizar
Andre Elmustanizar

Written by Andre Elmustanizar

I am 4+ years of Laravel development expert and have experience in building Laravel apps monolith or APIs in various industries & domains.

Responses (3)