web services php tutorial

78
Web Services Tutorial

Upload: lorna-mitchell

Post on 19-May-2015

127.379 views

Category:

Technology


1 download

DESCRIPTION

Web services tutorial slides from my session at DPC 2012 in Amsterdam. In this 3-hour session we built the simplest possible service, and then extended it, looking at RPC, REST and SOAP along the way.

TRANSCRIPT

Page 1: Web Services PHP Tutorial

Web Services Tutorial

Page 2: Web Services PHP Tutorial

Web Services Tutorial

2

http://bit.ly/oaxVdy

(while you’re waiting, download the files!)

Page 3: Web Services PHP Tutorial

About Me

3

• Lorna Jane Mitchell

• PHP Consultant/Developer

• Author

• API Specialist

• Project Lead on http://joind.in

• Twitter: @lornajane

• Website: http://lornajane.net

Page 4: Web Services PHP Tutorial

The Plan

4

• Talk about web services in general

• Build a web service

• Consume a web service

• Talk about how to make excellent web services

Page 5: Web Services PHP Tutorial

The Plan

4

• Talk about web services in general

• Build a web service

• Consume a web service

• Talk about how to make excellent web services

• (we’ll hide some actual textbook theory in there somewhere)

• Ask questions!

Page 6: Web Services PHP Tutorial

Theory and Introduction

Page 7: Web Services PHP Tutorial

What Is A Web Service?

6

• Means of exposing functionality or data

• A lot like a web page, but for machines

• Integration between applications

• Separation within an application

Page 8: Web Services PHP Tutorial

Integration Between Applications

7

Common to use an API internally as well as exposing it

Website

API

Data Store

3rd Party / Apps

Page 9: Web Services PHP Tutorial

Separation Within an Application

8

Routing

ProductsAuth Images Orders

Page 10: Web Services PHP Tutorial

Separation Within an Application

9

Routing

ProductsAuth Images Orders

Page 11: Web Services PHP Tutorial

Web Services and You

10

This is not rocket science

You already know most of what you need!

Page 12: Web Services PHP Tutorial

Let’s Begin

Page 13: Web Services PHP Tutorial

Building Blocks

12

You can make an API from any tools you like

• Existing MVC setup

• Simple PHP (as in these examples)

• Framework modules

• Component library

Page 14: Web Services PHP Tutorial

My First Web Service

13

• Make a virtual host

• e.g. http://api.local

• Don’t forget to restart apache

• Add an entry to your hosts file

<VirtualHost * :80>ServerName api.localServerAdmin admin@localhostDocumentRoot /var/www/myapi/public

<Directory /var/www/myapi/public>AllowOverride AllOrder deny,allowAllow from All

</Directory></VirtualHost>

api.vhost

Page 15: Web Services PHP Tutorial

My First Web Service

14

• Create the index.php file

• e.g. /var/www/myapi/public/index.php

$data = array ('format' => 'json' ,'status' => 'live');

echo json_encode ($data);

public/index.php

Page 16: Web Services PHP Tutorial

Consume Your Service

15

• Use cURL from the command line

• curl http://api.local

• For more information about curl:

• http://curl.haxx.se/ - curl homepage

• http://bit.ly/esqBmz - my cheat sheet

Page 17: Web Services PHP Tutorial

JSON JavaScript Object Notation

16

• Originally for JavaScript

• Native read/write in most languages

• Simple, lightweight format - useful for mobile

• In PHP we have json_encode() and json_decode()

• These work with arrays and objects

Our service returns:

{'format':'json','status':'live'}

Page 18: Web Services PHP Tutorial

Heartbeat Method

17

• A method which does nothing

• No authentication

• Requires correct request format

• Gives basic feedback

• Shows that service is alive

Page 19: Web Services PHP Tutorial

Delivering A Web Service

18

• Service

• Documentation

• Examples

• A help point

Page 20: Web Services PHP Tutorial

HTTP and Data Formats

Page 21: Web Services PHP Tutorial

HTTP

20

HTTP is Hypertext Transfer Protocol. It is designed to exchangeinformation about a request/response.

• Status Codes (e.g. 200, 404)

• Headers (e.g. Content-Type, Authorization)

• Verbs (e.g GET, POST)

Page 22: Web Services PHP Tutorial

Status Codes

21

Win or fail? Some common codes:

200 OK

204 No Content

302 Found

301 Moved Permanently

302 Found

400 Bad Request

401 Not Authorised

403 Forbidden

404 Not Found

500 Internal Server Error

For more, see: http://bitly.com/h03Dxe

Page 23: Web Services PHP Tutorial

Working with Status Codes in PHP

22

We can observe status codes with curl, passing the -I switch

curl -I http://api.local

Let’s amend our web service, to return a 302 header

header ( "302 Found" , true , 302);

$data = array ('format' => 'json' ,'status' => 'live');

echo json_encode ($data);

Page 24: Web Services PHP Tutorial

HTTP Verbs

23

• More than GET and POST

• PUT and DELETE to update and delete in a RESTful service

• HEAD, OPTIONS and others also specified

In REST, we use:

GET Read

POST Create

PUT Update

DELETE Delete

Page 25: Web Services PHP Tutorial

HTTP Headers

24

Headers are the metadata about the content we send/receive

Useful headers:

• Accept and Content-Type: used for content format negotiation

• User-Agent: to identify what made the request

• Set-Cookie and Cookie: working with cookie data

• Authorization: controlling access

Page 26: Web Services PHP Tutorial

Accept Header

25

What type of content can the consumer understand?

• -v with curl to see request and response headers

• -H to add headers

curl -v -H "Accept: text/html" http://api.local

Gives the output:

* About to connect() to api.local port 80 (#0)

* Trying 127.0.0.1... connected

* Connected to api.local (127.0.0.1) port 80 (#0)> GET / HTTP/1.1> User-Agent: curl/7.21.0 (i686-pc-linux-gnu) libcurl/7 .21.0 OpenSSL/0.9.8> Host: api.local> Accept: text/html>

Page 27: Web Services PHP Tutorial

Using the Accept Header

26

We can work out what format the user wanted to see from the Acceptheader.

$data = array ('status' => 'live' ,'now' => time ());

if ( false !== strpos ($_SERVER[ 'HTTP_ACCEPT' ], 'text/html' )) {echo "<pre>" ;print_r ($data);echo "</pre>" ;

} else {// return jsonecho json_encode ($data);

}

public/headers.php

Page 28: Web Services PHP Tutorial

How to REALLY Handle Accept Headers

27

Example accept header (from my browser)

text/html, application/xml;q=0.9, application/xhtml+x ml,image/png, image/jpeg, image/gif, image/x-xbitmap, * / * ;q=0.1

• See a much nicer example of this in headers-accept.php

• Taken almost entirely from the source of arbitracker

• http://arbitracker.org

• src/classes/request/parser.php

• Try this from curl, setting your own headers, and from your browser

Page 29: Web Services PHP Tutorial

Content-Type Header

28

The Content-Type header: literally labels the contents of the response.We can include these in our examples:

$data = array ('status' => 'live' ,'now' => time ());

if ( false !== strpos ($_SERVER[ 'HTTP_ACCEPT' ], 'text/html' )) {header ( 'Content-Type: text/html' );echo "<pre>" ;print_r ($data);echo "</pre>" ;

} else {// return jsonheader ( 'Content-Type: application/json' );echo json_encode ($data);

}

public/headers.php

Page 30: Web Services PHP Tutorial

Handling XML Formats

29

We can work with XML in PHP almost as easily

• Content type is text/xml or application/xml

• Two XML libraries in PHP

• SimpleXML bit.ly/g1xpaP

• DOM bit.ly/e0XMzd

• Give consumers a choice of formats: HTML, XML, JSON ...

Page 31: Web Services PHP Tutorial

Adding XML to Our Service

30

$data = array ('status' => 'live' ,'now' => time ());

$simplexml = simplexml_load_string( '<?xml version="1.0" ?><data />' );foreach ($data as $key => $value) {

$simplexml->addChild($key, $value);}

header ( 'Content-Type: text/xml' );echo $simplexml->asXML();

public/headers.php

The result is this:

<?xml version="1.0"?><data><status>live</status><now>1302981884</now></d ata>

Page 32: Web Services PHP Tutorial

Versioning

31

• Always include a version parameter or media type

http://example.com/api/v4/status

http://example.com/api/status

Content-Type: application/vnd.myapi.2+json

Page 33: Web Services PHP Tutorial

Data Formats

32

• Handle multiple formats, by header or parameter

• JSON

• XML

• ?

• Common to detect header, allow parameter override

http://example.com/api/v4/status

Accept: application/json

http://example.com/api/v4/status?format=json

Accept: text/html

Page 34: Web Services PHP Tutorial

Statelessness

33

• Request alone contains all information needed

• No data persistence between requests

• Resource does not need to be in known state

• Same operation performs same outcome

Page 35: Web Services PHP Tutorial

Consuming Services from PHP

Page 36: Web Services PHP Tutorial

Consuming Your First Web Service

35

Three ways to consume web services:

• Via streams (e.g. file_get_contents() )

• Using the curl extension

• http://lrnja.net/I5JD9R

• Using Pecl_HTTP

• http://lrnja.net/I23yZj

Page 37: Web Services PHP Tutorial

Using File_Get_Contents

36

This is the simplest, especially for a GET request

$response = file_get_contents ( 'http://api.local/' );var_dump ($response);

You can set more information in the stream context bit.ly/gxBAgV

Page 38: Web Services PHP Tutorial

Using Curl

37

This extension is commonly available

$ch = curl_init ( 'http://api.local/' );curl_setopt ($ch, CURLOPT_RETURNTRANSFER,true );$response = curl_exec ($ch);var_dump ($response);

Look out for the CURLOPT_RETURNTRANSFER; without it, this will echothe output

Page 39: Web Services PHP Tutorial

Using Pecl_HTTP

38

This is the most powerful and flexible, and can easily be installed fromhttp://pecl.php.net

$request = new HTTPRequest( 'http://api.local/' , HTTP_METH_GET);$request->send();$response = $request->getResponseBody();var_dump ($response);

Strongly recommend pecl_http if you are able to install pecl modules onyour platform

Page 40: Web Services PHP Tutorial

Service Types

Page 41: Web Services PHP Tutorial

Web Service Types

40

There are a few types of web service

• RESTful

• RPC (Remote Procedure Call)

• XML-RPC

• JSON-RPC

• Soap

Page 42: Web Services PHP Tutorial

RPC Services

41

These services typically have:

• A single endpoint

• Method names

• Method parameters

• A return value

• Often all POST requests

A familiar model for us as developers

Page 43: Web Services PHP Tutorial

Soap

42

• Not an acronym

• (used to stand for Simple Object Access Protocol)

• Special case of XML-RPC

• VERY easy to do in PHP

• Can be used with a WSDL

• Web Service Description Language

Page 44: Web Services PHP Tutorial

Soap Example: Library Class

43

public function eightBall() {$options = array (

"Without a doubt" ,"As I see it, yes" ,"Most likely" ,"Reply hazy, try again" ,"Better not tell you now" ,"Concentrate and ask again" ,"Don't count on it" ,"Very doubtful" );

return $options[ array_rand ($options)];}

/public/soap/Library.php

Page 45: Web Services PHP Tutorial

Soap Server

44

(don’t blink or you will miss it!)

include ( 'Library.php' );

$options = array ( 'uri' => 'http://api.local/soap' );$server = new SoapServer( NULL, $options);$server->setClass( 'Library' );

$server->handle();

/public/soap/index.php

Page 46: Web Services PHP Tutorial

Consuming a Soap Service

45

To call PHP directly, we would do:

include ( 'Library.php' );

$lib = new Library();$response = $lib->eightBall();echo $response;

Over Soap:

$options = array ( 'uri' => 'http://myapi.local' ,'location' => 'http://myapi.local/soap/' );

try{$client = new SoapClient( NULL, $options);$response = $client->eightBall();echo $response;

} catch (SoapFault $e) {echo "ERROR: " . $e->getMessage();

}

Page 47: Web Services PHP Tutorial

Pros and Cons of Soap

46

• Many languages have libraries for it

• .NET and Java programmers in particular like it

Page 48: Web Services PHP Tutorial

Pros and Cons of Soap

46

• Many languages have libraries for it

• .NET and Java programmers in particular like it

• Weird things happen between languages regarding data types

• When it works, it’s marvellous

• When it doesn’t work, it’s horrid to debug (so I’ll show you how)

Page 49: Web Services PHP Tutorial

Pros and Cons of Soap

46

• Many languages have libraries for it

• .NET and Java programmers in particular like it

• Weird things happen between languages regarding data types

• When it works, it’s marvellous

• When it doesn’t work, it’s horrid to debug (so I’ll show you how)

• WSDL is complicated!

Page 50: Web Services PHP Tutorial

Working with WSDLs

47

WSDL stands for Web Service Description Language

• WSDLs were not designed for humans to read

• They are written in XML, and are very verbose

• If you do need to read one, start at the END and read upwards insections

• Soap uses very strict data typing, which is an unknown concept inPHP

Read about WSDLs: bit.ly/eNZOmp

Page 51: Web Services PHP Tutorial

Debugging Soap

48

The Soap extension has some debug methods:

• Set the options to include trace=1 in the SoapClient

• getLastRequest() , getLastRequestHeaders() ,getLastResponse() , getLastResponseHeaders() are thenavailable

For all web service types, you can use:

• I like Wireshark (http://www.wireshark.org )

• Others use Charles (http://www.charlesproxy.com )

• If you like reading XML then use curl

• SoapUI (http://soapui.org )

Page 52: Web Services PHP Tutorial

Extending Our Service

Page 53: Web Services PHP Tutorial

Consistency

50

• Important to retain

• Naming conventions

• Parameter validation rules

• Parameter order

• Just as you would in library code

Page 54: Web Services PHP Tutorial

The Action Parameter

51

As a simple place to start, let’s add an action parameter.

// route the request (filter input!)$action = $_GET[ 'action' ];$library = new Actions();$data = $library->$action();

/rpc/index.php

Here’s the code for the Actions class

class Actions {public function getSiteStatus() {

return array ( 'status' => 'healthy' ,'time' => date ( 'd-M-Y' ));

}}

/rpc/actions.php

So try http://api.local/rpc/index.php?action=getSiteStatus

Page 55: Web Services PHP Tutorial

Small APIs

52

• Beware adding new functionality

• Simple is maintainable

• Easy to use and understand

Page 56: Web Services PHP Tutorial

Adding an Action

53

To add a new action, create a new method for the Actions class, returningan array to pass to the output handlers

public function addTwoNumbers($params) {return array ( 'result' => ($params[ 'a' ] + $params[ 'b' ]));

}

/rpc/actions.php

But how do we pass the parameters in? Something like this

// route the request (filter input!)$action = $_GET[ 'action' ];$library = new Actions();// OBVIOUSLY you would filter input at this point$data = $library->$action($_GET);

/rpc/index.php

Page 57: Web Services PHP Tutorial

Access Control

54

A few common ways to identify users

• Username and password with every request

• Login action and give a token to use

• OAuth

• For internal applications, firewalls

Page 58: Web Services PHP Tutorial

RPC Service Example: Flickr

55

Take a look at http://www.flickr.com/services/api/

• Supports multiple formats (for request and response)

• Is well-documented and consistent

• Has libraries helping users to consume it

• Offers both RPC and RESTful (kind of!) interfaces

• Follows true XML-RPC (seehttp://en.wikipedia.org/wiki/Xml-rpc )

Vast numbers of applications using this API to provide flickr functionalityelsewhere

Page 59: Web Services PHP Tutorial

RPC vs REST

56

We’ve seen an RPC service, but what about REST? The two are quitedifferent

• RPC services describe protocols, e.g. XML-RPC

• RPC is a familiar: functions and arguments

• REST is a set of principles

• Takes advantage of HTTP features

• Typically has "pretty URLs", e.g. Twitter is mostly RESTful

Page 60: Web Services PHP Tutorial

RESTful Web Service

Page 61: Web Services PHP Tutorial

REST

58

• REpresentational State Transfer

• URLs are unique resource identifiers

• HTTP verbs indicate which operation should happen

• We have full CRUD operations on a series of resources

Here’s one I prepared earlier: /public/rest/

Page 62: Web Services PHP Tutorial

REST as a Religion

59

Beware publishing a service labelled "RESTful"

• Someone will always tell you it isn’t

• They are probably right

• The strict rules around REST sometimes fit badly around businessrequirements

• Flamewars will ensue

Instead: "An HTTP Web Service"

Page 63: Web Services PHP Tutorial

Making Our Service Restful

60

We’re aiming for URLs that look something like this:

• http://api.local/rest/user

• http://api.local/rest/user/3

• http://api.local/rest/user/3/friends

A specific item is a resource; where you request a list, e.g. /user , this iscalled a collection

Page 64: Web Services PHP Tutorial

All Requests to index.php

61

We want to push all requests through index.php, there is an .htaccess filethat does this

<IfModule mod_rewrite.c>RewriteEngine OnRewriteBase /

RewriteCond %{REQUEST_FILENAME} !-fRewriteCond %{REQUEST_FILENAME} !-dRewriteRule ^(. * )$ index.php/$1 [L]

</IfModule>

/public/rest/.htaccess

Page 65: Web Services PHP Tutorial

Routing Within Our App

62

So our routing depends on the URL and on the verb used, so ourcontrollers have a method per verb:

• GET /user

• Becomes UserController::GETAction()

// route the request (filter input!)$verb = $_SERVER[ 'REQUEST_METHOD'];$action_name = strtoupper ($verb) . 'Action' ;$url_params = explode ( '/' ,$_SERVER[ 'PATH_INFO' ]);$controller_name = ucfirst ($url_params[1]) . 'Controller' ;$controller = new $controller_name();$data = $controller->$action_name($url_params);

// output appropriately$view->render($data);

/public/rest/index.php

Page 66: Web Services PHP Tutorial

A Simple Controller

63

Now in UserController we add a GETAction

class UsersController {public function GETAction($parameters) {

$users = array ();// imagine retreving data from models

if ( isset ($parameters[2])) {return $users[( int )$parameters[2]];

} else {return $users;

}}

}

/public/rest/controllers.php

Page 67: Web Services PHP Tutorial

Extending our Service

64

Next we will add something to get the user’s friendshttp://api.local/users/1/friends

class UsersController {public function GETAction($parameters) {

$users = array ();$friends = array ();// imagine retreving data from models

if ( isset ($parameters[2])) {if ( isset ($parameters[3]) && $parameters[3] == 'friends' ) {

return $friends[( int )$parameters[2]];} else {

return $users[( int )$parameters[2]];}

} else {return $users;

}}

}

/public/rest/controllers.php

Page 68: Web Services PHP Tutorial

Hypermedia

65

• The items returned are resources with their URLs

• This is hypermedia - providing links to related items/collections

• Allows a service to be self-documenting

• Allows a service to change its URLs - because they’re provided

Page 69: Web Services PHP Tutorial

Creating New Records

66

RESTful services use POST for creating data, so we have POSTAction

curl -X POST http://api.local/users -d name="FredWeasley"

public function POSTAction() {// sanitise and validate data please!$data = $_POST;

// create a user from params$user[ 'name' ] = $data[ 'name' ];

// save the user, return the new id

// redirect userheader ( '201 Created' , true , 201);header ( 'Location: http://api.local/rest/users/5' );return $user;

}

/public/rest/controllers.php

Page 70: Web Services PHP Tutorial

Updating Records

67

• To create: we used POST

• To update: we use PUT

The code looks basically the same, apart from:

// instead of this:$data = $_POST;

// use this:parse_str( file_get_contents ( 'php://input' ), $data);

Page 71: Web Services PHP Tutorial

Appropriate Status Codes for REST

68

• GET

• 200 or maybe 302 if we found it somewhere else

• 404 if we can’t find it

• POST

• 201 and a location header to the new resource

• or 400 if we can’t create an item

• PUT

• 204 for OK (but no content)

• 400 if the supplied data was invalid

• DELETE

• 200 at all times, for idempotency

Page 72: Web Services PHP Tutorial

Responding to Failure

69

• Use expected response format

• Collate all errors and return

• Help users help themselves

• Be consistent

• Be accurate

Page 73: Web Services PHP Tutorial

Delivering Services

Page 74: Web Services PHP Tutorial

Technical Aspects

71

All PHP Best Practices apply equally to APIs

• Source control

• Unit/Integration testing

• Automated deployment

• Monitoring

Reliability and consistency are key

Page 75: Web Services PHP Tutorial

User Aspects

72

Who will use your API?

• Offer API Docs

• Write a quick start for the impatient

• Show examples, as many as possible

• Tutorials, blog posts, links to forum answers, anything

• Respond to questions

Page 76: Web Services PHP Tutorial

Questions?

Page 77: Web Services PHP Tutorial

Resources

74

All links are in the bit.ly bundle bit.ly/emRpYT

Page 78: Web Services PHP Tutorial

Thanks

75

https://joind.in/6217

@lornajane

http://lornajane.net