2. What
we’re
gonna
talk
about…
Overview
of
REST
•
What
is
the
purpose
of
an
API
•
Different
API
Techniques
•
The
REST
Methodology
•
Components
of
REST
•
Good
PracIces
•
Not
so
Good
PracIces
•
AuthenIcaIon
and
OAuth
Building
Your
API
•
SeLng
up
Your
Routes
•
SeLng
up
Your
Controllers
•
Handling
Headers
•
Handling
JSON
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
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. 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. 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
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
12. REST
vs.
SOAP
REST
• Returns
data
• Supports
XML
and
JSON
• Uses
CRUD/
HTTP
Verbs
• Point
to
point
connecIons
• Ajax
(JavaScript)
Friendly
• Stateless
SOAP
• Exposes
operaIons/
method
calls
• All
calls
sent
through
POST
• Larger
packets
of
data,
XML
based
• Can
be
stateless
or
stateful
• WSDL
Support
Advantage
goes
to…
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. 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. 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. 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. 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. 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
20. A
Good
REST
API
Uses
Explicit
HTTP
Verbs
Create
–
POST
Read
–
GET
Update
–
PUT
Delete
-‐
DELETE
21. A
Good
REST
API
Is
built
for
longevity
and
designed
to
evolve…
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. A
Good
REST
API
Uses
Hypermedia
As
The
Engine
Of
ApplicaIon
State
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. 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. 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
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. 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!
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"}
30. Use
JSON
instead
of
XML
• Be`er
Language
Support
• Lightweight
(much
less
code
than
XML)
• 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!
{"object1":{"object":{"string":"rock","string2":"
star"}},"object2":{"string":"hello","string2":
"world"},"string":"json is cool"}
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. 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. 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. 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. 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. 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. 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. 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. 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. 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.
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. Installing
ZF2
mkdir apiproject
cd apiproject
1.
Create
directory
on
your
web
server
and
move
into
it
git init
git remote add https://github.com/zendframework/ZendSkeletonApplication.git source
git pull source master
2.
IniIalize
Git,
add
the
Skeleton
Repository,
and
Download
3.
Run
Composer
php composer.phar install
44.
45. Setup
the
View
JSON
Strategy
'view_manager' => array(
'strategies' => array(
'ViewJsonStrategy',
),
'display_not_found_reason' => true,
'display_exceptions' => true,
'doctype' => 'HTML5',
/* … */
),!
Add
the
ViewJsonStrategy
to
the
strategies
array
within
the
view_manager
in
moduleApplicaIonconfigmodule.config.php
46. 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!
47. Sefng
up
Routes
// Segmented Route for APIs
'user' => array(
'type' => 'Segment',
'options' => array(
'route' => '/api/user[/:id]',
'defaults' => array(
'controller' => 'ApplicationControllerUser',
),
),
),!
Add
routes
to
moduleApplicaIonconfigmodule.config.php
where
“ApplicaIon”
is
the
module
that
will
be
the
API
library.
Segmented
Routes
allow
you
to
have
dynamic
routes.
DO
NOT
include
a
default
AcIon
for
your
REST
API
endpoints
48. 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
49. The
AbstractResgulController
The
abstract
controller
comes
with
the
following
methods,
all
set
to
return
header
code
405
–
method
not
allowed:
• create($data)
• delete($id)
• deleteList()
• get($id)
• getList()
• update($id,
$data)
• replaceList($data)
• patch($id,
$data)
• patchList($data)
• opIons()
50. 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
51. Sefng
up
the
UserController
<?php
namespace ApplicationController;
use ZendMvcControllerAbstractRestfulController;
use ZendViewModelJsonModel;
class UserController extends AbstractRestfulController
{
}
!
52. 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
53. 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;
}!
54. 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.
55. 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;
}!
56. 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);
}!
58. 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);
}!
59. 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.
61. You
now
have
a
funcXonal
API!
You
can
conInue
to
use
the
following
methods
(and
some
others)
to
build
your
API
Controllers!
• create($data)
• delete($id)
• deleteList()
• get($id)
• getList()
• update($id,
$data)
• replaceList($data)
• patch($id,
$data)
• patchList($data)
• opIons()
62. 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)
63. 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
64. A
Final
Thought…
A
good
API
is
harder
for
your
clients
to
implement…
…but
easier
for
them
(and
you)
to
maintain.
SDKs
save
lives.