SlideShare a Scribd company logo
Web Services Tutorial
Lorna Mitchell

  • PHP Consultant/Developer/Trainer

  • API Specialist

  • Author and Speaker

  • Open Source Project Lead (http://joind.in)

  • Twitter: @lornajane

  • Site: http://lornajane.net




                                                 2
Agenda

  • Web Services and a Simple Example

  • HTTP and Data Formats

  • Consuming Services from PHP

  • Service Types and Soap

  • RPC Services

  • Building RESTful services

Code samples at: http://bit.ly/fE0f6f




                                        3
Theory and Introduction
What Is A Web Service?

 • Means of exposing functionality or data

 • A lot like a web page

 • Integration between applications

 • Separation within an application




                                             5
Web Services and You




             This is not rocket science

      You already know most of what you need!




                                                6
Architecture Using APIs

Common to use an API internally as well as exposing it




                                                         7
Let’s Begin
Building Blocks

You can make an API from any tools you like

  • Existing MVC setup

  • Simple PHP (as in these examples)

  • Framework module

  • Component library




                                              9
My First Web Service

  • 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.local
    ServerAdmin admin@localhost
    DocumentRoot /var/www/myapi/public

    <Directory /var/www/myapi/public>
        AllowOverride All
        Order deny,allow
        Allow from All
    </Directory>
</VirtualHost>

                                api.vhost
                                            10
My First Web Service

  • 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




                                                  11
Consume Your Service

 • curl http://api.local

 • For more information about curl:

     • http://curl.haxx.se/
     • http://bit.ly/esqBmz




                                      12
JSON JavaScript Object Notation

   • 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'}




                                                      13
Heartbeat Method

 • A method which does nothing

 • No authentication

 • Requires correct request format

 • Gives basic feedback

 • Shows that service is alive




                                     14
Delivering A Web Service

   • Service

   • Documentation

   • Examples

   • A help point


If you’re only going to build the service, don’t bother




                                                          15
HTTP and Data Formats
HTTP

HTTP is Hypertext Transfer Protocol - we’ll recap on some key elements:

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

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

  • Verbs (e.g GET, POST)




                                                                          17
Status Codes

A headline response. Common codes:

                      200   OK
                      302   Found
                      301   Moved
                      401   Not Authorised
                      403   Forbidden
                      404   Not Found
                      500   Internal Server Error

Consumers can get a WIN/FAIL indicator before unpacking the response
in full



                                                                       18
Working with Status Codes in PHP

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);




                                                               19
HTTP Verbs

  • More than GET and POST

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

  • HEAD, OPTIONS and others also specified

                     GET    Read
                    POST    Create
In REST, we use:
                     PUT    Update
                   DELETE   Delete




                                                               20
HTTP Headers

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




                                                                   21
Accept Header

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
>   Host: api.local
>   Accept: text/html
>



                                                                     22
Using the Accept Header

We can work out what format the user wanted to see from the Accept
header.
$data = array(
    'status' => 'live',
    'now' => time()
    );

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

                             public/headers.php




                                                                     23
Content-Type Header

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 json
    header('Content-Type: application/json');
    echo json_encode($data);
}

                              public/headers.php



                                                                          24
Handling XML Formats

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




                                                  25
Adding XML to Our Service

$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();

The result is this:
<?xml version="1.0"?>
<data><status>live</status><now>1302981884</now></data>




                                                                   26
How to REALLY Handle Accept Headers

Example accept header (from my browser)
text/html, application/xml;q=0.9, application/xhtml+xml,
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




                                                                          27
Versions and Formats

 • Always include a version parameter or media type

 • Handle multiple formats, by header or parameter

     • JSON
     • XML
     • HTML
     • ?

 • Common to detect header, allow parameter override




                                                       28
Statelessness

 • 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




                                                   29
Consuming Services from PHP
Consuming Your First Web Service

Three ways to consume web services:

  • Via streams (e.g. file_get_contents and some context)

  • Using the curl extension

      • bit.ly/h5dhyT

  • Using Pecl_HTTP

      • bit.ly/g4CfPw




                                                           31
Using File_Get_Contents

This is the simplest, useful for GET requests
$response = file_get_contents('http://api.local/');
var_dump($response);

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




                                                                   32
Using Curl

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 echo
the output




                                                                      33
Using Pecl_HTTP

This is the most powerful and flexible, and can easily be installed from
http://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 on
your platform




                                                                          34
Service Types
Web Service Types

There are a few types of web service

  • RESTful

  • RPC (Remote Procedure Call)

       • XML-RPC
       • JSON-RPC
       • Soap




                                       36
RPC Services

These services typically have:

   • A single endpoint

   • Method names

   • Method parameters

   • A return value


A familiar model for us as developers




                                        37
Soap

 • 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




                                                             38
Soap Example: Library Class

class Library {
    public function thinkOfANumber() {
        return 42;
    }

    public function thinkOfAName() {
        return 'Arthur Dent';
    }
}
                         /public/soap/Library.php




                                                    39
Publishing a Soap Service

(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




                                                              40
Consuming a Soap Service

To call PHP directly, we would do:
include('Library.php');

$lib = new Library();
$name = $lib->thinkOfAName();
echo $name; // Arthur Dent



Over Soap:
$options = array('uri' => 'http://api.local',
    'location' => 'http://api.local/soap');
$client = new SoapClient(NULL, $options);

$name = $client->thinkOfAName();
echo $name; // Arthur Dent




                                                41
Pros and Cons of Soap

 • Many languages have libraries for it

 • .NET and Java programmers in particular like it




                                                     42
Pros and Cons of Soap

 • Many languages have libraries for it

 • .NET and Java programmers in particular like it

 • Weird things happen between languages regarding data types




                                                                42
Pros and Cons of Soap

 • 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)




                                                                       42
Pros and Cons of Soap

 • 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!




                                                                       42
Working with WSDLs

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 in
    sections

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

Read about WSDLs: bit.ly/eNZOmp




                                                                        43
Debugging Soap

The Soap extension has some debug methods:

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

   • getLastRequest(), getLastRequestHeaders(),
     getLastResponse(), getLastResponseHeaders() are then
     available


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)



                                                            44
Wireshark Demo




  Bear with me while I fire up wireshark to show you




                                                      45
Extending Our Service
Consistency

 • Important to retain

     • Naming conventions
     • Parameter validation rules
     • Parameter order

 • Just as you would in library code




                                       47
The Action Parameter

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
                                                             48
Small APIs

 • Beware adding new functionality

 • Simple is maintainable

 • Easy to use and understand




                                     49
Adding an Action

To add a new action, create a new method for the Actions class, returning
an 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




                                                                            50
Access Control

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




                                               51
RPC Service Example: Flickr

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 (see
     http://en.wikipedia.org/wiki/Xml-rpc)

Vast numbers of applications using this API to provide flickr functionality
elsewhere




                                                                             52
RPC vs REST

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

  • 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




                                                                    53
RESTful Web Service
REST

  • 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/




                                                            55
REST as a Religion

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 business
    requirements

  • Flamewars will ensue

Instead: "An HTTP Web Service"




                                                                      56
Making Our Service Restful

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 is
called a collection




                                                                              57
All Requests to index.php

We want to push all requests through index.php, there is an .htaccess file
that does this
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ index.php/$1 [L]
</IfModule>

                             /public/rest/.htaccess




                                                                            58
Routing Within Our App

So our routing depends on the URL and on the verb used, so our
controllers 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




                                                                 59
A Simple Controller

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




                                                       60
Calling our Service

Example uses curl, there are options

$ch = curl_init('http://api.local/rest/users');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
print_r(json_decode($result, true));

                            /public/rest-test.php




                                                    61
Extending our Service

Next we will add something to get the user’s friends
http://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
                                                                    62
Hypermedia

 • 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




                                                                       63
Creating New Records

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

    public function POSTAction($path, $data) {
        // sanitise and validate data please!

        // create a user from params
        $new_user['name'] = isset($data['name']) ? $data['name'] : '';
        $new_user['house'] = isset($data['house']) ? $data['house'] :
        $new_user['age'] = isset($data['age']) ? $data['age'] : '';

        // save the user, return the new id
        $new_user['self'] = 'http://' . $_SERVER['HTTP_HOST'] . '/rest

        // redirect user
        header('HTTP/1.1 201 Created');
        header('Location: http://api.local/rest/users/5');
        return $new_user;
    }

                        /public/rest/controllers.php


                                                                     64
Incoming POST/PUT Data

We read from php://input which is a stream. So for JSON:

$verb = $_SERVER['REQUEST_METHOD'];
$data = array();
switch($verb) {
    case 'GET':
        parse_str($_SERVER['QUERY_STRING'], $data);
        break;
    case 'POST':
    case 'PUT':
        // incoming JSON data, it's an array
        $data = json_decode(file_get_contents('php://input'), true);
        break;

                          /public/rest/index.php




                                                                   65
POSTing JSON Data from PHP

Adding some appropriate data handling and headers to the curl call:
$data = array("name" => "Hagrid", "age" => "36");
$data_string = json_encode($data);

$ch = curl_init('http://api.local/rest/users');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/json',
    'Content-Length: ' . strlen($data_string))
);

$result = curl_exec($ch);

print_r(json_decode($result, true));

                             /public/rest-test.php




                                                                      66
Appropriate Status Codes for REST

 • 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
                                                       67
Responding to Failure

  • Use expected response format

  • Collate all errors and return

  • Help users help themselves

  • Be consistent

  • Be accurate




                                    68
Delivering Services
Technical Aspects

All PHP Best Practices apply equally to APIs

   • Source control

   • Unit/Integration testing

   • Automated deployment

   • Monitoring


Reliability and consistency are key




                                               70
User Aspects

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




                                                              71
Questions?
Resources

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




                                                   73
Thanks

 • http://joind.in/talk/view/3461

 • http://lornajane.net




                                    74

More Related Content

PDF
Creating And Consuming Web Services In Php 5
PPT
Develop webservice in PHP
PDF
Consuming RESTful services in PHP
PDF
OAuth: Trust Issues
PDF
RESTful API Design & Implementation with CodeIgniter PHP Framework
PDF
PHP And Web Services: Perfect Partners
PPT
Easy rest service using PHP reflection api
PDF
JSON-RPC - JSON Remote Procedure Call
Creating And Consuming Web Services In Php 5
Develop webservice in PHP
Consuming RESTful services in PHP
OAuth: Trust Issues
RESTful API Design & Implementation with CodeIgniter PHP Framework
PHP And Web Services: Perfect Partners
Easy rest service using PHP reflection api
JSON-RPC - JSON Remote Procedure Call

What's hot (20)

ODP
RESTful Web Services with JAX-RS
PPTX
Restful web services with java
PPTX
ASP.NET WEB API
PDF
JSON-RPC Proxy Generation with PHP 5
PPT
Json-based Service Oriented Architecture for the web
PDF
Rails vs Web2py
PPT
Common Gateway Interface
PDF
RESTful Web services using JAX-RS
PPTX
RESTful API 제대로 만들기
ODP
PHP BASIC PRESENTATION
PPTX
PHP FUNCTIONS
PDF
web2py:Web development like a boss
PDF
Cwinters Intro To Rest And JerREST and Jersey Introductionsey
PPTX
Introduction to RESTful Webservices in JAVA
PDF
RESTful Web Services
PDF
ACL in CodeIgniter
PDF
Java Web Programming [2/9] : Servlet Basic
PPT
ZendCon 08 php 5.3
PDF
SOAP-based Web Services
PDF
Services web RESTful
RESTful Web Services with JAX-RS
Restful web services with java
ASP.NET WEB API
JSON-RPC Proxy Generation with PHP 5
Json-based Service Oriented Architecture for the web
Rails vs Web2py
Common Gateway Interface
RESTful Web services using JAX-RS
RESTful API 제대로 만들기
PHP BASIC PRESENTATION
PHP FUNCTIONS
web2py:Web development like a boss
Cwinters Intro To Rest And JerREST and Jersey Introductionsey
Introduction to RESTful Webservices in JAVA
RESTful Web Services
ACL in CodeIgniter
Java Web Programming [2/9] : Servlet Basic
ZendCon 08 php 5.3
SOAP-based Web Services
Services web RESTful
Ad

Viewers also liked (20)

PDF
Web Services PHP Tutorial
PDF
Building Highly Reusable Taskflows
PDF
Web Services (SOAP, WSDL, UDDI)
PPT
Web Service Presentation
PPTX
Testing web services
PDF
Le jeu vidéo à la rescousse du web
PDF
Getting started with MySQL on Amazon Web Services
PDF
Xml interview questions
PPTX
Marrying HTML5 and Angular to ADF - Oracle OpenWorld 2014 Preview
PDF
Php tutorial(w3schools)
PDF
Web services
PPSX
Oracle ADF Overview for Beginners
PDF
Webservices(or)SoapUI Interview Questions
PDF
Restful Web Services
PPTX
Web Services - A brief overview
PDF
Spring Web Services: SOAP vs. REST
PPTX
Web services - A Practical Approach
PPTX
Web Services - Architecture and SOAP (part 1)
PPTX
Oracle JET CRUD and ADF BC REST
Web Services PHP Tutorial
Building Highly Reusable Taskflows
Web Services (SOAP, WSDL, UDDI)
Web Service Presentation
Testing web services
Le jeu vidéo à la rescousse du web
Getting started with MySQL on Amazon Web Services
Xml interview questions
Marrying HTML5 and Angular to ADF - Oracle OpenWorld 2014 Preview
Php tutorial(w3schools)
Web services
Oracle ADF Overview for Beginners
Webservices(or)SoapUI Interview Questions
Restful Web Services
Web Services - A brief overview
Spring Web Services: SOAP vs. REST
Web services - A Practical Approach
Web Services - Architecture and SOAP (part 1)
Oracle JET CRUD and ADF BC REST
Ad

Similar to Web services tutorial (20)

PDF
Web Services Tutorial
ODP
Web Scraping with PHP
PDF
Php and-web-services-24402
PDF
Best Practices in Web Service Design
PDF
Don't screw it up! How to build durable API
PDF
Best Practice in Web Service Design
PDF
Php And Web Services
PDF
PHP and Web Services
PDF
Consuming RESTful Web services in PHP
PDF
When RSS Fails: Web Scraping with HTTP
PPTX
ODP
Starting With Php
PDF
Best Practice in API Design
ODP
PHP Training: Module 1
PDF
Designing RESTful APIs
PPTX
Day02 a pi.
PDF
Facebook & Twitter API
KEY
Designing a RESTful web service
PDF
What is REST?
PDF
The never-ending REST API design debate
Web Services Tutorial
Web Scraping with PHP
Php and-web-services-24402
Best Practices in Web Service Design
Don't screw it up! How to build durable API
Best Practice in Web Service Design
Php And Web Services
PHP and Web Services
Consuming RESTful Web services in PHP
When RSS Fails: Web Scraping with HTTP
Starting With Php
Best Practice in API Design
PHP Training: Module 1
Designing RESTful APIs
Day02 a pi.
Facebook & Twitter API
Designing a RESTful web service
What is REST?
The never-ending REST API design debate

More from Lorna Mitchell (20)

PDF
Git, GitHub and Open Source
PDF
Business 101 for Developers: Time and Money
ODP
Things I wish web graduates knew
PDF
Teach a Man To Fish (phpconpl edition)
ODP
Join In With Joind.In
PDF
Tool Up Your LAMP Stack
PDF
Going Freelance
PDF
Understanding Distributed Source Control
PDF
Coaching Development Teams: Teach A Man To Fish
PDF
Zend Certification Preparation Tutorial
PDF
Implementing OAuth with PHP
PDF
Object Oriented Programming in PHP
PDF
Example Presentation
PDF
Could You Telecommute?
PDF
Design Patterns
PDF
Running a Project with Github
PDF
27 Ways To Be A Better Developer
PDF
Digital Representation
PDF
Goodpractice
PDF
SPL Primer
Git, GitHub and Open Source
Business 101 for Developers: Time and Money
Things I wish web graduates knew
Teach a Man To Fish (phpconpl edition)
Join In With Joind.In
Tool Up Your LAMP Stack
Going Freelance
Understanding Distributed Source Control
Coaching Development Teams: Teach A Man To Fish
Zend Certification Preparation Tutorial
Implementing OAuth with PHP
Object Oriented Programming in PHP
Example Presentation
Could You Telecommute?
Design Patterns
Running a Project with Github
27 Ways To Be A Better Developer
Digital Representation
Goodpractice
SPL Primer

Recently uploaded (20)

PDF
Modernizing your data center with Dell and AMD
PDF
Empathic Computing: Creating Shared Understanding
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
DOCX
The AUB Centre for AI in Media Proposal.docx
PPT
Teaching material agriculture food technology
PDF
NewMind AI Monthly Chronicles - July 2025
PDF
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
PDF
solutions_manual_-_materials___processing_in_manufacturing__demargo_.pdf
PPTX
MYSQL Presentation for SQL database connectivity
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
PPTX
Cloud computing and distributed systems.
PDF
Electronic commerce courselecture one. Pdf
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
Review of recent advances in non-invasive hemoglobin estimation
PPTX
breach-and-attack-simulation-cybersecurity-india-chennai-defenderrabbit-2025....
PDF
Approach and Philosophy of On baking technology
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
PDF
cuic standard and advanced reporting.pdf
Modernizing your data center with Dell and AMD
Empathic Computing: Creating Shared Understanding
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
Advanced methodologies resolving dimensionality complications for autism neur...
The AUB Centre for AI in Media Proposal.docx
Teaching material agriculture food technology
NewMind AI Monthly Chronicles - July 2025
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
solutions_manual_-_materials___processing_in_manufacturing__demargo_.pdf
MYSQL Presentation for SQL database connectivity
“AI and Expert System Decision Support & Business Intelligence Systems”
Cloud computing and distributed systems.
Electronic commerce courselecture one. Pdf
Unlocking AI with Model Context Protocol (MCP)
Review of recent advances in non-invasive hemoglobin estimation
breach-and-attack-simulation-cybersecurity-india-chennai-defenderrabbit-2025....
Approach and Philosophy of On baking technology
The Rise and Fall of 3GPP – Time for a Sabbatical?
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
cuic standard and advanced reporting.pdf

Web services tutorial

  • 2. Lorna Mitchell • PHP Consultant/Developer/Trainer • API Specialist • Author and Speaker • Open Source Project Lead (http://joind.in) • Twitter: @lornajane • Site: http://lornajane.net 2
  • 3. Agenda • Web Services and a Simple Example • HTTP and Data Formats • Consuming Services from PHP • Service Types and Soap • RPC Services • Building RESTful services Code samples at: http://bit.ly/fE0f6f 3
  • 5. What Is A Web Service? • Means of exposing functionality or data • A lot like a web page • Integration between applications • Separation within an application 5
  • 6. Web Services and You This is not rocket science You already know most of what you need! 6
  • 7. Architecture Using APIs Common to use an API internally as well as exposing it 7
  • 9. Building Blocks You can make an API from any tools you like • Existing MVC setup • Simple PHP (as in these examples) • Framework module • Component library 9
  • 10. My First Web Service • 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.local ServerAdmin admin@localhost DocumentRoot /var/www/myapi/public <Directory /var/www/myapi/public> AllowOverride All Order deny,allow Allow from All </Directory> </VirtualHost> api.vhost 10
  • 11. My First Web Service • 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 11
  • 12. Consume Your Service • curl http://api.local • For more information about curl: • http://curl.haxx.se/ • http://bit.ly/esqBmz 12
  • 13. JSON JavaScript Object Notation • 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'} 13
  • 14. Heartbeat Method • A method which does nothing • No authentication • Requires correct request format • Gives basic feedback • Shows that service is alive 14
  • 15. Delivering A Web Service • Service • Documentation • Examples • A help point If you’re only going to build the service, don’t bother 15
  • 16. HTTP and Data Formats
  • 17. HTTP HTTP is Hypertext Transfer Protocol - we’ll recap on some key elements: • Status Codes (e.g. 200, 404) • Headers (e.g. Content-Type, Authorization) • Verbs (e.g GET, POST) 17
  • 18. Status Codes A headline response. Common codes: 200 OK 302 Found 301 Moved 401 Not Authorised 403 Forbidden 404 Not Found 500 Internal Server Error Consumers can get a WIN/FAIL indicator before unpacking the response in full 18
  • 19. Working with Status Codes in PHP 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); 19
  • 20. HTTP Verbs • More than GET and POST • PUT and DELETE to update and delete in a RESTful service • HEAD, OPTIONS and others also specified GET Read POST Create In REST, we use: PUT Update DELETE Delete 20
  • 21. HTTP Headers 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 21
  • 22. Accept Header 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 > Host: api.local > Accept: text/html > 22
  • 23. Using the Accept Header We can work out what format the user wanted to see from the Accept header. $data = array( 'status' => 'live', 'now' => time() ); if(false !== strpos($_SERVER['HTTP_ACCEPT'], 'text/html')) { echo "<pre>"; print_r($data); echo "</pre>"; } else { // return json echo json_encode($data); } public/headers.php 23
  • 24. Content-Type Header 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 json header('Content-Type: application/json'); echo json_encode($data); } public/headers.php 24
  • 25. Handling XML Formats 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 25
  • 26. Adding XML to Our Service $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(); The result is this: <?xml version="1.0"?> <data><status>live</status><now>1302981884</now></data> 26
  • 27. How to REALLY Handle Accept Headers Example accept header (from my browser) text/html, application/xml;q=0.9, application/xhtml+xml, 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 27
  • 28. Versions and Formats • Always include a version parameter or media type • Handle multiple formats, by header or parameter • JSON • XML • HTML • ? • Common to detect header, allow parameter override 28
  • 29. Statelessness • 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 29
  • 31. Consuming Your First Web Service Three ways to consume web services: • Via streams (e.g. file_get_contents and some context) • Using the curl extension • bit.ly/h5dhyT • Using Pecl_HTTP • bit.ly/g4CfPw 31
  • 32. Using File_Get_Contents This is the simplest, useful for GET requests $response = file_get_contents('http://api.local/'); var_dump($response); You can set more information in the stream context bit.ly/gxBAgV 32
  • 33. Using Curl 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 echo the output 33
  • 34. Using Pecl_HTTP This is the most powerful and flexible, and can easily be installed from http://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 on your platform 34
  • 36. Web Service Types There are a few types of web service • RESTful • RPC (Remote Procedure Call) • XML-RPC • JSON-RPC • Soap 36
  • 37. RPC Services These services typically have: • A single endpoint • Method names • Method parameters • A return value A familiar model for us as developers 37
  • 38. Soap • 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 38
  • 39. Soap Example: Library Class class Library { public function thinkOfANumber() { return 42; } public function thinkOfAName() { return 'Arthur Dent'; } } /public/soap/Library.php 39
  • 40. Publishing a Soap Service (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 40
  • 41. Consuming a Soap Service To call PHP directly, we would do: include('Library.php'); $lib = new Library(); $name = $lib->thinkOfAName(); echo $name; // Arthur Dent Over Soap: $options = array('uri' => 'http://api.local', 'location' => 'http://api.local/soap'); $client = new SoapClient(NULL, $options); $name = $client->thinkOfAName(); echo $name; // Arthur Dent 41
  • 42. Pros and Cons of Soap • Many languages have libraries for it • .NET and Java programmers in particular like it 42
  • 43. Pros and Cons of Soap • Many languages have libraries for it • .NET and Java programmers in particular like it • Weird things happen between languages regarding data types 42
  • 44. Pros and Cons of Soap • 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) 42
  • 45. Pros and Cons of Soap • 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! 42
  • 46. Working with WSDLs 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 in sections • Soap uses very strict data typing, which is an unknown concept in PHP Read about WSDLs: bit.ly/eNZOmp 43
  • 47. Debugging Soap The Soap extension has some debug methods: • Set the options to include trace=1 in the SoapClient • getLastRequest(), getLastRequestHeaders(), getLastResponse(), getLastResponseHeaders() are then available 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) 44
  • 48. Wireshark Demo Bear with me while I fire up wireshark to show you 45
  • 50. Consistency • Important to retain • Naming conventions • Parameter validation rules • Parameter order • Just as you would in library code 47
  • 51. The Action Parameter 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 48
  • 52. Small APIs • Beware adding new functionality • Simple is maintainable • Easy to use and understand 49
  • 53. Adding an Action To add a new action, create a new method for the Actions class, returning an 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 50
  • 54. Access Control 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 51
  • 55. RPC Service Example: Flickr 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 (see http://en.wikipedia.org/wiki/Xml-rpc) Vast numbers of applications using this API to provide flickr functionality elsewhere 52
  • 56. RPC vs REST We’ve seen an RPC service, but what about REST? The two are quite different • 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 53
  • 58. REST • 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/ 55
  • 59. REST as a Religion 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 business requirements • Flamewars will ensue Instead: "An HTTP Web Service" 56
  • 60. Making Our Service Restful 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 is called a collection 57
  • 61. All Requests to index.php We want to push all requests through index.php, there is an .htaccess file that does this <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php/$1 [L] </IfModule> /public/rest/.htaccess 58
  • 62. Routing Within Our App So our routing depends on the URL and on the verb used, so our controllers 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 59
  • 63. A Simple Controller 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 60
  • 64. Calling our Service Example uses curl, there are options $ch = curl_init('http://api.local/rest/users'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $result = curl_exec($ch); print_r(json_decode($result, true)); /public/rest-test.php 61
  • 65. Extending our Service Next we will add something to get the user’s friends http://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 62
  • 66. Hypermedia • 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 63
  • 67. Creating New Records RESTful services use POST for creating data, so we have POSTAction public function POSTAction($path, $data) { // sanitise and validate data please! // create a user from params $new_user['name'] = isset($data['name']) ? $data['name'] : ''; $new_user['house'] = isset($data['house']) ? $data['house'] : $new_user['age'] = isset($data['age']) ? $data['age'] : ''; // save the user, return the new id $new_user['self'] = 'http://' . $_SERVER['HTTP_HOST'] . '/rest // redirect user header('HTTP/1.1 201 Created'); header('Location: http://api.local/rest/users/5'); return $new_user; } /public/rest/controllers.php 64
  • 68. Incoming POST/PUT Data We read from php://input which is a stream. So for JSON: $verb = $_SERVER['REQUEST_METHOD']; $data = array(); switch($verb) { case 'GET': parse_str($_SERVER['QUERY_STRING'], $data); break; case 'POST': case 'PUT': // incoming JSON data, it's an array $data = json_decode(file_get_contents('php://input'), true); break; /public/rest/index.php 65
  • 69. POSTing JSON Data from PHP Adding some appropriate data handling and headers to the curl call: $data = array("name" => "Hagrid", "age" => "36"); $data_string = json_encode($data); $ch = curl_init('http://api.local/rest/users'); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, array( 'Content-Type: application/json', 'Content-Length: ' . strlen($data_string)) ); $result = curl_exec($ch); print_r(json_decode($result, true)); /public/rest-test.php 66
  • 70. Appropriate Status Codes for REST • 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 67
  • 71. Responding to Failure • Use expected response format • Collate all errors and return • Help users help themselves • Be consistent • Be accurate 68
  • 73. Technical Aspects All PHP Best Practices apply equally to APIs • Source control • Unit/Integration testing • Automated deployment • Monitoring Reliability and consistency are key 70
  • 74. User Aspects 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 71
  • 76. Resources All links are in the bit.ly bundle bit.ly/emRpYT 73
  • 77. Thanks • http://joind.in/talk/view/3461 • http://lornajane.net 74