Skip to main content

Overview

RestController is the base controller class that:
  • Exposes REST endpoints: Standard CRUD operations via HTTP
  • Processes query parameters: Converts request params to service-compatible format
  • Handles errors: Database exception parsing with user-friendly messages
  • Supports exports: Excel and PDF export endpoints
  • Transaction management: Automatic database transactions for write operations
  • Logging: Configurable query logging
Extend RestController and set $modelClass and $service properties to instantly create a REST API for your model.

Properties

modelClass

protected BaseModel|string $modelClass = "";
The Eloquent model class (used for model name extraction).

service

protected BaseService|string $service = "";
The service instance handling business logic.

Core Methods

process_request()

public function process_request(Request $request): array
Extracts and normalizes query parameters from the request.
request
Request
required
Laravel HTTP request object
return
array
Normalized parameters object:
[
  'relations' => string|array|null,
  '_nested' => bool,
  'soft_delete' => mixed|null,
  'attr' => array|null, // equality filters
  'select' => string|array,
  'pagination' => array|null,
  'orderby' => array|null,
  'oper' => array|string|null,
  'hierarchy' => mixed|null
]
Merging behavior:
  • Merges query string and request body parameters
  • attr and eq are merged if both present
  • All parameters are optional (null if not provided)
Example request:
GET /api/users?relations=["posts","roles"]&oper={"and":["status = active"]}&pagination={"page":1,"pageSize":20}

handleDatabaseException()

protected function handleDatabaseException(\Throwable $e): DatabaseErrorParserException
Parses database exceptions into user-friendly error messages.
e
Throwable
required
Database exception (QueryException or PDOException)
return
DatabaseErrorParserException
Parsed exception with:
  • HTTP status code
  • User-friendly message
  • Error type (e.g., “unique_violation”, “foreign_key_violation”)
Handles:
  • Foreign key violations
  • Unique constraint violations
  • NOT NULL violations
  • Syntax errors
  • Connection errors
Logging: Full exception details are logged to the rest-generic-class channel.

callAction()

public function callAction($method, $parameters)
Intercepts method calls for logging (if enabled). Configuration:
// config/rest-generic-class.php
'logging' => [
    'query' => true, // Enable query logging
],
Log location: storage/logs/query.log

REST Endpoints

index()

public function index(Request $request): LengthAwarePaginator|array|CursorPaginator
HTTP: GET /resource Retrieves a list of resources.
relations
string|array
Relations to eager load (JSON array or comma-separated)
select
string|array
Fields to select
oper
string|array
Filter conditions (JSON object)
orderby
string|array
Ordering (JSON array of {"field": "direction"})
pagination
string|object
Pagination config (JSON object with page, pageSize, infinity, cursor)
hierarchy
string|object
Hierarchy mode config
_nested
boolean
Apply relation filters to eager loading
200
array|LengthAwarePaginator
{
  "data": [
    {"id": 1, "name": "John", "email": "[email protected]"},
    {"id": 2, "name": "Jane", "email": "[email protected]"}
  ]
}
// OR paginated:
{
  "current_page": 1,
  "data": [...],
  "total": 100,
  "per_page": 20,
  "last_page": 5
}
Example:
curl "https://api.example.com/users?relations=[\"posts\"]&oper={\"and\":[\"status = active\"]}&pagination={\"page\":1,\"pageSize\":20}"

getOne()

public function getOne(Request $request): array
HTTP: GET /resource/first Retrieves the first record matching filters.
...
mixed
Same query parameters as index()
200
array
{
  "data": {"id": 1, "name": "John", "email": "[email protected]"}
}

show()

public function show(Request $request, $id): mixed
HTTP: GET /resource/{id} Retrieves a single resource by ID.
id
mixed
required
Resource ID
relations
string|array
Relations to load
select
string|array
Fields to select
hierarchy
string|object
Hierarchy mode
200
object
{
  "id": 1,
  "name": "John Doe",
  "email": "[email protected]",
  "posts": [...],
  "roles": [...]
}
404
object
Model not found
Example:
curl "https://api.example.com/users/1?relations=[\"posts\",\"roles\"]"

store()

public function store(BaseFormRequest $request): array
HTTP: POST /resource Creates a new resource (or multiple).
...
object
required
Resource attributes OR wrapped array:
{"name": "John", "email": "[email protected]"}

// OR multiple:
{
  "user": [
    {"name": "John", "email": "[email protected]"},
    {"name": "Jane", "email": "[email protected]"}
  ]
}
200
object
{
  "success": true,
  "model": {"id": 1, "name": "John", "email": "[email protected]"}
}
422
object
Validation failed
Transaction handling:
  • Automatically wraps in database transaction
  • Commits on success
  • Rolls back on error
Example:
curl -X POST https://api.example.com/users \
  -H "Content-Type: application/json" \
  -d '{"name":"John Doe","email":"[email protected]","password":"secret"}'

update()

public function update(Request $request, $id): mixed
HTTP: PUT/PATCH /resource/{id} Updates an existing resource.
id
mixed
required
Resource ID
...
object
required
Fields to update (partial updates supported)
200
object
{
  "success": true,
  "model": {"id": 1, "name": "John Updated", ...}
}
404
object
Resource not found
422
object
Validation failed
Example:
curl -X PATCH https://api.example.com/users/1 \
  -H "Content-Type: application/json" \
  -d '{"status":"active"}'

updateMultiple()

public function updateMultiple(Request $request): mixed
HTTP: PATCH /resource/batch Updates multiple resources at once.
{model}
array
required
Array of objects with IDs:
{
  "user": [
    {"id": 1, "status": "active"},
    {"id": 2, "status": "inactive"}
  ]
}
200
object
{
  "success": true,
  "models": [
    {"success": true, "model": {...}},
    {"success": true, "model": {...}}
  ]
}

destroy()

public function destroy($id): array
HTTP: DELETE /resource/{id} Deletes a resource by ID.
id
mixed
required
Resource ID
200
object
{
  "success": true,
  "model": {...}
}
404
object
Resource not found
Example:
curl -X DELETE https://api.example.com/users/1

deleteById()

public function deleteById(Request $request): array
HTTP: DELETE /resource/batch Deletes multiple resources by IDs.
ids
array
required
Array of IDs to delete
200
object
{"success": true}

Export Endpoints

export_excel()

public function export_excel(Request $request)
HTTP: GET /resource/export/excel Exports filtered data to Excel.
...
mixed
Same query parameters as index() plus:
filename
string
Output filename (default: excel.xlsx)
columns
string|array
Columns to export (default: uses select or all fillable)
200
binary
Excel file download
Example:
curl "https://api.example.com/users/export/excel?oper={\"status = active\"}&columns=[\"id\",\"name\",\"email\"]&filename=active-users.xlsx"

export_pdf()

public function export_pdf(Request $request)
HTTP: GET /resource/export/pdf Exports filtered data to PDF.
...
mixed
Same query parameters as index() plus:
filename
string
Output filename (default: pdf_file.pdf)
template
string
Blade view name (default: pdf)
columns
string|array
Columns to export
200
binary
PDF file download

Validation Endpoint

actionValidate()

public function actionValidate(BaseFormRequest $request): JsonResponse
HTTP: POST /resource/validate Validates request data without saving.
...
object
required
Data to validate
200
object
{"success": true}
422
object
Validation errors

Error Handling

All database errors are caught and parsed into user-friendly responses.

Unique Constraint Violation

{
  "message": "The email has already been taken.",
  "type": "unique_violation",
  "field": "email",
  "status": 409
}

Foreign Key Violation

{
  "message": "Cannot delete record because it is referenced by other records.",
  "type": "foreign_key_violation",
  "status": 409
}

NOT NULL Violation

{
  "message": "The name field is required.",
  "type": "not_null_violation",
  "field": "name",
  "status": 422
}

Complete Implementation Example

use App\Models\User;
use App\Services\UserService;
use Ronu\RestGenericClass\Core\Controllers\RestController;

class UserController extends RestController
{
    public function __construct()
    {
        $this->modelClass = User::class;
        $this->service = new UserService();
    }
}

Route Registration

// routes/api.php
use App\Http\Controllers\UserController;

Route::prefix('users')->group(function () {
    Route::get('/', [UserController::class, 'index']);
    Route::get('/first', [UserController::class, 'getOne']);
    Route::get('/{id}', [UserController::class, 'show']);
    Route::post('/', [UserController::class, 'store']);
    Route::patch('/{id}', [UserController::class, 'update']);
    Route::patch('/batch', [UserController::class, 'updateMultiple']);
    Route::delete('/{id}', [UserController::class, 'destroy']);
    Route::delete('/batch', [UserController::class, 'deleteById']);
    Route::get('/export/excel', [UserController::class, 'export_excel']);
    Route::get('/export/pdf', [UserController::class, 'export_pdf']);
    Route::post('/validate', [UserController::class, 'actionValidate']);
});
That’s it! You now have a complete REST API with:
  • List with filtering, pagination, relations
  • Single record retrieval
  • Create, update, delete operations
  • Batch operations
  • Excel/PDF exports
  • Validation endpoint
  • Automatic error handling
  • Transaction management

Advanced Usage

Custom Endpoints

Extend the controller with custom methods:
class UserController extends RestController
{
    public function __construct()
    {
        $this->modelClass = User::class;
        $this->service = new UserService();
    }
    
    public function activateUser(Request $request, $id)
    {
        DB::beginTransaction();
        try {
            $user = $this->service->show([], $id);
            $result = $this->service->update(['status' => 'active'], $id);
            
            // Send activation email
            Mail::to($user->email)->send(new UserActivated($user));
            
            DB::commit();
            return $result;
        } catch (\Throwable $e) {
            DB::rollBack();
            throw $e;
        }
    }
}

Custom Request Validation

Create a FormRequest class:
use Ronu\RestGenericClass\Core\Requests\BaseFormRequest;

class CreateUserRequest extends BaseFormRequest
{
    public function rules()
    {
        return [
            'name' => 'required|min:3',
            'email' => 'required|email|unique:users',
            'password' => 'required|min:8',
        ];
    }
}

// Use in controller
public function store(CreateUserRequest $request): array
{
    return parent::store($request);
}

BaseModel

Model class with validation and hierarchy

BaseService

Service layer handling business logic

Filter Syntax

Complete filter operators reference

Middleware

Authentication and authorization

Build docs developers (and LLMs) love