Make Laravel API even more flexible with artisan resource.

Jurin Liyun
4 min readAug 27, 2023

What is Laravel API Resource?

Laravel API resources act as a transformation layer that sits between your Eloquent models and the JSON responses that are returned to your application’s users. Laravel’s resource classes allow you to expressively and easily transform your models and model collections into JSON.
For more insight into how they work you can check out the official laravel documentation.

Manipulating output was very tedious and tricky when it comes to API development. Most of the time, in old laravel I always find myself manipulating complex output through database view. But now, laravel make it even easier to manipulate with Laravel Resource. Let take a look how it made using Laravel resource.

In this example we will create 2 models namely, Book and Author. Let also create the relationship between book and author model. Let’s open up laravel 5.5+ project. In this example i ll be using Laravel 10. Open up the terminal inside the project and execute the following command.

php artisan make:model Book -m 

Php artisan make:model Author -m
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use App\Models\Author;

class Book extends Model
{
use HasFactory;

public function author()
{
return $this->belongsTo(Author::class, 'author_id', 'id');
}
}
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use App\Models\Book;

class Author extends Model
{
use HasFactory;

public function books()
{
return $this->hasMany(Book::class, 'author_id', 'id');
}
}

for the migrations part, please add this line.


<?php
//book migration
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('books', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->string('author_id');
$table->timestamps();
});
}

/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('books');
}
};
<?php
//Author migration
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('authors', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('address');
$table->timestamps();
});
}

/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('authors');
}
};

Now create the api controller for the Book model.

php artisan make:controller Api/BookController

Then, add the following code in your Api/BookController to get all the book data from database using eloquent ORM.

<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Book;
use Illuminate\Http\Request;

class BookController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index()
{
return response()->json(Book::all());
}
}

Lets define the api route for this book controller.

<?php
// routes/api.php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider and all of them will
| be assigned to the "api" middleware group. Make something great!
|
*/

Route::apiResource('books', \App\Http\Controllers\Api\BookController::class);

Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user();
});

Now you can run the artisan command as php artisan serve for the web to run. The sample output should be as follows.

Now it time to add BookResource for our book api. Lets run the following command, php artisan make:resource BookResource . This command will generate BookResource.php inside the newly created directory under Http>Resources . By modifying the BookResource and BookController file you will now get different result and more informative than the previous one. I can now expose data based on my needs. All data manipulation can be done in the resource file.

<?php

namespace App\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class BookResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
'title' => $this->title,
'author' => $this->author
];
}
}
<?php

namespace App\Http\Controllers\Api;

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

class BookController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index()
{
// return response()->json(Book::all());
return BookResource::collection(Book::all());
}
}

Hope that in this simple use case, can help you into your journey to learn laravel api resource. The full code for this tutorial can be found here.

Thanks for reading.

--

--

Jurin Liyun

Developer, Trainer , Consultant, Father of two children