-
Notifications
You must be signed in to change notification settings - Fork 63
2 rest api
#Bake backend REST API
I will reuse the database scheme of the CakePHP Blog tutorial.
Execute the following scripts to create a posts
table in your MySQL database, it also initialized the sample data.
/* First, create our posts table: */ CREATE TABLE posts ( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, title VARCHAR(50), body TEXT, created DATETIME DEFAULT NULL, modified DATETIME DEFAULT NULL ); /* Then insert some posts for testing: */ INSERT INTO posts (title,body,created) VALUES (’The title’, ’This is the post body.’, NOW()); INSERT INTO posts (title,body,created) VALUES (’A title once again’, ’And the post body follows.’, NOW()); INSERT INTO posts (title,body,created) VALUES (’Title strikes back’, ’This is really exciting! Not.’, NOW());
You can use MySQL client command line or MySQL Workbench(GUI) to complete this work.
Use bake
command line to generate model, controller for posts
table.
Vendor\pear-pear.cakephp.org\CakePHP\bin\cake.bat bake model Post
This command will generate a Model named Post
, it is under Model folder.
class Post extends AppModel { }
A model class must extend AppModel
which is a base class in the same folder, it is a place holder to customize common model hooks for all models in your application.
Use the following command to generate the posts controller.
Vendor\pear-pear.cakephp.org\CakePHP\bin\cake.bat bake controller posts
After it is executed and a file named PostsController.php will be generated in the Controller folder.
class PostsController extends AppController { public $scaffold; }
A controller class must extends AppController
, it is similar with the AppModel
. It is a place holder to customize the common controller lifecycle. All controllers in this application should extend AppController
The naming of table, model and controller follows the CakePHP naming convention.
You can also use cake bake all
to generate model, controller and view together. Of course, I do not need the view in this project, as described formerly, we will use AngularJS to build the frontend UI.
If you want to generate the codes interactively, ignore the name argument in the bake
command line.
For example,
Vendor\pear-pear.cakephp.org\CakePHP\bin\cake.bat bake controller
The bake
command will guide you to generate the PostsController
step by step, you can also generate the CRUD dummy codes instead of the default public $scaffold;
.
But the generated CRUD methods are ready for web pages, we will replace them with REST resource operations.
Open PostsController
and add the basic CRUD methods for model Post
.
public function index() { $posts = $this->Post->find('all'); $this->set(array( 'posts' => $posts, '_serialize' => array('posts') )); } public function view($id) { $post = $this->Post->findById($id); $this->set(array( 'post' => $post, '_serialize' => array('post') )); } public function add() { //$this->Post->id = $id; if ($this->Post->save($this->request->data)) { $message = array( 'text' => __('Saved'), 'type' => 'success' ); } else { $message = array( 'text' => __('Error'), 'type' => 'error' ); } $this->set(array( 'message' => $message, '_serialize' => array('message') )); } public function edit($id) { $this->Post->id = $id; if ($this->Post->save($this->request->data)) { $message = array( 'text' => __('Saved'), 'type' => 'success' ); } else { $message = array( 'text' => __('Error'), 'type' => 'error' ); } $this->set(array( 'message' => $message, '_serialize' => array('message') )); } public function delete($id) { if ($this->Post->delete($id)) { $message = array( 'text' => __('Deleted'), 'type' => 'success' ); } else { $message = array( 'text' => __('Error'), 'type' => 'error' ); } $this->set(array( 'message' => $message, '_serialize' => array('message') )); }
As you see, we must use _serialize
as the key of the associated array of the returned result.
Besides these, RequestHandler
component is required to process the REST resource request.
public $components = array('RequestHandler');
Open Config/routes.php, add the following lines before require CAKE . 'Config' . DS . 'routes.php';
.
Router::mapResources("posts"); Router::parseExtensions();
Router::mapResources
indicates which posts will be mapped as REST resources, and Router::parseExtensions
will parse the resources according to the file extension, XML and JSON are native supported.
Now navigate to http://localhost/posts.json, you will get the following JSON string in browser.
{ "posts": [ { "Post": { "id": "1", "title": "The title", "body": "This is the post body.", "created": "2013-10-22 16:10:53", "modified": null } }, { "Post": { "id": "2", "title": "A title once again", "body": "And the post body follows.", "created": "2013-10-22 16:10:53", "modified": null } }, { "Post": { "id": "3", "title": "Title strikes back", "body": "This is really exciting! Not.", "created": "2013-10-22 16:10:53", "modified": null } } ] }
When access http://localhost/posts.json, it will call the index
method of PostsController
, and render the data as JSON format. CakePHP follows the following rules to map REST resources to controllers. Here I use PostsController as an example to describe it.
URL | HTTP Method | PostsController method | Description |
/posts.json | GET | index | Get the list of Posts |
/posts.json | POST | add | Create a new Post |
/posts/:id.json | GET | view | Get the details of a Post |
/posts/:id.json | PUT | edit | Update a Post by id |
/posts/:id.json | DELETE | delete | Delete a Post by id |
If you want to change the resource mapping, you can define your rules via Router::resourceMap
in Config/routes.php.
Router::resourceMap(array( array(’action’ => ’index’, ’method’ => ’GET’, ’id’ => false), array(’action’ => ’view’, ’method’ => ’GET’, ’id’ => true), array(’action’ => ’add’, ’method’ => ’POST’, ’id’ => false), array(’action’ => ’edit’, ’method’ => ’PUT’, ’id’ => true), array(’action’ => ’delete’, ’method’ => ’DELETE’, ’id’ => true), array(’action’ => ’update’, ’method’ => ’POST’, ’id’ => true) ));
Alternatively, you can use Router::connect
to define the route rule manually.
##Summary
CakePHP REST API producing is simple and stupid, the only thing make me a little incompatible is the produced JSON data, the JSON data structure is a little tedious.