Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Building	
  a	
  REST	
  API	
  	
  

with	
  Zend	
  Framework	
  2	
  

January	
  17,	
  2014	
  
What	
  we’re	
  gonna	
  talk	
  about…	
  
Overview	
  of	
  REST	
  

Building	
  Your	
  API	
  

• 	
  What	
  is	
  ...
What	
  is	
  an	
  API?	
  
An	
  ApplicaIon	
  Program	
  Interface	
  (API)	
  is	
  a	
  set	
  of	
  rouInes,	
  
pro...
Code	
  and	
  Personal	
  Data	
  are	
  Secure	
  
Different	
  Types	
  of	
  APIs	
  
There	
  are	
  several	
  different	
  methods	
  for	
  building	
  an	
  API,	
  
ho...
An	
  Overview	
  of	
  RPC	
  
Remote	
  Procedure	
  Calls	
  work	
  in	
  some	
  instances,	
  but	
  as	
  an	
  
AP...
An	
  Overview	
  of	
  SOAP	
  
While	
  once	
  widely	
  popular,	
  SOAP	
  has	
  quickly	
  lost	
  ground	
  to	
  ...
SOAP	
  Sample	
  Request	
  
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
so...
SOAP	
  Sample	
  Response	
  
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
s...
An	
  Overview	
  of	
  REST	
  
REST	
  on	
  the	
  other	
  hand	
  has	
  gained	
  in	
  popularity	
  due	
  to	
  i...
REST	
  JSON	
  Sample	
  Request	
  
{"user":{"firstName":"John","lastName":"Smith","e
mail":"john.smith@pocahontas.com"}...
REST	
  vs.	
  SOAP	
  
REST	
  

SOAP	
  

•  Returns	
  data	
  

•  Exposes	
  operaIons/	
  method	
  calls	
  

•  Su...
Arguments	
  against	
  REST	
  
•  REST	
  APIs	
  are	
  difficult	
  to	
  build	
  and	
  maintain	
  
•  REST	
  is	
  ...
Arguments	
  against	
  REST	
  
•  REST	
  APIs	
  are	
  difficult	
  to	
  build	
  and	
  maintain	
  
Um,	
  we’re	
  g...
Arguments	
  against	
  REST	
  
•  REST	
  is	
  not	
  secure	
  (anyone	
  can	
  access	
  it)	
  
There	
  are	
  man...
Arguments	
  against	
  REST	
  
•  There	
  are	
  no	
  strict	
  standards	
  for	
  REST	
  APIs	
  
This	
  is	
  tru...
Arguments	
  against	
  REST	
  
•  REST	
  services	
  are	
  not	
  reliable	
  
REST	
  services	
  are	
  just	
  as	
...
A	
  Good	
  REST	
  API	
  Offers	
  
•  Generality	
  –	
  language	
  agnosIc	
  
•  Familiarity	
  –	
  developers	
  a...
REST	
  APIs	
  provide	
  a	
  concrete	
  barrier	
  
A	
  Good	
  REST	
  API	
  Uses	
  Explicit	
  HTTP	
  Verbs	
  

Create	
  –	
  POST	
  
Read	
  –	
  GET	
  
Update	
  ...
A	
  Good	
  REST	
  API	
  
Is	
  built	
  for	
  longevity	
  and	
  designed	
  
to	
  evolve…	
  
“	
  so#ware	
  design	
  on	
  the	
  scale	
  of	
  decades:	
  every	
  
detail	
  is	
  intended	
  to	
  promote	
  s...
A	
  Good	
  REST	
  API	
  Uses	
  
Hypermedia	
  
As	
  
The	
  
Engine	
  
Of	
  
ApplicaIon	
  
State	
  
A	
  Good	
  REST	
  API	
  Uses	
  
Hypermedia	
  
As	
  
The	
  
Engine	
  
Of	
  
ApplicaIon	
  
State	
  

HATEOAS	
  ...
A	
  Good	
  REST	
  API	
  Uses	
  
Hypermedia	
  
As	
  
The	
  
Engine	
  
Of	
  
ApplicaIon	
  
State	
  

In	
  order...
A	
  Good	
  REST	
  API	
  Uses	
  
Hypermedia	
  
ApplicaIon	
  
Language	
  

Hypermedia	
  ApplicaIon	
  Language	
  
...
Using	
  HATEOAS	
  
{"data":{"user":{"fname":"first","lname":"last"}},
"_links":{
"edit":{"href":"/api/user/id/1"},
"mess...
A	
  Good	
  REST	
  API	
  Uses	
  
Hypermedia	
  
As	
  
The	
  
Engine	
  
Of	
  
ApplicaIon	
  
State	
  

By	
  sendi...
Using	
  HATEOAS	
  
{"data":{"user":{"fname":"first","lname":"last"}},

"_links":{
"edit":{"href" : "/api/user/id/1"},

"...
Use	
  JSON	
  instead	
  of	
  XML	
  
•  Be`er	
  Language	
  Support	
  
	
  
•  Lightweight	
  (much	
  less	
  code	
...
Use	
  AuthenXcaXon	
  Tokens	
  
•  Users	
  should	
  be	
  provided	
  with	
  a	
  unique	
  
API	
  key/	
  idenIfier	...
Thro^le	
  API	
  Key	
  Usage	
  
Be	
  sure	
  to	
  place	
  limits	
  on	
  the	
  number	
  of	
  calls/	
  queries	
...
OAuth	
  Tokens	
  
Tokens	
  help	
  prevent	
  misuse	
  of	
  the	
  system	
  and	
  limit	
  
access	
  to	
  the	
  ...
Use	
  HTTP	
  Status	
  Codes	
  
Proper	
  use	
  of	
  HTTP	
  status	
  codes	
  give	
  your	
  users	
  immediate	
 ...
Use	
  HTTP	
  Status	
  Codes	
  
You	
  probably	
  shouldn’t	
  use	
  these…	
  
	
  
	
  

•  418	
  –	
  I’m	
  a	
 ...
Use	
  DescripXve	
  Error	
  Messages	
  
Error	
  messages	
  should	
  give	
  a	
  clear	
  descripIon	
  of	
  what	
...
Use	
  DescripXve	
  Error	
  Messages	
  
These	
  are	
  not	
  good	
  error	
  messages:	
  
	
  

•  Something	
  wen...
Use	
  DescripXve	
  Error	
  Messages	
  
Good	
  Error	
  Messages:	
  
	
  

•  The	
  AuthenIcaIon	
  token	
  is	
  n...
Remember!	
  
DO	
  NOT	
  BREAK	
  BACKWARDS	
  COMPATIBILITY.	
  	
  Make	
  
sure	
  whatever	
  updates	
  you	
  make...
Versioning	
  (ie:	
  /api/v2/…)	
  
For	
  this	
  reason	
  I	
  am	
  not	
  a	
  fan	
  of	
  “versioning”	
  your	
  ...
That’s	
  awesome!	
  	
  	
  
Now	
  let’s	
  write	
  	
  
some	
  code…	
  
Step	
  1	
  –	
  Install	
  ZF2	
  
On	
  the	
  chance	
  that	
  you	
  don’t	
  already	
  have	
  Zend	
  
Framework	...
Installing	
  ZF2	
  
1.	
  Create	
  directory	
  on	
  your	
  web	
  server	
  and	
  move	
  into	
  it	
  
mkdir apip...
Setup	
  the	
  View	
  JSON	
  Strategy	
  
Add	
  the	
  ViewJsonStrategy	
  to	
  the	
  strategies	
  array	
  within	...
Setup	
  the	
  Controller	
  
Add	
  the	
  UserController	
  to	
  the	
  invokables	
  array	
  within	
  controllers	
...
Sefng	
  up	
  Routes	
  
Add	
  routes	
  to	
  moduleApplicaIonconfigmodule.config.php	
  where	
  
“ApplicaIon”	
  is	
  ...
The	
  AbstractResgulController	
  
Zend	
  Framework	
  2	
  comes	
  with	
  an	
  abstract	
  controller	
  for	
  
cre...
The	
  AbstractResgulController	
  
The	
  abstract	
  controller	
  comes	
  with	
  the	
  following	
  methods,	
  
all...
Sefng	
  up	
  the	
  User	
  Controller	
  
Extending	
  the	
  AbstractRestulController	
  we	
  can	
  setup	
  
module...
Sefng	
  up	
  the	
  UserController	
  
<?php
namespace ApplicationController;
use ZendMvcControllerAbstractRestfulContro...
Setup	
  OpXons	
  
class UserController extends AbstractRestfulController
{
protected $collectionOptions = array('GET', '...
Returning	
  Available	
  OpXons	
  
public function options()
{
$response = $this->getResponse();
// If in Options Array,...
Adding	
  an	
  Event	
  Listener	
  
public function setEventManager(EventManagerInterface $events)
{
// events property ...
Add	
  Event	
  Listener	
  Method	
  
public function checkOptions($e)
{
if (in_array($e->getRequest()->getMethod(), $thi...
Add	
  AcXon	
  Methods	
  
public function create($data)
{
// get created service to handle user creation
// in this case...
Curl	
  –X	
  POST	
  Request	
  Response	
  
Add	
  AcXon	
  Methods	
  
public function update($id, $data)
{
// get created service to handle user updates
// in this ...
Add	
  AcXon	
  Methods	
  
public function deleteList()
{
$response = $this->getResponse();
$response->setStatusCode(400)...
Curl	
  –X	
  DELETE	
  Request	
  Response	
  
You	
  now	
  have	
  a	
  funcXonal	
  API!	
  
You	
  can	
  conInue	
  to	
  use	
  the	
  following	
  methods	
  (and...
Remember…	
  
You	
  will	
  want	
  to	
  add	
  more	
  features	
  including	
  OAuth	
  2	
  and	
  
thro`ling.	
  	
 ...
More	
  Resources	
  
You	
  can	
  learn	
  more	
  about	
  REST	
  APIs	
  and	
  Zend	
  Framework	
  
2	
  by	
  visi...
A	
  Final	
  Thought…	
  
A	
  good	
  API	
  is	
  harder	
  for	
  your	
  clients	
  to	
  
implement…	
  
…but	
  eas...
THANK YOU.
A big thank you to Constant Contact for
making this presentation possible
@mikegstowe
@ctct_api

visit	
  mikes...
Building a Rest API with Zend Framework 2
Upcoming SlideShare
Loading in …5
×

Building a Rest API with Zend Framework 2

62,137 views

Published on

This presentation covers building a Representational State Transfer (REST) API, starting off with a quick overview of what REST is, comparing it to other methods, using good practices, and building a simple API in Zend Framework 2 using the AbstractRestfulController as well as looking at and solving API related challenges.

Published in: Technology

Building a Rest API with Zend Framework 2

  1. 1. Building  a  REST  API     with  Zend  Framework  2   January  17,  2014  
  2. 2. What  we’re  gonna  talk  about…   Overview  of  REST   Building  Your  API   •   What  is  the  purpose  of  an  API   •   SeLng  up  Your  Routes   •   Different  API  Techniques   •   SeLng  up  Your  Controllers     •   The  REST  Methodology   •   Handling  Headers   •   Components  of  REST   •   Handling  JSON   •   Good  PracIces   •   Not  so  Good  PracIces   •   AuthenIcaIon  and  OAuth      
  3. 3. What  is  an  API?   An  ApplicaIon  Program  Interface  (API)  is  a  set  of  rouInes,   protocols,  and  tools  for  building  soRware  applicaIons.    A   good  API  makes  it  easier  to  develop  a  program  by  providing   all  the  building  blocks,  which  a  developer  can  then  use  to   put  the  blocks  together.1    Web  APIs  allow  the  transmission   of  data  and  acIons  across  different  web  applicaIons  and   sites  securely  and  through  a  language     agnosIc  interface.   1  definiIon  by  
  4. 4. Code  and  Personal  Data  are  Secure  
  5. 5. Different  Types  of  APIs   There  are  several  different  methods  for  building  an  API,   however  the  three  leading  methods  are  using   RepresentaIonal  State  Transfer  (REST),    Remote  Procedure   Calls  (RPC),  and    Simple  Object  Access    Protocol  (SOAP).  
  6. 6. An  Overview  of  RPC   Remote  Procedure  Calls  work  in  some  instances,  but  as  an   API  causes  problems  through  Ight  coupling  that:   •  Requires  clients  to  know  procedure  names   •  Has  specific  procedure  parameters  and  order   •  Requires  a  URI  per  method/  funcIon  (ie  create,  edit,   delete)  
  7. 7. An  Overview  of  SOAP   While  once  widely  popular,  SOAP  has  quickly  lost  ground  to   REST  based  APIs.    SOAP  based  APIs:   •  Exposes  operaIons/  method  calls   •  Larger  packets  of  data,  XML  based   •  All  calls  sent  through  POST   •  Can  be  stateless  or  stateful   •  WSDL  –  Web  Service  DefiniIons  
  8. 8. SOAP  Sample  Request   <?xml version="1.0"?> <soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope" soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> <soap:Body xmlns:m="http://www.example.org/stock"> <m:GetStockPrice> <m:StockName>IBM</m:StockName> </m:GetStockPrice> </soap:Body> </soap:Envelope> h`p://www.w3schools.com/soap/soap_example.asp  
  9. 9. SOAP  Sample  Response   <?xml version="1.0"?> <soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope" soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> <soap:Body xmlns:m="http://www.example.org/stock"> <m:GetStockPriceResponse> <m:Price>34.5</m:Price> </m:GetStockPriceResponse> </soap:Body> </soap:Envelope> h`p://www.w3schools.com/soap/soap_example.asp  
  10. 10. An  Overview  of  REST   REST  on  the  other  hand  has  gained  in  popularity  due  to  its   simplicity,  reduced  transfer  requirements,  and  usage  of  JSON.     REST:   •  Returns  data,  doesn’t  expose  methods   •  Supports  XML  and  JSON   •  Uses  explicit  HTTP  Verbs   •  Point  to  point  connecIons   •  Ajax  (JavaScript)  Friendly   •  Stateless  
  11. 11. REST  JSON  Sample  Request   {"user":{"firstName":"John","lastName":"Smith","e mail":"john.smith@pocahontas.com"}! REST  JSON  Sample  Response   {"user":{"firstName":"John","lastName":"Smith","e mail":"john.smith@pocahontas.com"},"_links":{"edi t":["href","http://www.mysite.com/api/user/1 0"],"message":["href","http://www.mysite.com/a pi/user/10/message"]}}!
  12. 12. REST  vs.  SOAP   REST   SOAP   •  Returns  data   •  Exposes  operaIons/  method  calls   •  Supports  XML  and  JSON   •  All  calls  sent  through  POST   •  Uses  CRUD/  HTTP  Verbs   •  Larger  packets  of  data,  XML  based   •  Point  to  point  connecIons   •  Can  be  stateless  or  stateful   •  Ajax  (JavaScript)  Friendly   •  WSDL  Support   •  Stateless       Advantage  goes  to…  
  13. 13. Arguments  against  REST   •  REST  APIs  are  difficult  to  build  and  maintain   •  REST  is  not  secure  (anyone  can  access  it)   •  There  are  no  strict  standards  for  REST  APIs   •  REST  services  are  not  reliable  
  14. 14. Arguments  against  REST   •  REST  APIs  are  difficult  to  build  and  maintain   Um,  we’re  going  to  build  one  in  thirty  minutes…    And  as   REST  has  gained  in  popularity  there  are  more  tools  to  help   keep  documentaIon  up  to  date.    As  long  as  basic  guidelines   are  followed  REST  APIs  can  be  maintained  and     provide  backwards  compaIbility.   Read  how  we  do  it  @   h`p://bit.ly/1cCEYjC  
  15. 15. Arguments  against  REST   •  REST  is  not  secure  (anyone  can  access  it)   There  are  many  precauIons  we  can  take  to  ensure  our   REST  API  only  serves  those  who  we  want  to  have  access   to  the  data,  including  OAuth  tokens  and  IP  restricIons.     However,  it’s  important  to  remember  that  like     anything,  JavaScript/  AJAX  should  only  be  used  to     make  calls  to  public  or  insensiIve  data.  
  16. 16. Arguments  against  REST   •  There  are  no  strict  standards  for  REST  APIs   This  is  true  as  there  is  no  governing  body  for  REST.     However,  we  will  be  going  over  some  general   guidelines  that  should  be  used  when  building  your   API  and  as  long  as  these  are  followed  your   API  should  be  totally  awesome.  
  17. 17. Arguments  against  REST   •  REST  services  are  not  reliable   REST  services  are  just  as  reliable  as  SOAP  APIs  when  the   proper  checks  are  implemented  on  the  client’s  side.     These  should  include  checking  the  request  headers   returned  by  CURL  requests.    For  this  reason  it  is   important  to  make  sure  you  are  using  the  correct   response  codes  and  giving  easy  to  understand     error  messages.  
  18. 18. A  Good  REST  API  Offers   •  Generality  –  language  agnosIc   •  Familiarity  –  developers  are  used  to  it   •  Scalability  –  can  grow  with  usage/  demand   •  SegmentaIon  –  secIons  can  be  updated  independently   •  Speed  –  low  data  transfer,  cacheable   •  Security  –  personal  data  remains  protected   •  EncapsulaIon  –  ability  to  send  data  as  objects  
  19. 19. REST  APIs  provide  a  concrete  barrier  
  20. 20. A  Good  REST  API  Uses  Explicit  HTTP  Verbs   Create  –  POST   Read  –  GET   Update  –  PUT   Delete  -­‐  DELETE  
  21. 21. A  Good  REST  API   Is  built  for  longevity  and  designed   to  evolve…  
  22. 22. “  so#ware  design  on  the  scale  of  decades:  every   detail  is  intended  to  promote  so#ware   longevity  and  independent  evolu8on.  Many  of   the  constraints  are  directly  opposed  to  short-­‐ term  efficiency.  Unfortunately,  people  are   fairly  good  at  short-­‐term  design,  and  usually   awful  at  long-­‐term  design  ”   -­‐  Dr.  Roy  Fielding  
  23. 23. A  Good  REST  API  Uses   Hypermedia   As   The   Engine   Of   ApplicaIon   State  
  24. 24. A  Good  REST  API  Uses   Hypermedia   As   The   Engine   Of   ApplicaIon   State   HATEOAS  relies  on  the  concept   that  applicaIons  will  change,   data  required  will  change,  and   paths  can  change.    However,   these  changes  should  not  effect   exisIng  clients.    Hypermedia  is   stressed  over  a  server   oriented  architecture.  
  25. 25. A  Good  REST  API  Uses   Hypermedia   As   The   Engine   Of   ApplicaIon   State   In  order  to  accommodate  these   changes  HATEOAS  not  only  sends   back  the  data  requested,  but  the   next  possible  acIons  as  urls,  this   allows  the  client’s  applicaIon  to   be  dynamic  while  accommodaIng   any  updates  to  the  API  itself,   prevenIng  V1,  V2,  V3     endpoints  
  26. 26. A  Good  REST  API  Uses   Hypermedia   ApplicaIon   Language   Hypermedia  ApplicaIon  Language   provides  a  format  for  describing   addiIonal  resources  (ie  links)  using  a   _links -> item -> connection type => url grouping.       Content  type:  applicaXon/hal+json      
  27. 27. Using  HATEOAS   {"data":{"user":{"fname":"first","lname":"last"}}, "_links":{ "edit":{"href":"/api/user/id/1"}, "message":{"href":"/api/message/id/1"} },"id":"1"} (Sample  JSON  Response)  
  28. 28. A  Good  REST  API  Uses   Hypermedia   As   The   Engine   Of   ApplicaIon   State   By  sending  back  the  next  possible   acIons  we  are  able  to  modify  the   endpoints  without  breaking   backwards  compaIbility…    Let’s   say  we  now  required  the  last   name  in  the  message  endpoint,   just  to  prevent  accidental     message  from  being     sent…  
  29. 29. Using  HATEOAS   {"data":{"user":{"fname":"first","lname":"last"}}, "_links":{ "edit":{"href" : "/api/user/id/1"}, "message":{"href" : "/api/message/id/1/lname/last"} }," id":"1"} We  can  update  the  endpoint  in  the  response  for  our  clients,   allowing  them  to  use  the  dynamic  endpoint  to  perform  the   acIon,  prevenIng  any  backwards  compaIbility  breaks!    
  30. 30. Use  JSON  instead  of  XML   •  Be`er  Language  Support     •  Lightweight  (much  less  code  than  XML)       {"object1":{"object":{"string":"rock","string2":"   star"}},"object2":{"string":"hello","string2":   "world"},"string":"json is cool"}     •  Object  Oriented  by  nature     •  Simple  to  encode/  decode   To  encode/  decode  JSON  in  PHP  simply  use  the  json_encode()  and     json_decode() funcIons!    Many  frameworks  also  have  JSON  libraries   that  take  care  of  all  of  the  error  checking  for  you  as  well!  
  31. 31. Use  AuthenXcaXon  Tokens   •  Users  should  be  provided  with  a  unique   API  key/  idenIfier  that  allows  you  to  track,   limit,  and  enable  features   •  An  OAuth  token  should  be  used  to  link  API   keys  to  accounts  instead  of  requesIng   account  usernames  and  passwords  
  32. 32. Thro^le  API  Key  Usage   Be  sure  to  place  limits  on  the  number  of  calls/  queries  an   API  key  can  make  per  hour  or  per  day  to  prevent  your   applicaIon  from  becoming  bogged  down  and  suscepIble   to  DOS  a`acks.     This  risk  can  also  be  reduced  by  ensuring  your   API  is  operaIng  within  the  cloud  and  has  the   ability  to  scale  to  increased  traffic  demands.  
  33. 33. OAuth  Tokens   Tokens  help  prevent  misuse  of  the  system  and  limit   access  to  the  control  panel.    Usernames  and  passwords   allow  hackers  to  go  in  beyond  the  API,  oRen  accessing   billing  and  profile  informaIon  that  exposes  your  clients   to  catastrophic  damage  should  this  informaIon     fall  into  the  wrong  hands  
  34. 34. Use  HTTP  Status  Codes   Proper  use  of  HTTP  status  codes  give  your  users  immediate   feedback  on  the  result.    Some  of  the  more  widely  used  Header   codes  include:     •  •  •  •  •  •  •  •  •  200  –  OK   201  –  Created   304  –  Not  modified   400  –  Bad  Request   401  –  Not  Authorized   403  –  Forbidden   404  –  Page/  Resource  Not  Found   405  –  Method  Not  Allowed   500  –  Internal  Server  Error  
  35. 35. Use  HTTP  Status  Codes   You  probably  shouldn’t  use  these…       •  418  –  I’m  a  teapot   •  420  –  Keep  your  calm   Status  Code  420  has  gained  popularity  as  it  is  saIrically  returned  by   Twi`er  when  there’s  been  too  many  requests,  however  the  proper   response  code  for  “too  many  requests”  would  be  429.      
  36. 36. Use  DescripXve  Error  Messages   Error  messages  should  give  a  clear  descripIon  of  what  went  wrong   and  how  the  client  can  fix  their  code  to  avoid  the  error  in  the   future.     Providing  a  link  to  addiIonal  informaIon  and  live  debugging   examples  is  oRen  extremely  useful  to  developers,  and  allows  your   error  messages  to  be  more  compact,  but  requires  you  to  keep   addiIonal  documentaIon  up  to  date  for  your  users.  
  37. 37. Use  DescripXve  Error  Messages   These  are  not  good  error  messages:     •  Something  went  wrong     •  Could  not  complete  acIon     •  Invalid  parameters     •  Hey  look,  it’s  a  rocket.  
  38. 38. Use  DescripXve  Error  Messages   Good  Error  Messages:     •  The  AuthenIcaIon  token  is  not  recognized,  learn   more  at  h`p://…     •  A  User  ID  is  required  to  perform  this  acIon,  learn   more  at  h`p://…     •  Error  Code  313.    Read  more  at  h`p://…  
  39. 39. Remember!   DO  NOT  BREAK  BACKWARDS  COMPATIBILITY.    Make   sure  whatever  updates  you  make  to  your  API  do  not   cause  problems  for  your  exisIng  clients.     It  is  ideal  to  have  unit  tests  running  against  your   API  to  ensure  changes  do  not  cause  negaIve     or  unforeseen  consequences.  
  40. 40. Versioning  (ie:  /api/v2/…)   For  this  reason  I  am  not  a  fan  of  “versioning”  your  API.     All  releases  should  be  backwards  compaIble  so  that  your   users  do  not  need  to  know  which  version  they  are  trying   to  access!    Imagine  if  you  versioned  your  website!     The  excepIon  to  this  is  a  complete  rewrite  of     your  API,  in  which  case  the  old  API  should  sIll     be  supported  unIl  clients  are  migrated.  
  41. 41. That’s  awesome!       Now  let’s  write     some  code…  
  42. 42. Step  1  –  Install  ZF2   On  the  chance  that  you  don’t  already  have  Zend   Framework  2  installed,  let’s  get  it  up  and  running.     We’re  going  to  assume  you  have  PHP  (php.net),  Git   (git-­‐scm.com)  and  Composer  (getcomposer.org)   already  installed.  
  43. 43. Installing  ZF2   1.  Create  directory  on  your  web  server  and  move  into  it   mkdir apiproject cd apiproject 2.  IniIalize  Git,  add  the  Skeleton  Repository,  and  Download   git init git remote add https://github.com/zendframework/ZendSkeletonApplication.git source git pull source master 3.  Run  Composer   php composer.phar install
  44. 44. Setup  the  View  JSON  Strategy   Add  the  ViewJsonStrategy  to  the  strategies  array  within  the   view_manager  in  moduleApplicaIonconfigmodule.config.php   'view_manager' => array( 'strategies' => array( 'ViewJsonStrategy', ), 'display_not_found_reason' => true, 'display_exceptions' => true, 'doctype' => 'HTML5', /* … */ ),!
  45. 45. Setup  the  Controller   Add  the  UserController  to  the  invokables  array  within  controllers  in   moduleApplicaIonconfigmodule.config.php   'controllers' => array( 'invokables' => array( 'ApplicationControllerIndex' => 'ApplicationControllerIndexController', 'ApplicationControllerUser' => 'ApplicationControllerUserController' ), ),! Remember  the  alias  (leR)  you  give  your  controller  as   we  will  use  that  to  setup  our  routes!  
  46. 46. Sefng  up  Routes   Add  routes  to  moduleApplicaIonconfigmodule.config.php  where   “ApplicaIon”  is  the  module  that  will  be  the  API  library.   // Segmented Route for APIs 'user' => array( 'type' => 'Segment', 'options' => array( 'route' => '/api/user[/:id]', 'defaults' => array( 'controller' => 'ApplicationControllerUser', ), ), ),! Segmented  Routes  allow  you  to  have  dynamic  routes.      DO  NOT  include  a  default  AcIon  for  your  REST  API  endpoints  
  47. 47. The  AbstractResgulController   Zend  Framework  2  comes  with  an  abstract  controller  for   creaIng  a  REST  API  built  in.         The  AbstractRestulController  can  be  found  in  the     vendor/zendframework/zendframework/library/Zend/MVC/Controller/ directory.     Note  –  you  should  not  modify  this  file  
  48. 48. The  AbstractResgulController   The  abstract  controller  comes  with  the  following  methods,   all  set  to  return  header  code  405  –  method  not  allowed:     •  create($data)   •  update($id,  $data)   •  delete($id)   •  replaceList($data)   •  deleteList()   •  patch($id,  $data)   •  get($id)   •  patchList($data)   •  getList()   •  opIons()    
  49. 49. Sefng  up  the  User  Controller   Extending  the  AbstractRestulController  we  can  setup   moduleApplicationsrcApplicationControllerUserController.php For  this  class  we  will:     •  Set  the  opIons/  header  permissions   •  Create  an  event  listener   •  Start  building  our  API  methods      
  50. 50. Sefng  up  the  UserController   <?php namespace ApplicationController; use ZendMvcControllerAbstractRestfulController; use ZendViewModelJsonModel; class UserController extends AbstractRestfulController { } !
  51. 51. Setup  OpXons   class UserController extends AbstractRestfulController { protected $collectionOptions = array('GET', 'POST'); protected $resourceOptions = array('GET', 'PUT', 'DELETE'); protected function _getOptions() { if ($this->params->fromRoute('id', false)) { // we have an ID, return specific item return $this->resourceOptions; } // no ID, return collection return $this->collectionOptions; } } ! We’ll  use  the  _getOpIons()  method  in  the  opIons()  and   checkOpIons()  methods  
  52. 52. Returning  Available  OpXons   public function options() { $response = $this->getResponse(); // If in Options Array, Allow $response->getHeaders() ->addHeaderLine('Allow', implode(',', $this->_getOptions())); // Return Response return $response; }!
  53. 53. Adding  an  Event  Listener   public function setEventManager(EventManagerInterface $events) { // events property defined in AbstractController $this->events = $events; // Register the listener and callback method with a priority of 10 $events->attach('dispatch', array($this, 'checkOptions'), 10); }! The  event  listener  will  check  the  header  when  dispatched  to  see  if   the  behavior/  h`p  verb  being  a`empted  is  allowed  for  the   resource/  collecIon.    If  it  isn’t,  the  checkOpIons()  method  will  kill   the  process  and  return  a  status  code  of  405  to  inform  the  user  the   method  a`empted  is  not  allowed.  
  54. 54. Add  Event  Listener  Method   public function checkOptions($e) { if (in_array($e->getRequest()->getMethod(), $this->_getOptions())) { // Method Allowed, Nothing to Do return; } }! // Method Not Allowed $response = $this->getResponse(); $response->setStatusCode(405); return $response;
  55. 55. Add  AcXon  Methods   public function create($data) { // get created service to handle user creation // in this case userAPIService extends UserService and // adds in the _links or available actions to the result $userAPIService = $this->getServiceLocator()->get('userAPIService'); $result = $userAPIService->create($data); $response = $this->getResponse(); $response->setStatusCode(201); // Send Data to the View return new JsonModel($result); }!
  56. 56. Curl  –X  POST  Request  Response  
  57. 57. Add  AcXon  Methods   public function update($id, $data) { // get created service to handle user updates // in this case userAPIService extends UserService and // adds in the _links or available actions to the result $userAPIService = $this->getServiceLocator()->get('userAPIService'); $result = $userAPIService->update($id, $data); $response = $this->getResponse(); $response->setStatusCode(200); // Send Data to the View return new JsonModel($result); }!
  58. 58. Add  AcXon  Methods   public function deleteList() { $response = $this->getResponse(); $response->setStatusCode(400); $result = array( 'Error' => array( 'HTTP Status' => '400', 'Code' => '123', 'Message' => 'A user ID is required to delete a user', 'More Info' => 'http://www.mysite.com/api/docs/user/delete', ), ); return new JsonModel($result); }! In  most  cases  you’re  going  to  want  to  prevent  clients  from   uIlizing  the  DELETE  HTTP  verb  without  providing  an  ID.    In     the  event  they  try  to  access  it  generically,  they  will  go  to  the   deleteList()  method.  
  59. 59. Curl  –X  DELETE  Request  Response  
  60. 60. You  now  have  a  funcXonal  API!   You  can  conInue  to  use  the  following  methods  (and  some   others)  to  build  your  API  Controllers!     •  create($data)   •  update($id,  $data)   •  delete($id)   •  replaceList($data)   •  deleteList()   •  patch($id,  $data)   •  get($id)   •  patchList($data)   •  getList()   •  opIons()    
  61. 61. Remember…   You  will  want  to  add  more  features  including  OAuth  2  and   thro`ling.    You  can  easily  do  this  by  creaIng  your  own   abstract  class  that  extends  the  AbstractRestulController,   or  by  taking  advantage  of  a  Zend  Framework  2  REST   Skeleton  App  (available  on  GitHub)  
  62. 62. More  Resources   You  can  learn  more  about  REST  APIs  and  Zend  Framework   2  by  visiIng  the  following:     •  REST  API  Tutorial  -­‐  h`p://www.restapitutorial.com/   •  Apigee  REST  Design  (PDF)  -­‐  h`p://bit.ly/13vZXAL     •  ZF2  GeLng  Started  -­‐  h`p://bit.ly/17Wgmun     •  MWOP  ZF2  REST  -­‐  h`p://bit.ly/19rmk9M     •  Hounddog  ZF2  REST  -­‐  h`p://bit.ly/12fVW0x  
  63. 63. A  Final  Thought…   A  good  API  is  harder  for  your  clients  to   implement…   …but  easier  for  them  (and  you)  to   maintain.    SDKs  save  lives.    
  64. 64. THANK YOU. A big thank you to Constant Contact for making this presentation possible @mikegstowe @ctct_api visit  mikestowe.com/slides  for  more  on  PHP  and  Web  Development  

×