CakePHP 4 How To Create CRUD REST API Tutorial

Reading Time: 9 minutes
7,067 Views

Inside this article we will learn CakePHP 4 how to create CRUD REST API tutorial. Article contains classified information about step by step rest api development.

CRUD stands for Create Read Update Delete. It contains all operations of database.

REST (Representational State Transfer) is an API that defines a set of functions that programmers can use to send requests and receive responses using the HTTP protocol methods such as GET, POST, PUT, PATCH, DELETE.

Learn More –

Let’s get started.

CakePHP 4 Installation

To create a CakePHP project, run this command into your shell or terminal. Make sure composer should be installed in your system.

$ composer create-project --prefer-dist cakephp/app:~4.0 mycakephp

Above command will creates a project with the name called mycakephp.

Create Database

To create a database, either we can create via Manual tool of PhpMyadmin or by means of a mysql command.

CREATE DATABASE mydatabase;

Successfully, we have created a database.

Database Connection

Open app_local.php file from /config folder. Search for Datasources. Go to default array of it.

You can add your connection details here to connect with your database. It will be like this –

//...

'Datasources' => [
        'default' => [
            'host' => 'localhost',
            /*
             * CakePHP will use the default DB port based on the driver selected
             * MySQL on MAMP uses port 8889, MAMP users will want to uncomment
             * the following line and set the port accordingly
             */
            //'port' => 'non_standard_port_number',

            'username' => 'root',
            'password' => 'sample@123',

            'database' => 'mydatabase',
            /*
             * If not using the default 'public' schema with the PostgreSQL driver
             * set it here.
             */
            //'schema' => 'myapp',

            /*
             * You can use a DSN string to set the entire configuration
             */
            'url' => env('DATABASE_URL', null),
        ],
  
     //...

//...

You can pass host, username, password and database.

Successfully, you are now connected with the database.

Create Migration

Open project into terminal and run this command –

$ bin/cake bake migration CreateEmployees

It will create a file 20220324164252_CreateEmployees.php inside /config/Migrations folder. Open migration file and write this following code into it. The code is all about for the schema of employees table.

<?php
declare(strict_types=1);

use Migrations\AbstractMigration;

class CreateEmployees extends AbstractMigration
{
    public function change()
    {
        $table = $this->table('employees');

        // name
        $table->addColumn("name", "string", [
            "limit" => 50,
            "null" => false
        ]);

        // email
        $table->addColumn("email", "string", [
            "limit" => 50,
            "null" => false
        ]);

        // designation
        $table->addColumn("designation", "string", [
            "limit" => 100,
            "null" => false
        ]);

        // gender
        $table->addColumn("gender", "enum", [
            "values" => ["male", "female", "other"]
        ]);

        // created_at
        $table->addColumn("created_at", "timestamp", [
            "default" => 'CURRENT_TIMESTAMP'
        ]);

        $table->create();
    }
}

Run Migration

Back to terminal and run this command.

$ bin/cake migrations migrate

It will create table “employees” inside database.

Create Model & Entity

Next,

We will create model and entity. Back to terminal and run this command.

$ bin/cake bake model Employees --no-validation --no-rules

It will create model file EmployeesTable.php inside /src/Model/Table folder. Also we should see the entity file Employee.php inside /src/Model/Entity folder.

Routes Setup

Open routes.php file from /config folder. Add these API routes into it.

//...

// API routes
$routes->prefix("Api", function (RouteBuilder $builder) {

    $builder->setExtensions(["json", "xml"]);

    $builder->connect("/add-employee", ["controller" => "Employee", "action" => "addEmployee"]);

    $builder->connect("/list-employees", ["controller" => "Employee", "action" => "listEmployees"]);

    $builder->connect("/update-employee/{id}", ["controller" => "Employee", "action" => "updateEmployee"])->setPass(["id"]);

    $builder->connect("/delete-employee/{id}", ["controller" => "Employee", "action" => "deleteEmployee"])->setPass(["id"]);
});

//...

API URLs will be accessible in two extension as .json and .xml. The structure of API routes will look like this when you call.

/add-employee.json OR /add-employee.xml

/list-employees.json OR /list-employees.xml

/update-employee/2.json OR /update-employee/2.xml

/delete-employee/2.json OR /delete-employee/2.xml

Create Controller

Open project into terminal and run this command into it.

$ bin/cake bake controller Employee --no-actions --prefix Api

It will create EmployeeController.php file inside /src/Controller/Api folder. Open controller file and write this code into it.

<?php

declare(strict_types=1);

namespace App\Controller\Api;

use App\Controller\AppController;

class EmployeeController extends AppController
{
    public function initialize(): void
    {
        parent::initialize();

        $this->loadModel("Employees");
    }

    // Add employee api
    public function addEmployee()
    {
        $this->request->allowMethod(["post"]);

        // form data
        $formData = $this->request->getData();

        // email address check rules
        $empData = $this->Employees->find()->where([
            "email" => $formData['email']
        ])->first();

        if (!empty($empData)) {
            // already exists
            $status = false;
            $message = "Email address already exists";
        } else {
            // insert new employee
            $empObject = $this->Employees->newEmptyEntity();

            $empObject = $this->Employees->patchEntity($empObject, $formData);

            if ($this->Employees->save($empObject)) {
                // success response
                $status = true;
                $message = "Employee has been created";
            } else {
                // error response
                $status = false;
                $message = "Failed to create employee";
            }
        }

        $this->set([
            "status" => $status,
            "message" => $message
        ]);

        $this->viewBuilder()->setOption("serialize", ["status", "message"]);
    }

    // List employees api
    public function listEmployees()
    {
        $this->request->allowMethod(["get"]);

        $employees = $this->Employees->find()->toList();

        $this->set([
            "status" => true,
            "message" => "Employee list",
            "data" => $employees
        ]);

        $this->viewBuilder()->setOption("serialize", ["status", "message", "data"]);
    }

    // Update employee
    public function updateEmployee()
    {
        $this->request->allowMethod(["put", "post"]);

        $emp_id = $this->request->getParam("id");

        $employeeInfo = $this->request->getData();

        // employee check
        $employee = $this->Employees->get($emp_id);

        if (!empty($employee)) {
            // employees exists
            $employee = $this->Employees->patchEntity($employee, $employeeInfo);

            if ($this->Employees->save($employee)) {
                // success response
                $status = true;
                $message = "Employee has been updated";
            } else {
                // error response
                $status = false;
                $message = "Failed to update employee";
            }
        } else {
            // employee not found
            $status = false;
            $message = "Employee Not Found";
        }

        $this->set([
            "status" => $status,
            "message" => $message
        ]);

        $this->viewBuilder()->setOption("serialize", ["status", "message"]);
    }

    // Delete employee api
    public function deleteEmployee()
    {
        $this->request->allowMethod(["delete"]);
        
        $emp_id = $this->request->getParam("id");

        $employee = $this->Employees->get($emp_id);

        if (!empty($employee)) {
            // employee found
            if ($this->Employees->delete($employee)) {
                // employee deleted
                $status = true;
                $message = "Employee has been deleted";
            } else {
                // failed to delete
                $status = false;
                $message = "Failed to delete employee";
            }
        } else {
            // not found
            $status = false;
            $message = "Employee doesn't exists";
        }

        $this->set([
            "status" => $status,
            "message" => $message
        ]);

        $this->viewBuilder()->setOption("serialize", ["status", "message"]);
    }
}

Above controller class contains these methods –

  • initialize() Method loads Employees model class to use.
  • addEmployee() Method is for add employee and also before creating any new employee it is checking for email existence.
  • listEmployees() Method to list all employees
  • updateEmployee() Method to accept the employee ID and on the behalf of that it will update the existing information of an employee
  • deleteEmployee() It will delete an employee on basis of employee ID.

Disable CSRF Token

When we submit a cakephp form, it needs a CSRF token should be submitted with form submission request.

We are not interested to send CSRF token with form data. To disable it, Open Application.php from /src folder.

Remove these lines of code from middleware() method.

->add(new CsrfProtectionMiddleware([
    'httponly' => true,
]))

Application Testing

Open terminal and run this command to start development server.

$ bin/cake server

Open Postman to test REST APIs

Add Employee API

URL: http://localhost:8765/api/add-employee.json

Method: POST

Headers:

Accept:application/json
Content-Type:application/json

Body

{
	"name": "Sanjay Kumar",
	"email": "sanjaytest@mail.com",
	"designation": "PHP Developer",
	"gender": "male"
}

Output

List Employee API

URL: http://localhost:8765/api/list-employees.json

Method: GET

Headers:

Accept:application/json
Content-Type:application/json

Output:

Update Employee API

URL: http://localhost:8765/api/update-employee/1.json

Method: PUT

Headers:

Accept:application/json
Content-Type:application/json

Body

{
	"name": "Vikas Singh",
	"email": "vikastest@mail.com",
	"designation": "PHP Developer",
	"gender": "male"
}

Output

Delete Employee API

URL: http://localhost:8765/api/delete-employee/1.json

Method: DELETE

Headers:

Accept:application/json
Content-Type:application/json

Output:

We hope this article helped you to learn about CakePHP 4 How To Create CRUD REST API Tutorial Example in a very detailed way.

Online Web Tutor invites you to try Skillshike! Learn CakePHP, Laravel, CodeIgniter, Node Js, MySQL, Authentication, RESTful Web Services, etc into a depth level. Master the Coding Skills to Become an Expert in PHP Web Development. So, Search your favourite course and enroll now.

If you liked this article, then please subscribe to our YouTube Channel for PHP & it’s framework, WordPress, Node Js video tutorials. You can also find us on Twitter and Facebook.