- Published on
How to use a CakePHP 3 REST API
In this follow-up post to How to build a CakePHP 3 REST API in minutes we explore the inner workings of our new API.
We will address the most common use cases by:
- Adding some tasty cocktail data to our application (already listening at
http://cake3api.app
) - Accessing the cocktail resources through our API using the:
- Index action (GET)
- View action (GET)
- Add action (POST)
- Edit/update action (PUT)
- Delete action (DELETE)
- Configuring Pagination
- Testing Querystring Parameters
Before We Begin
This is part two of the CakePHP 3 REST API tutorial series:
- How to build a CakePHP 3 REST API in minutes
- How to use a CakePHP 3 REST API
- How to prefix route a CakePHP 3 REST API
- How to add JWT Authentication to a CakePHP 3 REST API
- How to make your CakePHP 3 API produce JSON API
- How to use a CakePHP API as the data backend for Ember in 30 minutes
Before starting this tutorial either:
- Complete the previous post
- Start fresh by using these end-state application sources, composer installing and running the database migration
1. Adding The Cocktails
Populate the database
Download this CakePHP database migration file to your config/Migrations
directory.
Now run the following command inside your application's root directory to create and popuplate the cocktails
table:
bin/cake migrations migrate
Create the controller
Create a new file named src/Controller/CocktailsController.php
with the following content:
<?php
namespace App\Controller;
use App\Controller\AppController;
class CocktailsController extends AppController
{
public $paginate = [
'page' => 1,
'limit' => 10,
'maxLimit' => 100,
'fields' => [
'id', 'name', 'description'
],
'sortWhitelist' => [
'id', 'name', 'description'
]
];
}
Generate the entity and table
Generate the required entity and model by running the following command inside your application's root directory:
bin/cake bake model Cocktails
Create html views
Even though your API does not need/use views to output JSON and XML (that part is handled for you by the CRUD plugin) we will still generate some html views for easy browsing the cocktails and to prepare for the follow-up tutorials.
Generate the views by by running the following command inside your application's root directory:
bin/cake bake template Cocktails
If things went well browsing to http://cake3api.app/cocktails
should display something similar to:
2. Accessing API Resources
Your API supports accessing resources with or without extensions and we will test both where applicable.
If you don't have a client capable of testing Request Headers you might consider using:
- Postman
- The RESTClient plugin for Firefox
- The Cocoa REST Client if you are on a Mac
Note: for brevity we will only test JSON responses.
Index action (GET)
Retrieve the first JSON page with cocktails from your API by either:
- Retrieving directly from
http://cake3api.app/cocktails.json
- Querying
http://cake3api.app/cocktails
using:- HTTP Method
GET
- Accept Header
application/json
- HTTP Method
Should return Status Code 200 (Success) with a JSON response body similar to:
{
"success": true,
"data": [
{
"id": 1,
"name": "Cosmopolitan",
"description": "Vodka based"
},
{
"id": 2,
"name": "Margarita",
"description": "Tequila based"
},
{
"id": 3,
"name": "Mojito",
"description": "Rum based"
}
],
"pagination": {
"page_count": 5,
"current_page": 1,
"has_next_page": true,
"has_prev_page": false,
"count": 21,
"limit": null
}
}
View action (GET)
Specify a record id to retrieve JSON details for a single cocktail by either:
- Retrieving directly from e.g.
http://cake3api.app/cocktails/5.json
- Querying
http://cake3api.app/cocktails/5
using:- HTTP Method
GET
- Accept Header
application/json
- HTTP Method
Should return Status Code 200 (Success) with a JSON response body similar to:
{
"success": true,
"data": {
"id": 5,
"name": "Caipirinha",
"description": "Rum based",
"created": "2015-04-11T09:33:37+0000",
"modified": null
}
}
Add action (POST)
Create a new cocktail record by posting JSON data to your API using:
- The index URL
http://cake3api.app/cocktails
- HTTP Method
POST
- Accept Header
application/json
- Content-Type Header
application/json
- Body data in (absolutely) correct JSON format
Should return Status Code 201 (Created) with a JSON response body containing the id of the created cocktail similar to:
{
"success": true,
"data": {
"id": 22
}
}
Edit/Update action (PUT)
Change an existing cocktail by posting JSON data to our API using:
- The view URL for the specific recipe, e.g.
http://cake3api.app/cocktails/5
- HTTP Method
PUT
- Accept Header
application/json
- Content-Type Header
application/json
- Partial or full body data in (absolutely) correct JSON format
Should return Status Code 200 (Success) with a JSON response body similar to:
{
"success": true,
"data": []
}
Delete action (DELETE)
Delete an existing cocktail through your API by using:
- The view URL for the specific cocktail, e.g.
http://cake3api.app/cocktails/5
- HTTP Method
DELETE
- Accept Header
application/json
Should return Status Code 200 (Success) on success with a JSON response body similar to:
{
"success": true,
"data": []
}
3. Configuring Pagination
The Paginator settings in src/Controller/CocktailsController.php
are used by your API to format the outputted JSON/XML. Let's change some of the settings below in preparation for querystring parameter testing.
public $paginate = [
'page' => 1,
'limit' => 10,
'maxLimit' => 100,
'fields' => [
'id', 'name', 'description'
],
'sortWhitelist' => [
'id', 'name', 'description'
]
];
Show all cocktail details/fields
To show all record details completely remove the fields
array (used earlier to keep the JSON output examples readable).
Querying http://cake3api.app/cocktails.json?limit=2
should now produce more detailed JSON similar to:
{
"success": true,
"data": [
{
"id": 1,
"name": "Cosmopolitan",
"description": "Vodka based",
"created": "2015-04-10T15:56:23+0000",
"modified": null
},
{
"id": 2,
"name": "Margarita",
"description": "Tequila based",
"created": "2015-04-10T15:59:39+0000",
"modified": null
}
],
"pagination": {
"page_count": 11,
"current_page": 1,
"has_next_page": true,
"has_prev_page": false,
"count": 21,
"limit": 2
}
}
Show less cocktails per page
To show only show 5 cocktails per page change limit => 10
to limit => 5
.
Set maximum number of cocktails per page
To never show more than 15 cocktails change 'maxLimit' => 100
to 'maxLimit' => 15
.
Prevent sorting by description
To prevent users from sorting by the description field remove description
from the sortWhitelist
array.
Default page
Do NOT change the default page
used for the index resultset to prevent frustrating further tests.
4. Testing Querystring Parameters
Your API comes with support for querystring parameters that clients can use to manipulate the output produced by your API.
Limiting results
Clients can use the limit
parameter to manipulate the number of records returned by your API.
To verify the parameter works as expected query http://cake3api.app/cocktails.json?limit=3
.
The result should list three cocktails instead of (the now default) five.
Rate limiting
To verify your API is respecting the maxLimit
Paginator setting query http://cake3api.app/cocktails.json?limit=20
.
The result should only list 15 cocktails.
Sorting by field
Clients can use the sort
parameter to specify which field should be used to sort the results produced by your API.
To verify the parameter is working as expected query http://cake3api.app/cocktails.json?sort=name
.
The results should be sorted by cocktail name.
Sorting ascending/descending
Clients can use the direction
parameter in combination with the sort
parameter to specify the direction in which results are sorted by your API (either asc
or desc
).
To verify the parameter is working as expected query http://cake3api.app/cocktails.json?sort=name&direction=desc
.
The results should be reverse-sorted by cocktail name.
Sort whitelist
To verify your API is respecting the sortWhitelist
Paginator setting query http://cake3api.app/cocktails.json?sort=description
.
The result should show the default (non-sorted) index results since we removed description
from the sortWhitelist array.
Additional reading
- Follow-up tutorial "How to prefix route a CakePHP3 REST API"
- Git repository with working end state application produced by this tutorial
- CakePHP pagination documentation
- The CakePHP 3 Book and CakePHP 3 API documentation