Laravel CRUD rest api

Ivan Shaburov
3 min readJun 10, 2021

--

I want to tell about package for REST API CRUD operations, based on laravel framework. If you want to create controllers and get json response (like Pagination, Object list without pagination, Store, Update, Destroy and Show methods.) faster, you can use this one package. You can also use it for table’ creation in admin panels

composer require shaburov/laravel-crud-rest-api

Configuration

Publish config

 php artisan vendor:publish --provider="CrudRestApi\CrudServiceProvider"

Default config

'load_routes' => false, // load test routes
'migration_dir' => database_path()."/migrations/crud" // migrations export path - not required ,
'per_page' => [
'key' => 'per_page', // key for get parameter
'value' => 10, // default value
'limit' => 100, // max value
],

Commands

Run controller tests
php artisan crud-rest-api:test
Run migrations
php artisan crud-rest-api:migrate {param_from_migrate}

How to use

Create Controller and extends it from CrudBaseController or create your Controller realize from interfaces and traits. Connect your model realize method setModelClass e.g.

abstract class MyController extends CrudController implements
CrudSaveInterface, CrudIndexInterface,
CrudStoreInterface, CrudListInterface,
CrudUpdateInterface, CrudDestroyInterface,
CrudRestoreInterface, CrudShowInterface
{
use CrudListTrait,
CrudIndexTrait,
CrudStoreTrait,
CrudIndexTrait,
CrudUpdateTrait,
CrudRestoreTrait,
CrudDestroyTrait,
CrudSaveTrait,
CrudShowTrait;

abstract public function setModelClass(): string;
}

class ArticleController extends MyController
{
public function setModelClass(): string
{
return Article::class;
}
}

Routes

You should add routes in your routes file

Route::namespace('App\Http\Controllers')->group(function (){
Route::resource('articles', 'ArticleController');
});

Validations

You can implement class from CrudValidatorInterface in Controller, use the Trait CrudValidatorTrait and realize method setValidations for connect your validations

public function setValidations(): void
{
$this->validateShow = ArticleShowRequest::class;
$this->validateStore = ArticleStoreRequest::class;
$this->validateIndex = null;
$this->validateList = null;
$this->validateUpdate = null;
$this->validateDelete = null;
}

Index parameters [GET]

page - current page
// https://example.com/api/articles?page=1
per_page - number of objects in the list
// https://example.com/api/articles?per_page=15
list - for get all object
// https://example.com/api/articles?list=1

Change default behaviors

Behaviors methods :

public function beforeList(); // event before list 
public function afterList(); // event after list

public function updating() // event before update
public function updated($model) // event after update

public function creating() // event before store
public function created($model) // event after store

public function saving() // event before store and update
public function saved($model) // event after store and update

public function beforeIndex() // event before index
public function afterIndex() // event after index

public function beforeShow() // event before show
public function afterShow() // event after show

public function deleting() // event before destroy
public function deleted() // event after destroy

Controller example

<?php

namespace CrudRestApi\Http\Controllers;

use CrudRestApi\Http\Request\ArticleShowRequest;
use CrudRestApi\Http\Request\ArticleStoreRequest;
use CrudRestApi\Interfaces\CrudValidatorInterface;
use CrudRestApi\Models\CrudArticle;
use CrudRestApi\Repositories\ArticleRepository;
use CrudRestApi\Traits\CrudValidatorTrait;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;

class ArticleController extends CrudBaseController implements CrudValidatorInterface
{
use CrudValidatorTrait;

protected ArticleRepository $articleRepository;

public function __construct()
{
parent::__construct();
$this->articleRepository = app(ArticleRepository::class);
}

public function setValidations(): void
{
$this->validateShow = ArticleShowRequest::class;
$this->validateStore = ArticleStoreRequest::class;
}

public function setModelClass(): string
{
return CrudArticle::class;
}

public function updating(): void
{
$this->requestData['title'] = Str::lower($this->requestData['title']);
}

public function creating(): void
{
$this->requestData['title'] = Str::upper($this->requestData['title']);
}

public function saving(): void
{
$this->requestData['title'] = Str::lower($this->requestData['title']);
}

public function created($model): void
{
$model->title = Hash::make($model->title);
$model->save();
}

public function updated($model): void
{
$model->title = Hash::make($model->title);
$model->save();
}

public function saved($model): void
{
$model->title = Hash::make($model->title);
$model->save();
}

public function beforeIndex()
{
$this->articleRepository
->index($this->query);
}

public function beforeShow()
{
$this->articleRepository
->show($this->query);
}

public function afterIndex()
{
$this->articleRepository
->transformPaginate($this->pagination);
}

}

Repository example:

<?php


namespace CrudRestApi\Repositories;


use Illuminate\Database\Eloquent\Builder;
use Illuminate\Pagination\LengthAwarePaginator;
use CrudRestApi\Http\Resource\ArticleIndexResource;

class ArticleRepository
{
public function index(Builder $state): void
{
$state->select([
'id',
'title',
'category_id',
])->with('category:id,title');
}

public function show(Builder $state): void
{
$state->select([
'id',
'title',
'description',
'category_id',
'created_at',
])->with('category:id,title');
}

public function transformPaginate(LengthAwarePaginator $pagination): void
{
$pagination->getCollection()
->transform(function ($item) {
return new ArticleIndexResource($item);
});
}
}

In the future

*Generate controllers executing command
*Middleware for custom limits number of pages for some Controllers separately
And more…

github repository: https://github.com/ishaburov/crud-rest-api
packagist: https://packagist.org/packages/shaburov/laravel-crud-rest-api

--

--