Tranquil Controller

Introduction

The Tranquil Controller takes care of all the methods of a standard Laravel controller: index, create, show, edit, store, and destroy

For any of your model controllers all you have to do is extend TranquilController

1class CarController extends TranquilController {}

Then all you need to do is add the resource routes for the model.

1// routes/web.php
2 
3Route::resource('cars', CarController::class);

Now all of the endpoints for the resource routes will automatically work - without having to add any methods to your controller.

1GET|HEAD cars .................. cars.index › CarController@index
2POST cars .................. cars.store › CarController@store
3GET|HEAD cars/create ......... cars.create › CarController@create
4GET|HEAD cars/{car} .............. cars.show › CarController@show
5PUT|PATCH cars/{car} .......... cars.update › CarController@update
6DELETE cars/{car} ........ cars.destroy › CarController@destroy
7GET|HEAD cars/{car}/edit ......... cars.edit › CarController@edit

Show

GET /cars/1

1{
2 "success": true,
3 "message": "",
4 "car": {
5 "id": 1,
6 "make": "Audi",
7 "model": "A3",
8 "year": 2016
9 }
10}

Update

Endpoint

PATCH /cars/1

Payload

1{
2 "year": 2024
3}

This will update year column of the cars record that has the id of 1 - As long as the year is included in the $fillable model parameter.

Or if you have the model extend TranquilModel

1class Car extends TranquilModel {
2 //...
3}

Store

Endpoint

POST /cars

Payload

1{
2 "make": "Tesla",
3 "model": "Model S",
4 "year": 2024
5}

This will create a new record in the cars table. You can have automatic input validation if the model extends TranquilModel or uses the HasValidation trait.

1class Car extends Model {
2 use HasValidation;
3 //...
4}

List

There is also a list route endpoint you can add for fetching a list of records for the model

1// routes/web.php
2 
3Route::post('cars/list', [CarController::class, 'list'])->name('cars.list');

Endpoint

POST /cars/list

Payload

1{
2 "where": {"make": "Buick"}
3}

Response

1{
2 "success": true,
3 "message": "",
4 "total": 4,
5 "records": [
6 {
7 "id": 108,
8 "make": "Buick",
9 "model": "Enclave",
10 "year": 2016
11 },
12 {
13 "id": 109,
14 "make": "Buick",
15 "model": "Encore GX",
16 "year": 2016
17 },
18 {
19 "id": 110,
20 "make": "Buick",
21 "model": "Envision",
22 "year": 2016
23 },
24 {
25 "id": 111,
26 "make": "Buick",
27 "model": "Envista",
28 "year": 2016
29 }
30 ]
31}

Search Parameter

In the request payload you can include a search parameter with an array of search logic to filter the results.

Basic Payload Example

POST /users/list

1{
2 "search": [
3 {"column": "firstName", "value": "Jane"},
4 {"column": "lastName", "value": "Doe"}
5 ]
6}

This would produce a query equivalent to:

1User::where('firstName', 'Jane')->where('lastName', 'Doe')

Available Search Logic Parameters

Parameter Description Required Default
logic Available options: 'and', 'or' 'and'
column The name of the DB column. You can use dot notation to search on a relation column (one level only) e.g. parent.companyName Yes
rawColumn For using raw sql on the left side of the where clause operator
operator Any valid SQL operator - 'startsWith', 'contains', and 'endsWith' will translate to 'like' '='
value The value to be search for Yes
type Available options: 'date', 'bool', 'boolean', 'raw' Defaults to the table column schema type
caseSensitive Boolean flag for case sensitivity for this column search false
subSearch An array of search logic parameters to group in a sub query. Use this to isolate grouped and/or logic.

Complex Payload Example

1{
2 "search": [
3 {"column": "firstName", "operator": "startsWith", "value": "Jane"},
4 {"column": "lastName", "operator": "endsWith", "value": "Doe", "logic": "or"},
5 {
6 "logic": "or",
7 "subSearch": [
8 {"column": "email", "operator": "contains", "value": "example"},
9 {"column": "jobTitle", "like", "%foo%bar%", "caseSensitive": true}
10 ]
11 },
12 {"column": "created_at", "type": "date", "operator": "between", "value": ["2024-01-01", "2024-02-01"]},
13 {"rawColumn": "concat(firstName, lastName)", "value": "JaneDoe" },
14 {"column": "email", "type": "raw", "value": "concat(firstName, lastName, '@example.com')"}
15 ]
16}

This would produce a query equivalent to:

1User::where(DB::raw("lower(firstName)"), 'like' strtolower('Jane%'))
2 ->orWhere(DB::raw("lower(lastName)"), 'like' strtolower('%Doe'))
3 ->orWhere(function($query) {
4 $query->where(DB::raw("lower(email)"), 'like', strtolower('%example%'))
5 ->where('jobTitle', 'like', '%foo%bar%')
6 })
7 ->whereBetween('created_at', ['2024-01-01', '2024-02-01'])
8 ->where(DB::raw("concat(firstName, lastName)"), strtolower('JaneDoe'))
9 ->where('email', DB::raw("concat(firstName, lastName, '@example.com')"));