You are on page 1of 6

CakePHP

Downloads

Documentation

Community

Services

Search

Cookbook 2.x

Development

Welcome

REST

Installation
Getting Started
CakePHP Overview
Controllers

en

2.x Book

Improve this Doc

Manynewerapplicationprogrammersarerealizingtheneedtoopentheircore
functionalitytoagreateraudience.Providingeasy,unfetteredaccesstoyourcoreAPI
canhelpgetyourplatformaccepted,andallowsformashupsandeasyintegrationwith
othersystems.

Views
Models
Core Libraries
Plugins
Shells, Tasks & Console
Tools
Development
Configuration
Routing
Sessions
Exceptions
Error Handling
Debugging
Testing
REST

Whileothersolutionsexist,RESTisagreatwaytoprovideeasyaccesstothelogic
youvecreatedinyourapplication.Itssimple,usuallyXMLbased(weretalkingsimple
XML,nothinglikeaSOAPenvelope),anddependsonHTTPheadersfordirection.
ExposinganAPIviaRESTinCakePHPissimple.

The Simple Setup


ThefastestwaytogetupandrunningwithRESTistoaddafewlinestoyour
routes.phpfile,foundinapp/Config.TheRouterobjectfeaturesamethodcalled
mapResources(),thatisusedtosetupanumberofdefaultroutesforRESTaccessto
yourcontrollers.Makesure mapResources()comesbefore require CAKE .
'Config' . DS . 'routes.php';andotherrouteswhichwouldoverridetheroutes.If
wewantedtoallowRESTaccesstoarecipedatabase,weddosomethinglikethis:
//In app/Config/routes.php...
Router::mapResources('recipes');
Router::parseExtensions();

Dispatcher Filters
Deployment
Tutorials & Examples
Contributing
Appendices

Page
contents
REST
The Simple Setup
Accepting Input in
Other Formats

ThefirstlinesetsupanumberofdefaultroutesforeasyRESTaccesswhile
parseExtensions()methodspecifiesthedesiredresultformat(e.g.xml,json,rss).
TheseroutesareHTTPRequestMethodsensitive.
HTTP
format

URLformat

Controlleractioninvoked

GET

/recipes.format

RecipesController::index()

GET

/recipes/123.format

RecipesController::view(123)

POST

/recipes.format

RecipesController::add()

POST

/recipes/123.format

RecipesController::edit(123)

PUT

/recipes/123.format

RecipesController::edit(123)

DELETE

/recipes/123.format

RecipesController::delete(123)

Other Formats
Modifying the
default REST routes
Custom REST
Routing

CakePHPsRouterclassusesanumberofdifferentindicatorstodetecttheHTTP
methodbeingused.Heretheyareinorderofpreference:
1.The_methodPOSTvariable
2.TheX_HTTP_METHOD_OVERRIDE
3.TheREQUEST_METHODheader
The_methodPOSTvariableishelpfulinusingabrowserasaRESTclient(oranything
elsethatcandoPOSTeasily).Justsetthevalueof_methodtothenameoftheHTTP
requestmethodyouwishtoemulate.
OncetherouterhasbeensetuptomapRESTrequeststocertaincontrolleractions,we
canmoveontocreatingthelogicinourcontrolleractions.Abasiccontrollermightlook
somethinglikethis:

// Controller/RecipesController.php

// Controller/RecipesController.php
class RecipesController extends AppController {
public $components = array('RequestHandler');
public function index() {
$recipes = $this->Recipe->find('all');
$this->set(array(
'recipes' => $recipes,
'_serialize' => array('recipes')
));
}
public function view($id) {
$recipe = $this->Recipe->findById($id);
$this->set(array(
'recipe' => $recipe,
'_serialize' => array('recipe')
));
}
public function add() {
$this->Recipe->create();
if ($this->Recipe->save($this->request->data)) {
$message = 'Saved';
} else {
$message = 'Error';
}
$this->set(array(
'message' => $message,
'_serialize' => array('message')
));
}
public function edit($id) {
$this->Recipe->id = $id;
if ($this->Recipe->save($this->request->data)) {
$message = 'Saved';
} else {
$message = 'Error';
}
$this->set(array(
'message' => $message,
'_serialize' => array('message')
));
}

public function delete($id) {


if ($this->Recipe->delete($id)) {
$message = 'Deleted';
} else {
$message = 'Error';
}
$this->set(array(
'message' => $message,
'_serialize' => array('message')
));
}

Sinceweveaddedacallto Router::parseExtensions()
(routing.html#Router::parseExtensions),theCakePHProuterisalreadyprimedtoserve

(routing.html#Router::parseExtensions),theCakePHProuterisalreadyprimedtoserve
updifferentviewsbasedondifferentkindsofrequests.SinceweredealingwithREST
requests,wellbemakingXMLviews.YoucanalsoeasilymakeJSONviewsusing
CakePHPsbuiltinJSONandXMLviews(../views/jsonandxmlviews.html).Byusing
thebuiltin XmlView(../views/jsonandxmlviews.html#XmlView)wecandefinea
_serializeviewvariable.Thisspecialviewvariableisusedtodefinewhichview
variables XmlViewshouldserializeintoXML.
IfwewantedtomodifythedatabeforeitisconvertedintoXMLweshouldnotdefinethe
_serializeviewvariable,andinsteaduseviewfiles.WeplacetheRESTviewsforour
RecipesControllerinside app/View/recipes/xml.Wecanalsousethe Xml(../core
utilitylibraries/xml.html#Xml)forquickandeasyXMLoutputinthoseviews.Hereswhat
ourindexviewmightlooklike:
// app/View/Recipes/xml/index.ctp
// Do some formatting and manipulation on
// the $recipes array.
$xml = Xml::fromArray(array('response' => $recipes));
echo $xml->asXML();

WhenservingupaspecificcontenttypeusingparseExtensions(),CakePHP
automaticallylooksforaviewhelperthatmatchesthetype.SincewereusingXMLas
thecontenttype,thereisnobuiltinhelper,howeverifyouweretocreateoneitwould
automaticallybeloadedforouruseinthoseviews.
TherenderedXMLwillenduplookingsomethinglikethis:
<recipes>
<recipe id="234" created="2008-06-13" modified="2008-06-14">
<author id="23423" first_name="Billy" last_name="Bob"></author
<comment id="245" body="Yummy yummmy"></comment>
</recipe>
<recipe id="3247" created="2008-06-15" modified="2008-06-15">
<author id="625" first_name="Nate" last_name="Johnson"></author
<comment id="654" body="This is a comment for this tasty dish."
</recipe>
</recipes>

Creatingthelogicfortheeditactionisabittrickier,butnotbymuch.Sinceyoure
providinganAPIthatoutputsXML,itsanaturalchoicetoreceiveXMLasinput.Notto
worry,the RequestHandlerand Router(routing.html#Router)classesmakethings
mucheasier.IfaPOSTorPUTrequesthasanXMLcontenttype,thentheinputisrun
throughCakePHPs Xml(../coreutilitylibraries/xml.html#Xml)class,andthearray
representationofthedataisassignedto$this>request>data.Becauseofthisfeature,
handlingXMLandPOSTdatainparallelisseamless:nochangesarerequiredtothe
controllerormodelcode.Everythingyouneedshouldendupin $this->request>data.

Accepting Input in Other Formats


TypicallyRESTapplicationsnotonlyoutputcontentinalternatedataformats,butalso
acceptdataindifferentformats.InCakePHP,the RequestHandlerComponent(../core
libraries/components/requesthandling.html#RequestHandlerComponent)helps

libraries/components/requesthandling.html#RequestHandlerComponent)helps
facilitatethis.Bydefault,itwilldecodeanyincomingJSON/XMLinputdatafor
POST/PUTrequestsandsupplythearrayversionofthatdatain$this>request>data.
Youcanalsowireinadditionaldeserializersforalternateformatsifyouneedthem,
using RequestHandler::addInputType().

Modifying the default REST routes


Newinversion2.1.

IfthedefaultRESTroutesdontworkforyourapplication,youcanmodifythemusing
Router::resourceMap().Thismethodallowsyoutosetthedefaultroutesthatgetset
with Router::mapResources()(routing.html#Router::mapResources).Whenusingthis
methodyouneedtosetallthedefaultsyouwanttouse:
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)
));

Byoverwritingthedefaultresourcemap,futurecallsto mapResources()willusethe
newvalues.

Custom REST Routing


Ifthedefaultroutescreatedby Router::mapResources()
(routing.html#Router::mapResources)dontworkforyou,usethe Router::connect()
(routing.html#Router::connect)methodtodefineacustomsetofRESTroutes.The
connect()methodallowsyoutodefineanumberofdifferentoptionsforagivenURL.
SeethesectiononUsingAdditionalConditionsWhenMatchingRoutes
(routing.html#routeconditions)formoreinformation.
Newinversion2.5.

Youcanprovide connectOptionskeyinthe $optionsarrayfor


Router::mapResources()(routing.html#Router::mapResources)toprovidecustom
settingusedby Router::connect()(routing.html#Router::connect):

Router::mapResources('books', array(
'connectOptions' => array(
'routeClass' => 'ApiRoute',

));

'routeClass' => 'ApiRoute',

index|next|previous
Found an issue? Submit a correction on GitHub
[ documentation on how to contribute ]
Copyright2014,CakeSoftwareFoundation,Inc.LastupdatedonMay21,2016.Createdusing
Sphinx1.2.3.

You might also like