Upload
others
View
3
Download
0
Embed Size (px)
Citation preview
Working With Web ServicesRob Richards
May 20, 2008
http://xri.net/=rob.richards
http://xri.net/=rob.richardshttp://xri.net/=rob.richards
• GET / POST
• Restful
• REST
• XML-RPC
• JSON-RPC
• SOAP
Common Types Of Services
2
GET / POST
• More Service Oriented– Actions are performed on the same/similar endpoints
– Parameters or Body drive actions
– Tend to be more free for all in design
– Perform Read/Write operations
• Any data format supported– XML
– JSON
Examples From Amazon EC2 Servicehttps://ec2.amazonaws.com/?Action=AllocateAddress&AWSAccessKeyId=...
https://ec2.amazonaws.com/?Action=CreateKeyPair&KeyName=example-key-name&AWSAccessKeyId=...
https://ec2.amazonaws.com/?Action=DescribeInstances&AWSAccessKeyId=...
3
https://ec2.amazonaws.com/?Action=AllocateAddress&AWSAccessKeyId=https://ec2.amazonaws.com/?Action=AllocateAddress&AWSAccessKeyId=https://ec2.amazonaws.com/?Action=CreateKeyPair&KeyName=example-key-name&AWSAccessKeyId=https://ec2.amazonaws.com/?Action=CreateKeyPair&KeyName=example-key-name&AWSAccessKeyId=https://ec2.amazonaws.com/?Action=CreateKeyPair&KeyName=example-key-name&AWSAccessKeyId=https://ec2.amazonaws.com/?Action=CreateKeyPair&KeyName=example-key-name&AWSAccessKeyId=
Amazon Simple Queue Service
$url = 'http://queue.amazonaws.com/queue1';$params = array('Action'=>'SendMessage', 'MessageBody' => 'Your%20Message%20Text', 'AWSAccessKeyId'=>'0GS755xyzEXAMPLE', . . .);
$post_body = http_build_query($params);$context_params = array( 'http' => array( 'method' => 'POST', 'header' => 'Content-Type: application/x-www-form-urlencoded', 'content' => $post_body ));$file_context = stream_context_create($context_params);
$results = file_get_contents($url, false, $file_context);var_dump($results);
4
http://queue.amazonaws.com/queue1'http://queue.amazonaws.com/queue1'
RESTful
• Generally follow REST guidelines
• Read-only data using HTTP GET
• URL path typically does not refer to resource
• Parameters influence results
Yahoo Image Search
http://search.yahooapis.com/ImageSearchService/V1/imageSearch?appid=YahooDemo&query=PHP+elephant&output=json
{"ResultSet":{"totalResultsAvailable":"561","totalResultsReturned":10,"firstResultPosition":1,"Result":[{"Title":"php_elephant.jpg","Summary":"php_elephant.jpg","Url":"http:\/\/vizzed.com\/VizzedBoardFiles\/upload\/php_elephant.jpg","ClickUrl":"http:\/\/vizzed.com\/VizzedBoardFiles\/upload\/php_elephant.jpg","RefererUrl":"http:\/\/vizzed.com\/VizzedBoardFiles\/upload","FileSize":7065,"FileFormat":"jpeg","Height":"96","Width":"150","Thumbnail":{"Url":"http:\/\/re3.yt-thm-a01.yimg.com\/image\/25\/m1\/2070796738","Height":"80","Width":"125"}} . . .
5
http://search.yahooapis.com/ImageSearchService/V1/imageSearch?appid=YahooDemo&query=PHP+elephant&output=jsonhttp://search.yahooapis.com/ImageSearchService/V1/imageSearch?appid=YahooDemo&query=PHP+elephant&output=jsonhttp://search.yahooapis.com/ImageSearchService/V1/imageSearch?appid=YahooDemo&query=PHP+elephant&output=jsonhttp://search.yahooapis.com/ImageSearchService/V1/imageSearch?appid=YahooDemo&query=PHP+elephant&output=json
Representational State Transfer: REST
• Endpoints are resource identifiers– A resource is any named item
– Resources are identified by URLs
• Architectural style not a standard
• Builds upon standards– HTTP
– URLS
– Mime types
• HTTP methods determine action
• Google APIs are good examples– Calendar
– Spreadsheet
– Notebook
6
HTTP Methods & Actions
7
HTTP CRUD
POST CREATE
GET RETRIEVE
PUT UPDATE
DELETE DELETE
HTTP CRUD
POST CREATE/UPDATE/DELETE
GET RETRIEVE
PUT CREATE/UPDATE
DELETE DELETE
Formal Operations Relaxed Operations
REST Retrieve Data
Retrieve private entries from a personal calendarUses HTTP GET
Retrieve All Entries:http://www.google.com/calendar/feeds//private/full
Retreive Specific Entry:http://www.google.com/calendar/feeds//private/full/cmanvsln9jk5e
Limit To Entries Within Date Range:http://www.google.com/calendar/feeds//private/full?start-min=2008-05-01T00:00:00&start-max=2008-05-31T23:59:59
8
http://www.google.com/calendar/feeds/http://www.google.com/calendar/feeds/http://www.google.com/calendar/feeds/http://www.google.com/calendar/feeds/http://www.google.com/calendar/feeds/http://www.google.com/calendar/feeds/
REST: Google Calendar Entry
http://www.google.com/calendar/feeds/default/private/full/asdc 2008-05-13T23:36:58.000Z 2008-05-13T23:44:44.000Z Tennis with John Meet for a quick lesson.. . . Rob Richards . . .
9
http://www.google.com/calendar/feeds/default/private/full/http://www.google.com/calendar/feeds/default/private/full/http://schemas.google.com/g/2005#kindhttp://schemas.google.com/g/2005#kindhttp://schemas.google.com/g/2005#eventhttp://schemas.google.com/g/2005#eventhttp://www.google.com/calendar/feeds/default/private/full/asdc/63346405484http://www.google.com/calendar/feeds/default/private/full/asdc/63346405484http://www.google.com/calendar/feeds/default/private/full/asdc/63346405484http://www.google.com/calendar/feeds/default/private/full/asdc/63346405484http://www.google.com/calendar/feeds/default/private/full/cbdmc5lksen8idhspn9jk5i76k/commentshttp://www.google.com/calendar/feeds/default/private/full/cbdmc5lksen8idhspn9jk5i76k/comments
REST Create Entry
POST Entry Datahttp://www.google.com/calendar/feeds/default/owncalendars/full
• URL Is Same As One Used By Calendar Retrieval• Content-Type is application/atom+xml• Successful Creation
- 201 Created status returned- Newly created Entry returned
• Failure returns other GData Status Code
10
http://www.google.com/calendar/feeds/default/owncalendars/fullhttp://www.google.com/calendar/feeds/default/owncalendars/full
REST Update Entry
URL used to edit an entry is located in the edit link:
HTTP PUT edited entry to edit URL
http://www.google.com/calendar/feeds/default/private/full/asdc 2008-05-13T23:36:58.000Z 2008-05-14T23:44:44.000Z Tennis with John Meet for a quick lesson.. . . Rob Richards . . .
11
http://www.google.com/calendar/feeds/default/private/full/asdc/63346405484http://www.google.com/calendar/feeds/default/private/full/asdc/63346405484http://www.google.com/calendar/feeds/default/private/full/asdc/63346405484http://www.google.com/calendar/feeds/default/private/full/asdc/63346405484http://www.google.com/calendar/feeds/default/private/full/asdchttp://www.google.com/calendar/feeds/default/private/full/asdc
REST Delete Entry
HTTP DELETE to edit URL
http://www.google.com/calendar/feeds/default/private/full/asdc/63346405484
Successful deletion returns status 200
12
http://www.google.com/calendar/feeds/default/private/full/asdc/63346405484http://www.google.com/calendar/feeds/default/private/full/asdc/63346405484http://www.google.com/calendar/feeds/default/private/full/asdc/63346405484http://www.google.com/calendar/feeds/default/private/full/asdc/63346405484http://www.google.com/calendar/feeds/default/private/full/cbdmc5lksen8idhspn9jk5i76k/63346405484http://www.google.com/calendar/feeds/default/private/full/cbdmc5lksen8idhspn9jk5i76k/63346405484http://www.google.com/calendar/feeds/default/private/full/cbdmc5lksen8idhspn9jk5i76k/63346405484http://www.google.com/calendar/feeds/default/private/full/cbdmc5lksen8idhspn9jk5i76k/63346405484
XML-RPC
• XML-based Remote Procedure Call
• Function call is marshaled
• Data structure defines method, types and values
• Parameters and return values are typed
• Defines how the messages is to be transported– HTTP POST
– Required HTTP Headers
• More Tightly Coupled
• Predecessor to SOAP
13
XML-RPC Request
HTTP POST: http://www.upcdatabase.com/rpc
lookupUPC 021000013425
14
upc 021000013425 description SUPER MAC & CHEESE SPONGE BO * size 5.5 oz
XML-RPC Response
15
JSON-RPC
• Comparable to XML-RPC though using JSON
• In addition to method and parameters, JSON-RPC includes an id property to map requests and responses
• Defines one-way communications (notifications)
• No specific transport protocol required
• HTTP POST most common transport
16
JSON-RPC Request
HTTP POST:http://www.raboof.com/Projects/Jayrock/Demo.ashx
Content-type: application/json
{"method":"total","params":{"values":[1,2,3]},"id":55}
$data = array("method"=>"total", "params"=>array("values"=>array(1,2,3)), "id" => 55);echo json_encode($data)."\n";$json = json_encode($data)
17
http://www.raboof.com/Projects/Jayrock/Demo.ashxhttp://www.raboof.com/Projects/Jayrock/Demo.ashx
JSON-RPC Response
{"id":55,"result":6}
$objResult = json_decode($results); echo $obResult->result."\n";
18
SOAP
• SOAP stands for ABSOLUTELY NOTHING!
• Can be RPC or Message based
• Strong data typing
• Designed for interoperability
• Can be simple to use
• Allows for advanced communications– Standard security mechanisms
– Message delivery guarantee
– Additional out of band information
– Addressing and callback capabilities
19
SOAP Message
[email protected] [email protected] this is a test test
20
http://schemas.xmlsoap.org/soap/envelope/http://schemas.xmlsoap.org/soap/envelope/http://schemas.xmlsoap.org/soap/encoding/http://schemas.xmlsoap.org/soap/encoding/mailto:[email protected]:[email protected]:[email protected]:[email protected]
SOAP Response
21
http://schemas.xmlsoap.org/soap/envelope/http://schemas.xmlsoap.org/soap/envelope/
Deciding Upon A Service
With All The Different Types Of Services, How Do You Decide
What To Use?
?22
Intended Audience
• Exposing To The Masses
• Internal Developers
• Business Partners
• Multiple Audiences
23
Security Implications
• Do you need to protect your data?
• Do users need to be authenticated?
• To what level do you need protection?
• Are multiple parties involved?
• Does the data pass through multiple systems?
• Do you need granularity?
24
What Is The Purpose?
• Reduce system maintenance?
• Expose existing logic as services?
• Expose logic from legacy systems?
• Aggregate functionality?
25
Any Curveballs?
• Two-phase commits
• Asynchronous Messaging
• Legacy System Protocols
• Multi-System Involvement
26
Let’s Get Our Hands Dirty!
Helpful Tools
• Eclipse– WSDL Editor
– XML / XSD Editors & Validators
• Misc. XML Editors– XML NotePad 2007 (Microsoft)
– XML Spy (Altova)
• soapUI– http://www.soapui.org
– Multiple platforms / Free & enhanced Pro versions
• SOAPSonar– http://www.crosschecknet.com
– Windows only / Free and Professional versions
28
http://www.soapui.orghttp://www.soapui.orghttp://www.crosschecknet.comhttp://www.crosschecknet.com
Yahoo Product Search
// URL to Product Search service$url = 'http://shopping.yahooapis.com/ShoppingService/V3/productSearch?';
// The query is separate here as the terms must be encoded.$url .= 'query='.rawurlencode('linksys');
// Complete the URL with App ID, limit to 1 result and start at second record$url .= "&appid=zzz&results=2&start=2";
$data = file_get_contents($url);
echo $data;
29
http://shopping.yahooapis.com/ShoppingService/V3/productSearch?'http://shopping.yahooapis.com/ShoppingService/V3/productSearch?'
Not So Simple
The following errors were detected:User-agent not valid
30
http://www.w3.org/2001/XMLSchema-instancehttp://www.w3.org/2001/XMLSchema-instancehttp://api.yahoo.com/Api/V1/error.xsdhttp://api.yahoo.com/Api/V1/error.xsdhttp://api.yahoo.com/Api/V1/error.xsdhttp://api.yahoo.com/Api/V1/error.xsd
Set The User Agent
$context_params = array( 'http' => array( 'user_agent' => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)' ));
$file_context = stream_context_create($context_params);
$data = file_get_contents($url, false, $file_context);
echo $data;
31
Yahoo Results
Computers & Software 1can1acp 7196 Networking 1can1gnetwork 5308 Network Adapters 1can1cnetworkZZZ5Fadapter
32
http://www.w3.org/2001/XMLSchema-instancehttp://www.w3.org/2001/XMLSchema-instancehttp://www.w3.org/2001/XMLSchema-instancehttp://www.w3.org/2001/XMLSchema-instancehttp://shopping.yahooapis.com/shoppingservice/v3/productsearch.xsdhttp://shopping.yahooapis.com/shoppingservice/v3/productsearch.xsdhttp://shopping.yahooapis.com/shoppingservice/v3/productsearch.xsdhttp://shopping.yahooapis.com/shoppingservice/v3/productsearch.xsd
We Want To Use SimpleXML Directly!
if ($sxe = simplexml_load_file($url)) { echo $sxe->Categories->SubCategory->Title;}
PHP Notice: Trying to get property of non-object in /Users/rrichards/tests/php/yahoo/shop.php on line 23
33
Stream Contexts and XML
$context_params = array( 'http' => array( 'user_agent' => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)' ));$xml_context = stream_context_create($context_params);
libxml_set_streams_context($xml_context);
if ($sxe = simplexml_load_file($url)) { echo $sxe->Categories->SubCategory->Title;}
Computers & Software
34
Google Calendar
35
Google Calendar Login
$url = 'https://www.google.com/accounts/ClientLogin';
$params = array('Email'=>'[email protected]', 'Passwd' => , 'source'=>'phpwebsvc-1', 'service' => 'cl');
$post_body = http_build_query($params);
$context_params = array( 'http' => array( 'method' => 'POST', 'header' => 'Content-Type: application/x-www-form-urlencoded', 'content' => $post_body ));$file_context = stream_context_create($context_params);
$results = file_get_contents($url, false, $file_context);
36
https://www.google.com/accounts/ClientLogin'https://www.google.com/accounts/ClientLogin'mailto:[email protected]:[email protected]
Google Calendar Login Using ext/http
$url = 'https://www.google.com/accounts/ClientLogin';$params = array('Email'=>'[email protected]', 'Passwd' => , 'source'=>'phpwebsvc-1', 'service' => 'cl');
$post_body = http_build_query($params);
$req->setBody($post_body);
$req->setContentType('application/x-www-form-urlencoded');
$msg = $req->send();
$results = $msg->getBody();
37
https://www.google.com/accounts/ClientLogin'https://www.google.com/accounts/ClientLogin'mailto:[email protected]:[email protected]
Google Calendar Our Login
SID=DQAAAIkAAAAnSKcLgj-iO123456789012345123456789012345gHq_QlR2ruTbbDsXoB5H2OWsgg-E4tEeq7U23o1234567890123455v9Nsf6AkYdf1234567890123458eCEjr867-5dO3Needaa6xoltHi-ryWGKrui1234567890123455U4x9WN-vafQHx3JanyysLSID=DQAAAIoAAACEji868ECURZS3GDZsfls8nl-3O5WoiPzboDD2lwJkAmcQ0Sbyg3SPAe0yxiJa123456789012345yk9123456789012345jaYrUxHerwl1wD4Uz603z1234567890123457OkD4dTewAw6YVQRMin123234567890123458xpJ0rAx1saURz9RKTKbjen2AoAuth=DQAAAIoAAACEji123456789012345ls8nl-3O5WoiPzboDD2123456789012345PAe0yxiJa7Tfzeyk9eB4B0hMgT5t_1234567890123454ejaYrUxHekJqc4fe7SaZYd123456789012345SjUK1kLrCualqsZTpBpS-T123456789012345g3RobFeGDh2Yv-68nHffw
38
Get Auth Token
$tokens = split("\n", $results);foreach ($tokens AS $current) { $artemp = split("=", $current); if ($artemp[0] == 'Auth') { $token = $artemp[1]; break; }}
39
Get Our Calendar Entries
$url = 'http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full';
$req = new HttpRequest($url, HttpRequest::METH_GET);
$req->addHeaders(array('Authorization' => "GoogleLogin auth=$token"));
$req->setOptions(array('redirect'=>1));
$msg = $req->send();
$cal = simplexml_load_string( $msg->getBody() );
echo $cal->asXML();
40
http://www.google.com/calendar/feeds/default/owncalendars/full'http://www.google.com/calendar/feeds/default/owncalendars/full'http://www.google.com/calendar/feeds/default/owncalendars/full'http://www.google.com/calendar/feeds/default/owncalendars/full'
Our Calendar Entries
http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full 3... http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/i3jg8t7ggoaj5l99dafue9ap1g 2008-05-17T16:23:49.000Z 2008-05-17T16:24:29.000Z Working With Web Services . . .
41
http://www.w3.org/2005/Atomhttp://www.w3.org/2005/Atomhttp://a9.com/-/spec/opensearchrss/1.0/http://a9.com/-/spec/opensearchrss/1.0/http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/fullhttp://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/fullhttp://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/fullhttp://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/fullhttp://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/i3jg8t7ggoaj5l99dafue9ap1ghttp://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/i3jg8t7ggoaj5l99dafue9ap1ghttp://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/i3jg8t7ggoaj5l99dafue9ap1ghttp://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/i3jg8t7ggoaj5l99dafue9ap1ghttp://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/i3jg8t7ggoaj5l99dafue9ap1ghttp://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/i3jg8t7ggoaj5l99dafue9ap1ghttp://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/i3jg8t7ggoaj5l99dafue9ap1ghttp://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/i3jg8t7ggoaj5l99dafue9ap1ghttp://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/i3jg8t7ggoaj5l99dafue9ap1g/63346724669http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/i3jg8t7ggoaj5l99dafue9ap1g/63346724669http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/i3jg8t7ggoaj5l99dafue9ap1g/63346724669http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/i3jg8t7ggoaj5l99dafue9ap1g/63346724669http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/i3jg8t7ggoaj5l99dafue9ap1g/63346724669http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/i3jg8t7ggoaj5l99dafue9ap1g/63346724669
New Entry
Cocktails Mashery cocktail event
42
http://www.w3.org/2005/Atom'http://www.w3.org/2005/Atom'http://schemas.google.com/g/2005'http://schemas.google.com/g/2005'http://schemas.google.com/g/2005#kind'http://schemas.google.com/g/2005#kind'http://schemas.google.com/g/2005#event'http://schemas.google.com/g/2005#event'http://schemas.google.com/g/2005#event.opaque'http://schemas.google.com/g/2005#event.opaque'http://schemas.google.com/g/2005#event.confirmed'http://schemas.google.com/g/2005#event.confirmed'
Create The Entry
$url = 'http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full';
$req = new HttpRequest($url, HttpRequest::METH_POST);
$req->setBody($myentry);
$req->setContentType('application/atom+xml');$req->setOptions(array('redirect'=>3));
$req->addHeaders(array('Authorization' => "GoogleLogin auth=$token"));
$msg = $req->send();
echo $msg->getBody();
43
http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full'http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full'http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full'http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full'
Now What???
No Error, But No New Entry
44
Inspecting The Transaction
$req = new HttpRequest($url, HttpRequest::METH_POST);$req->setBody($myentry);
$req->setContentType('application/atom+xml');$req->setOptions(array('redirect'=>3));$req->addHeaders(array('Authorization' => "GoogleLogin auth=$token"));
$msg = $req->send();
echo $msg->getBody();
var_dump($msg->getParentMessage());
45
Inspecting The Transaction
. . . ["responseStatus:protected"]=> string(17) "Moved Temporarily" ["responseCode:protected"]=> int(302) ["httpVersion:protected"]=> float(1.1) ["headers:protected"]=> array(8) { ["Location"]=> string(91) "http://www.google.com/calendar/feeds/default/private/full?gsessionid=ulqFh1tY96KwH2uR8QBKYw" ["Content-Type"]=> string(24) "text/html; charset=UTF-8" ["Date"]=> string(29) "Sat, 17 May 2008 17:04:23 GMT" ["Expires"]=> string(29) "Sat, 17 May 2008 17:04:23 GMT" ["Cache-Control"]=> string(18) "private, max-age=0" ["Content-Length"]=> . . .
46
http://www.google.com/calendar/feeds/default/private/full?gsessionid=ulqFh1tY96KwH2uR8QBKYwhttp://www.google.com/calendar/feeds/default/private/full?gsessionid=ulqFh1tY96KwH2uR8QBKYwhttp://www.google.com/calendar/feeds/default/private/full?gsessionid=ulqFh1tY96KwH2uR8QBKYwhttp://www.google.com/calendar/feeds/default/private/full?gsessionid=ulqFh1tY96KwH2uR8QBKYw
Fixed The URL
$url = 'http://www.google.com/calendar/feeds/default/private/full?gsessionid=ulqFh1tY96KwH2uR8QBKYw';
$req = new HttpRequest($url, HttpRequest::METH_POST);
$req->setBody($myentry);
$req->setContentType('application/atom+xml');$req->setOptions(array('redirect'=>3));
$req->addHeaders(array('Authorization' => "GoogleLogin auth=$token"));
$msg = $req->send();
echo $msg->getBody();
47
http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full'http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full'http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full'http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full'
Our New Entry
http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/ns4d6037c1kvrm4i5ena2oo9h4 Cocktails Mashery sponsored cocktails... ...
48
http://www.w3.org/2005/Atomhttp://www.w3.org/2005/Atomhttp://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/ns4d6037c1kvrm4i5ena2oo9h4http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/ns4d6037c1kvrm4i5ena2oo9h4http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/ns4d6037c1kvrm4i5ena2oo9h4http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/ns4d6037c1kvrm4i5ena2oo9h4http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/ns4d6037c1kvrm4i5ena2oo9h4/63346727478http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/ns4d6037c1kvrm4i5ena2oo9h4/63346727478http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/ns4d6037c1kvrm4i5ena2oo9h4/63346727478http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/ns4d6037c1kvrm4i5ena2oo9h4/63346727478http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/ns4d6037c1kvrm4i5ena2oo9h4/63346727478http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/ns4d6037c1kvrm4i5ena2oo9h4/63346727478http://schemas.google.com/g/2005#event.organizerhttp://schemas.google.com/g/2005#event.organizermailto:[email protected]:[email protected]
Our Calendar
49
Fix The Content, Time & Location
$url = 'http://www.google.com/calendar/feeds/default/private/full? start-min=2008-05-22&start-max=2008-05-23&q=Cocktails';$req = new HttpRequest($url, HttpRequest::METH_GET);$req->setContentType('application/atom+xml');$req->setOptions(array('redirect'=>3));$req->addHeaders(array('Authorization' => "GoogleLogin auth=$token"));$msg = $req->send();
if ($cal = simplexml_load_string( $msg->getBody() )) { foreach ($cal->entry AS $entry) { if ($entry->title == 'Cocktails') { $domentry = dom_import_simplexml($entry); $dom = new DOMDocument(); $myEntry = $dom->importNode($domentry, TRUE); $dom->appendChild($myEntry); } }}
50
http://www.google.com/calendar/feeds/default/private/full?start-min=2008-05-21T00:00:00&start-max=2008-05-21T23:59:59&q=Cocktails'http://www.google.com/calendar/feeds/default/private/full?start-min=2008-05-21T00:00:00&start-max=2008-05-21T23:59:59&q=Cocktails'http://www.google.com/calendar/feeds/default/private/full?start-min=2008-05-21T00:00:00&start-max=2008-05-21T23:59:59&q=Cocktails'http://www.google.com/calendar/feeds/default/private/full?start-min=2008-05-21T00:00:00&start-max=2008-05-21T23:59:59&q=Cocktails'
What Did We Find? (Summarized)
http://www.google.com/calendar/feeds/default/private/full/ns4d6037c1kvrm4i5ena2oo9h4 Cocktails Mashery sponsored cocktails
51
http://www.w3.org/2005/Atomhttp://www.w3.org/2005/Atomhttp://schemas.google.com/g/2005http://schemas.google.com/g/2005http://schemas.google.com/g/2005http://schemas.google.com/g/2005http://schemas.google.com/gCal/2005http://schemas.google.com/gCal/2005http://www.google.com/calendar/feeds/default/private/full/ns4d6037c1kvrm4i5ena2oo9h4http://www.google.com/calendar/feeds/default/private/full/ns4d6037c1kvrm4i5ena2oo9h4http://www.google.com/calendar/feeds/default/private/full/ns4d6037c1kvrm4i5ena2oo9h4http://www.google.com/calendar/feeds/default/private/full/ns4d6037c1kvrm4i5ena2oo9h4http://www.google.com/calendar/feeds/default/private/full/ns4d6037c1kvrm4i5ena2oo9h4/63346727478http://www.google.com/calendar/feeds/default/private/full/ns4d6037c1kvrm4i5ena2oo9h4/63346727478http://www.google.com/calendar/feeds/default/private/full/ns4d6037c1kvrm4i5ena2oo9h4/63346727478http://www.google.com/calendar/feeds/default/private/full/ns4d6037c1kvrm4i5ena2oo9h4/63346727478mailto:[email protected]:[email protected]://schemas.google.com/g/2005#event.organizerhttp://schemas.google.com/g/2005#event.organizermailto:[email protected]:[email protected]
Edit The Entry
$gSession = '?gsessionid=3IqBQirtNrir7o4nNTCSDA';$gdNS = 'http://schemas.google.com/g/2005';
$entry = simplexml_import_dom($dom);$entry->content = 'Mashery cocktail event';
$when = $entry->children($gdNS)->when->attributes();$when['startTime'] = '2008-05-22T17:30:00.000-05:00';$when['endTime'] = '2008-05-22T19:30:00.000-05:00';
$where = $entry->children($gdNS)->where->attributes();$where['valueString'] = '11th Floor';
foreach ($entry->link AS $link) { if ($link['rel'] == 'edit') { $updateUrl = $link['href'] . $gSession; $contentType = $link['type']; }}
52
http://schemas.google.com/g/2005'http://schemas.google.com/g/2005'
Edited Entry (Summarized)
http://www.google.com/calendar/feeds/default/private/full/ns4d6037c1kvrm4i5ena2oo9h4 Cocktails Mashery cocktail event
53
http://www.w3.org/2005/Atomhttp://www.w3.org/2005/Atomhttp://schemas.google.com/g/2005http://schemas.google.com/g/2005http://schemas.google.com/g/2005http://schemas.google.com/g/2005http://schemas.google.com/gCal/2005http://schemas.google.com/gCal/2005http://www.google.com/calendar/feeds/default/private/full/ns4d6037c1kvrm4i5ena2oo9h4http://www.google.com/calendar/feeds/default/private/full/ns4d6037c1kvrm4i5ena2oo9h4http://www.google.com/calendar/feeds/default/private/full/ns4d6037c1kvrm4i5ena2oo9h4http://www.google.com/calendar/feeds/default/private/full/ns4d6037c1kvrm4i5ena2oo9h4http://www.google.com/calendar/feeds/default/private/full/ns4d6037c1kvrm4i5ena2oo9h4/63346727478http://www.google.com/calendar/feeds/default/private/full/ns4d6037c1kvrm4i5ena2oo9h4/63346727478http://www.google.com/calendar/feeds/default/private/full/ns4d6037c1kvrm4i5ena2oo9h4/63346727478http://www.google.com/calendar/feeds/default/private/full/ns4d6037c1kvrm4i5ena2oo9h4/63346727478mailto:[email protected]:[email protected]://schemas.google.com/g/2005#event.organizerhttp://schemas.google.com/g/2005#event.organizermailto:[email protected]:[email protected]
Call The Update
$req = new HttpRequest($updateUrl, HttpRequest::METH_PUT);
$req->setPutData($entry->asXML());$req->setContentType($contentType);
$req->setOptions(array('redirect'=>3));
$req->addHeaders(array('Authorization' => "GoogleLogin auth=$token"));$msg = $req->send();
echo $msg->getBody();
54
Updated Calendar
55
Working With SOAP
• Web Service Inspection– WSDL Inspector
– HTTP data inspection (request & response)
• Web Service Invocation– Automatic Request generation
– Authentication support (Basic, Digest, WS-Security)
– Custom HTTP Header support
• Web Service Development and Validation
• Web Service Functional Testing
• Web Service Load Testing
• Web Service Simulation
soapUI Features
57
Working With soapUI
58
Eclipse WSDL Editing
59
Eclipse WSDL Editing
60
Eclipse XML Schema Editing
61
OpenCalais Service
• http://www.opencalais.com/
• Powered by Reuters
• Extracts semantic metadata from documents
• Results returned in RDF (Resource Description Framework) format
• Become part of the Semantic Web
• Service is Free!
62
http://www.opencalais.comhttp://www.opencalais.com
Inspect The API
$wsdl = 'http://api.opencalais.com/enlighten/?wsdl';
$client = new SOAPClient($wsdl);
$types = $client->__getTypes();foreach ($types AS $type) { echo $type."\n";}echo "\n\n";
$functions = $client->__getFunctions();foreach ($functions AS $func) { echo $func."\n";}
63
http://api.opencalais.com/enlighten/?wsdl'http://api.opencalais.com/enlighten/?wsdl'
OpenCalais API
struct Enlighten { string licenseID; string content; string paramsXML;}struct EnlightenResponse { string EnlightenResult;}
EnlightenResponse Enlighten(Enlighten $parameters)string Enlighten(string $licenseID, string $content, string $paramsXML)
64
Working With Structs
From WSDLstruct Enlighten { string licenseID; string content; string paramsXML;}
IN PHP
array('licenseID' => x, 'content' => y, 'paramsXML'=>z)
class Enlighten { public $licenseID; public $content; public $paramsXML;}
65
Making The Request
$_content =
Making The Request
$_ paramsXML =
Making The Request
$wsdl = 'http://api.opencalais.com/enlighten/?wsdl';
$client = new SOAPClient($wsdl);
$result = $client->Enlighten( array( 'licenseID' => '', 'content' => $_content, 'paramsXML' => $_paramsXML ));
echo $result->EnlightenResult;
68
http://api.opencalais.com/enlighten/?wsdl'http://api.opencalais.com/enlighten/?wsdl'
The Response (Edited)
... Norman Mineta political
[the current system," Transportation Secretary ]Norman Mineta[ said in a statement. The newly ratified accord] 1765 13 ...
69
http://www.w3.org/1999/02/22-rdf-syntax-ns#http://www.w3.org/1999/02/22-rdf-syntax-ns#http://s.opencalais.com/1/pred/http://s.opencalais.com/1/pred/http://d.opencalais.com/pershash-1/37225f05-d55e-3512-9808-4ff11370db12http://d.opencalais.com/pershash-1/37225f05-d55e-3512-9808-4ff11370db12http://s.opencalais.com/1/type/em/e/Personhttp://s.opencalais.com/1/type/em/e/Personhttp://d.opencalais.com/dochash-1/11af6c89-9a70-331e-b113-12546ced5d10/Instance/1http://d.opencalais.com/dochash-1/11af6c89-9a70-331e-b113-12546ced5d10/Instance/1http://s.opencalais.com/1/type/sys/InstanceInfohttp://s.opencalais.com/1/type/sys/InstanceInfohttp://d.opencalais.com/dochash-1/11af6c89-9a70-331e-b113-12546ced5d10http://d.opencalais.com/dochash-1/11af6c89-9a70-331e-b113-12546ced5d10http://d.opencalais.com/pershash-1/37225f05-d55e-3512-9808-4ff11370db12http://d.opencalais.com/pershash-1/37225f05-d55e-3512-9808-4ff11370db12
What About the Other Method Signature?
$wsdl = 'http://api.opencalais.com/enlighten/?wsdl';
try {
$client = new SOAPClient($wsdl);
$result = $client->Enlighten('', $_content,
$_paramsXML);
echo $result->EnlightenResult;
} catch (Exception $e) {
echo "Fault: " . $e->faultstring."\n";
echo "Code: " . $e->faultcode."\n";
}
70
http://api.opencalais.com/enlighten/?wsdl'http://api.opencalais.com/enlighten/?wsdl'
When Things Go Wrong...
Fault: ForbiddenCode: HTTP
71
Enter Debug Mode
$wsdl = 'http://api.opencalais.com/enlighten/?wsdl';
$options = array('trace' => 1);
try { $client = new SOAPClient($wsdl, $options);
$result = $client->Enlighten('', $_content, $_paramsXML); echo $result->EnlightenResult;} catch (Exception $e) {
echo $client->__getLastRequest();
}
72
Our Request
NEWS
http://biz.yahoo.com/rb/030905/airlines_damages_1.html
...
73
http://schemas.xmlsoap.org/soap/envelope/http://schemas.xmlsoap.org/soap/envelope/http://schemas.xmlsoap.org/soap/envelope/http://schemas.xmlsoap.org/soap/envelope/http://clearforest.comhttp://clearforest.comhttp://biz.yahoo.com/rb/030905/airlines_damages_1.htmlhttp://biz.yahoo.com/rb/030905/airlines_damages_1.htmlhttp://biz.yahoo.com/rb/030905/airlines_damages_1.htmlhttp://biz.yahoo.com/rb/030905/airlines_damages_1.htmlhttp://s.opencalais.com/1/pred/http://s.opencalais.com/1/pred/http://s.opencalais.com/1/pred/http://s.opencalais.com/1/pred/
Let’s Try soapUI
74
Other Debugging Functions
SOAPClient::__getLastRequest()– Get the raw SOAP request
SOAPClient::__getLastRequestHeaders()– Get the HTTP headers sent with the request
SOAPClient::__getLastResponse()– Get the response from the server
SOAPClient::__getLAstResponseHeaders()– Get the HTTP headers received from the server
75
Server Sided SOAP
DISABLE WSDL CACHINGWHEN DEVELOPING!
ini_set("soap.wsdl_cache_enabled", "0");
Disable That Cache
77
Generating The WSDL
• Integrated Generators– Services_Webservices
• http://pear.php.net/package/Services_Webservice
– PRADO
• http://pradosoft.com/demos/quickstart/?page=Services.SoapService
– WSO2 WSF/PHP (http://wso2.org/projects/wsf/php)
• External Tools– Eclipse WSDL Editor in Web Tools Platform (WTP)
– Zend Studio (http://www.zend.com/en/products/studio/)
78
http://pear.php.net/package/Services_Webservicehttp://pear.php.net/package/Services_Webservicehttp://pradosoft.com/demos/quickstart/?page=Services.SoapServicehttp://pradosoft.com/demos/quickstart/?page=Services.SoapServicehttp://wso2.org/projects/wsf/phphttp://wso2.org/projects/wsf/phphttp://www.zend.com/en/products/studio/http://www.zend.com/en/products/studio/
Services_Webservice WSDL Generation
include_once('Services/Webservice.php'); class myService extends Services_Webservice { /** * Says "Hello!" * * @param int * @return string */ public function hello($i ) { //create some logic here return 'myString'; }
79
Serving Up The WSDL
Server Script: myserv.php
/* Helper functions here */$soapSrv = new SoapServer('helloworld.wsdl');
/* Register functions */$soapSrv->handle();
Using the SoapClient:$soapClient = new SoapClient( 'http://localhost/myserv.php?wsdl');
80
Handling Requests
• The typical method to process a SOAP request– $soapServer->handle();
• Request may be passed to handler– $soapServer->handle($request);
• Passing in the request can be handy– You can be guaranteed of the same request while debugging
– Debugging can be performed via CLI
– Requests can be modified prior to being processed
81
Handling Requests: Debugging
/* create the initial request to be re-used */$request = file_get_contents("php://input");file_save_contents('debugging.xml', $request);
/* retrieve saved request on subsequent calls$request = file_get_contents('debugging.xml');*/
$server = new SoapServer($wsdl);/* Setup function handlers */$server->handle($request);
82
Creating Our Service
class cSayHello { private $date = NULL;
function __construct($date) { $this->_date = $date; }
function greet($name, $age) { return "Hello $name. Today is" . $this->_date . ". You are $age"; }}
Our Logic
84
Skeleton Server
ini_set("soap.wsdl_cache_enabled", "0");class cSayHello { private $date = NULL;
function __construct($date) { $this->_date = $date; }
function greet($name, $age) { return "Hello $name. Today is" . $this->_date . ". You are $age"; }}
$srv = new SOAPServer();$srv->setClass('cSayHello', date());
$srv->handle();
85
Create The WSDL
86
Creating The WSDL
87
Creating The WSDL
88
Calling The Client
PHP Fatal error: Uncaught SoapFault exception: [Client] looks like we got no XML document in /Users/rrichards/Sites/fizzer/tek/PHPTek/demo/soapclient-step1.php:4Stack trace:#0 [internal function]: SoapClient->__call('greet', Array)#1 /Users/rrichards/Sites/fizzer/tek/PHPTek/demo/soapclient-step1.php(4): SoapClient->greet(Array)#2 {main} thrown in /Users/rrichards/Sites/fizzer/tek/PHPTek/demo/soapclient-step1.php on line 4
89
Debugging The Server
ini_set("soap.wsdl_cache_enabled", "0");
//file_put_contents('/tmp/myclient.xml', file_get_contents('php://input'));$input = file_get_contents('/tmp/myclient.xml');class cSayHello { private $date = NULL;
function __construct($date) { $this->_date = $date; }
function greet($name, $age) { return "Hello $name. Today is" . $this->_date . ". You are $age"; }}
$srv = new SOAPServer('myservice.wsdl');$srv->setClass('cSayHello', date());
$srv->handle($input);
90
Execute The Server Code
PHP Warning: date() expects at least 1 parameter, 0 given in /Users/rrichards/Sites/fizzer/tek/PHPTek/demo/soapsrv.php on line 23
PHP Warning: Missing argument 2 for cSayHello::greet() in /Users/rrichards/Sites/fizzer/tek/PHPTek/demo/soapsrv.php on line 15
91
Fix Server Code
ini_set("soap.wsdl_cache_enabled", "0");$input = file_get_contents('/tmp/mysoapclient.xml');
class cSayHello { private $date = NULL;
function __construct($date) { $this->_date = $date; }
function greet($objGreet) { return "Hello $objGreet->name. Today is" . $this->_date . ". You are $objGreet->age"; }}
$srv = new SOAPServer('myservice.wsdl');$srv->setClass('cSayHello', date('F j, Y'));
$srv->handle($input);
92
The Server Response
Hello Rob. Today isMay 18, 2008. You are 37
93
http://schemas.xmlsoap.org/soap/envelope/http://schemas.xmlsoap.org/soap/envelope/
Service Component Architecture (SCA)
• Project by the Open Service Oriented Architecture (OSOA) collaboration - http://www.osoa.org/display/Main/Home
• http://www.osoa.org/display/PHP/SOA+PHP+Homepage
• Combined with the SDO extension
• Pecl repository: http://pecl.php.net/package/SCA_SDO
• Allows the developer to concentrate on the business logic rather than how it is all connected together
Service Component Architecture (SCA)
95
http://www.osoa.org/display/Main/Homehttp://www.osoa.org/display/Main/Homehttp://www.osoa.org/display/PHP/SOA+PHP+Homepagehttp://www.osoa.org/display/PHP/SOA+PHP+Homepagehttp://pecl.php.net/package/SCA_SDOhttp://pecl.php.net/package/SCA_SDO
SCA Benefits
• Support multiple protocols without additional coding
• Re-usable code through the separation of business logic and communication layers
• Local and remote integration transparency
• Simplify consumption and exposure of web services
96
SCA Components
97
BusinessLogic
Annotations
Binding Types
Data Types
InterfaceDescription
SOAP Request
JSON Request
REST Request
Developer’sResponsibility
SCA Component
include "SCA/SCA.php";
/** * @service * @binding.soap * @binding.jsonrpc * @binding.rest.rpc */
class RobsService {
/** Find out who I am. * @return string Who I am. */ public function whoAmI() { return "I am Rob Richards"; } }
98
Calling The Component
include "SCA/SCA.php"; $url = 'http://localhost/robsService.php';
/* Use SOAP Binding */ $robservice = SCA::getService($url.'?wsdl'); $whoami = $robservice->whoAmI();
/* Use JSON Binding */ $robservice = SCA::getService($url.'?smd'); $whoami = $robservice->whoAmI();
/* Use Native SOAP */ $client = new SoapClient($url.'?wsdl'); $whoami = $client->whoAmI();
/* Use RESTful Call */ $whoami = file_get_contents($url.'/whoAmI');
/* Use Local Binding */ $robservice = SCA::getService('/home/rrichards/robweb/robsService.php'); $whoami = $robservice->whoAmI();
99
http://localhost/robsService.php'http://localhost/robsService.php'
Complex Types
include "SCA/SCA.php";
/** * @service * @binding.soap * @binding.jsonrpc * @types urn::people PeopleTypes.xsd*/
100
Complex Types
101
http://www.w3.org/2001/XMLSchemahttp://www.w3.org/2001/XMLSchema
Creating The XML Schema
102
Creating The XML Schema
103
Finishing Off The Component
class ComplexService {
/** Find out who I am. * @param int $id My ID * @return PersonType urn::people Who I am. */ public function whoAmI($id) { $person = SCA::createDataObject('urn::people', 'PersonType'); $person->Name = 'Rob Richards'; $person->ID = $id; $person->TimeStamp = time(); return $person; } }
104
Calling The Component
$url = 'http://fizzer/tek/PHPTek/SCA/ComplexService.php';
$complexservice = SCA::getService($url.'?wsdl'); $whoami = $complexservice->whoAmI(12);
var_dump($whoami);
object(SDO_DataObjectImpl)#11 (3) { ["Name"]=> string(12) "Rob Richards" ["ID"]=> string(2) "12" ["TimeStamp"]=> string(10) "1211136763"}
105
http://fizzer/tek/PHPTek/SCA/ComplexService.php'http://fizzer/tek/PHPTek/SCA/ComplexService.php'
Referencing Components
class ReferenceService { /** * Get The WhoAmI from robsService * * @reference * @binding.php robsService.php */ public $robs_service;
106
Referencing Components (cont’d)
/** Find out who I am. * @param int $id My ID * @return PersonType urn::people Who I am. */ public function whoAmI($id) { $person = SCA::createDataObject('urn::people', 'PersonType'); $person->Name = $this->robs_service->whoAmI(); $person->ID = $id; $person->TimeStamp = time(); return $person; } }
107
Calling New Component
$url = 'http://fizzer/tek/PHPTek/SCA/ReferenceService.php';
$referenceservice = SCA::getService($url.'?wsdl'); $whoami = $referenceservice->whoAmI(12);
var_dump($whoami);
object(SDO_DataObjectImpl)#16 (3) { ["Name"]=> string(17) "I am Rob Richards" ["ID"]=> string(2) "12" ["TimeStamp"]=> string(10) "1211136763"}
108
http://fizzer/tek/PHPTek/SCA/ReferenceService.php'http://fizzer/tek/PHPTek/SCA/ReferenceService.php'
SCA: More Information
• Where To Get It– PECL package SCA_SDO
– http://pecl.php.net/sca_sdo
• Documentation, Wiki, Examples– PHP Manual SCA and SDO XML Data Access Service
– Open Service Oriented Architecture http://www.osoa.org/display/PHP/
• Mail List – http://groups.google.com/group/phpsoa
109
http://pecl.php.net/sca_sdohttp://pecl.php.net/sca_sdohttp://www.osoa.org/display/PHP/http://www.osoa.org/display/PHP/http://groups.google.com/group/phpsoahttp://groups.google.com/group/phpsoa
WSO2 Web Services Framework for PHP
(WSO2 WSF/PHP)http://wso2.org/projects/wsf/php
http://wso2.org/projects/wsf/phphttp://wso2.org/projects/wsf/php
• Web Service Provider and Consumer– SOAP
– REST
• WS-* Support– WS-Addressing
– WS-Security / WS-SecurityPolicy
– WS-ReliableMessaging
• MTOM Support for attachments
• WSDL Generation
• PHP Class generation from WSDL
WSO2 WSF/PHP
111
Raw Request
$client = new WSClient(array("to"=> "http://172.16.183.129/transpers.php"));
$message =
WSDL Request
$client = new WSClient(array("wsdl"=> "http://172.16.183.129/transformer.wsdl"));
$proxy = $client->getProxy();
$myperson = array('fname' => 'Joe', 'lname' => 'Schmoe');
$res = $proxy->getPerson($myperson);var_dump($res);
113
http://172.16.183.129/transformer.wsdlhttp://172.16.183.129/transformer.wsdl
Raw Response
function getPerson($message) { $sxe = simplexml_load_string($message->str);
$response = “ {$sxe->fname} {$sxe->lname} ”.rand(18,100).”. ”.(rand(0,1)?'M':'F').” ”; return new WSMessage($response);}
$soapSrv = new WSService(array("operations" => array("getPerson")));$soapSrv->reply();
114
WSDL Response
function getPersonfunc($fname, $lname) { return array('fullname' => $fname." ".$lname, 'age' => rand(18,100), 'sex' => (rand(0,1)?'M':'F'));}
$operations = array("getPerson"=>"getPersonfunc");$opParams = array("getPersonfunc"=>"MIXED");
$service = new WSService(array("wsdl"=>"transformer2.wsdl", "operations" => $operations, "opParams"=>$opParams)); $service->reply();
115
REST
$requestPayloadString = "myDemoPro PHP XML";
try { $client = new WSClient( array("to"=>"http://search.yahooapis.com/WebSearchService/V1/webSearch", "HTTPMethod"=>GET, "useSOAP"=>FALSE));
$responseMessage = $client->request($requestPayloadString); $results = simplexml_load_string($responseMessage->str);
echo 'Total Results: '.$results['totalResultsAvailable']."\n\n";
} catch (WSFault $e) { echo $e->Reason;}
116
http://search.yahooapis.com/WebSearchService/V1/webSearchhttp://search.yahooapis.com/WebSearchService/V1/webSearch
Advanced Usage
$randNum = (rand()%99);
$reqDate = mktime(0,0,0,date("m"),date("d")+14,date("Y"));$reqDateStr = date("Y/m/d", $reqDate); /* The payload string*/$requestPayloadString =
Attachments
try { /* Load the design*/ $f = file_get_contents("./design.jpg"); /* Build the message*/ $requestMessage = new WSMessage($requestPayloadString, array("to" => "http://localhost/store/manuf_service.php", "action" => "http://www.back_packers.com/purchaseOrder", "attachments" => array("myid1" => $f)));
118
http://localhost/wsf/input.phphttp://localhost/wsf/input.phphttp://www.backhttp://www.back
Policy & WS-SecurityPolicy
// Use WS-Policy File$policy_xml = file_get_contents("policy.xml");//$policy = new WSPolicy($policy_xml);
// Use policy options$policy = new WSPolicy( array( "security" => array("encrypt"=>TRUE, "sign"=>TRUE, "algorithmSuite" => "Basic256Rsa15", "protectionOrder" => "EncryptBeforeSigning", "encryptSignature" => true, "includeTimeStamp" => true)));
119
WS-SecurityPolicy
120
WS-Security
$rec_cert = ws_get_cert_from_file("bob_cert.cert"); $my_cert = ws_get_cert_from_file("alice_cert.cert"); $my_key = ws_get_key_from_file("alice_key.pem");
/* Ceate a security token with reqd configurations*/ $sec_token = new WSSecurityToken(array("user" => "Alice", "password" => "abcd!1234", "passwordType" => "Digest", "privateKey" => $my_key, "certificate" => $my_cert, "receiverCertificate" => $rec_cert));
121
Making The Request
/* Create a new client*/ $client = new WSClient(array("useWSA" => TRUE, "useMTOM" => FALSE, "policy" => $policy, "securityToken" => $sec_token)); /* Request*/ $responseMessage = $client->request($requestMessage); /* Print the response*/ echo $responseMessage->str;
} catch (WSFault $e) { echo $e->Reason;}
122
Working With Web Services
Rob Richards
http://www.cdatazone.orghttp://xri.net/=rob.richards
http://www.cdatazone.orghttp://www.cdatazone.orghttp://xri.net/=rob.richardshttp://xri.net/=rob.richards
We Are Hiring PHP & AJAX Developers Contact us: [email protected]
OPEN TO ALL We want to meet you! Please join us for complimentary pizza
and beer (or your drink of choice)
Sheraton Gateway Suites O'Hare 11th floor
Thursday, May 22nd 5:30 - 7:30pm
mailto:[email protected]:[email protected]