Build a REST API using CakePHP 2.x in 3 Minutes
CakePHP is a PHP framework that makes building web applications faster and simpler. It possesses a powerful scaffolding system that reduces development time when building simple or complex systems.
CakePHP emerged around 2005, and was developed by Larry Masters. It currently has over 7,000 stars on its Github repo.
Since this tutorial is not about getting started with CakePHP, I’ll assume you are familiar with setting up a CakePHP 2.x app. Let’s get started.
Requirements
- CakePHP 2.x, preferably verison 2.8
- MySQL Database
- Postman. For testing our API.
We are going to learn how to create a basic REST API in JSON format. A typical JSON format looks like this:
{
"field":"value"
}
We will be creating an API to create, read, update, and delete products. As you may know, CakePHP database table naming conventions is pluralized. For this tutorial, we will assume our table to be “products”. Go ahead and create a products table in MySQL using the syntax below:
CREATE TABLE `products` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`description` varchar(255) DEFAULT NULL,
`created` datetime DEFAULT NULL,
`modified` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
In your project directory, go to app/Controllers. Create a new file called ProductsController.php. Open up the file and paste the code below:
<?php
App::uses('AppController','Controller');
class ProductsController extends AppController{
}
?>
What we simply did here was state that our ProductsController inherits the main AppController. Now let’s insert our first API which would be the create or add new product API.
API to create new record
public function add(){
$this->layout = false;
$response = array('status'=>'failed', 'message'=>'HTTP method not allowed');
if($this->request->is('post')){
//get data from request object
$data = $this->request->input('json_decode', true);
if(empty($data)){
$data = $this->request->data;
}
//response if post data or form data was not passed
$response = array('status'=>'failed', 'message'=>'Please provide form data');
if(!empty($data)){
//call the model's save function
if($this->Product->save($data)){
//return success
$response = array('status'=>'success','message'=>'Product successfully created');
} else{
$response = array('status'=>'failed', 'message'=>'Failed to save data');
}
}
}
$this->response->type('application/json');
$this->response->body(json_encode($response));
return $this->response->send();
}
Explaining the code above, we first informed CakePHP not to use a layout for this function. We did this so as to only receive our JSON encoded response. Then we set a default response status as failed. Next, we checked if the request header is POST. Since we are dealing with JSON data, the method to receive JSON data in CakePHP is to use $this->request->input('json_decode', true)
.
By default, your content-type encoding should be application/json
. Should that not be the case, we need to handle such scenario. To do this, we check if the data in $this->request->input('json_decode', true)
is empty. If it is, we retrieve the post data by calling $this->request->data
.
Finally, we call the save function on the Product Model. We make a check if the data was successfully saved or not. And that’s it. You have created an API to create record in a MySQL database.
Go to app/View
and create a Products folder. Inside this folder, create an empty file add.ctp If you don’t do this, your response will return a missing view error.
Open your Postman application. On the new tab, paste your domain URL. If you are working from localhost, make sure your server is open, and copy the path to your project. In my case, it is http://localhost/apitest
. We need to make sure our path links to the add function in the products controller. To do this, just add /products/add to your domain URL above. Using my test above, my full path will be http://localhost/apitest/products/add
. Paste this in URL section on your Postman. Change the request header to POST. Navigate to body tab, and then section ‘raw’. Click the dropdown box and select JSON(application/json). Paste the code below:
{
"name":"Sample test product",
"description":"Sample description for sample test product"
}
You should get a success response. See image below:
API to read record
The next action is to read a record and output it as JSON. To do this, see code below:
public function view($id = null){
$this->layout = false;
//set default response
$response = array('status'=>'failed', 'message'=>'Failed to process request');
//check if ID was passed
if(!empty($id)){
//find data by ID
$result = $this->Product->findById($id);
if(!empty($result)){
$response = array('status'=>'success','data'=>$result);
} else {
$response['message'] = 'Found no matching data';
}
} else {
$response['message'] = "Please provide ID";
}
$this->response->type('application/json');
$this->response->body(json_encode($response));
return $this->response->send();
}
Create a file view.ctp in the app/View/Products folder. The URL requires an ID parameter passed. In this case, we will pass the ID of the last product we added to the URL. In this case, we didn’t handle the request type. We only check if an ID is set, if so, we look it up in the database and return the result as JSON.
Using the test URL above, our URL should look like this: http://localhost/apitest/products/view/1, where 1 is the Product ID. Now run this in your Postman. See result below:
API to update record
Create file called update.ctp in products folder. Paste the code below in the Products Controller.
public function update(){
//set layout as false to unset default CakePHP layout. This is to prevent our JSON response from mixing with HTML
$this->layout = false;
//set default response
$response = array('status'=>'failed', 'message'=>'HTTP method not allowed');
//check if HTTP method is PUT
if($this->request->is('put')){
//get data from request object
$data = $this->request->input('json_decode', true);
if(empty($data)){
$data = $this->request->data;
}
//check if product ID was provided
if(!empty($data['id'])){
//set the product ID to update
$this->Product->id = $data['id'];
if($this->Product->save($data)){
$response = array('status'=>'success','message'=>'Product successfully updated');
} else {
$response['message'] = "Failed to update product";
}
} else {
$response['message'] = 'Please provide product ID';
}
}
$this->response->type('application/json');
$this->response->body(json_encode($response));
return $this->response->send();
}
API to delete record
public function ajax_delete(){
$this->layout = false;
//set default response
$response = array('status'=>'failed', 'message'=>'HTTP method not allowed');
//check if HTTP method is DELETE
if($this->request->is('delete')){
//get data from request object
$data = $this->request->input('json_decode', true);
if(empty($data)){
$data = $this->request->data;
}
//check if product ID was provided
if(!empty($data['id'])){
if($this->Product->delete($id, true)){
$response = array('status'=>'success','message'=>'Product successfully deleted');
}
}
}
$this->response->type('application/json');
$this->response->body(json_encode($response));
return $this->response->send();
}
Yippy! We have successfully created an API that performs CRUD functionalities. Clap for yourself 👍👍🤛🏾
Thank you for following through. Our next tutorial will teach how to consume your CakePHP API using jQuery. Till then, keep learning!
P.S: This article was first published on my medium post: https://medium.com/@abeltolu/build-a-rest-api-using-cakephp-2-x-in-3-minutes-1abe842ad7a1