Successfully reported this slideshow.
Your SlideShare is downloading. ×

Architecting Web Services

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Loading in …3
×

Check these out next

1 of 44 Ad

More Related Content

Advertisement

More from Lorna Mitchell (20)

Recently uploaded (20)

Advertisement

Architecting Web Services

  1. 1. Architecting Web Services Lorna Mitchell, Ibuildings
  2. 2. About Me <ul><li>PHP Developer/Consultant/Trainer with Ibuildings
  3. 3. PHP community evangelist
  4. 4. Blog at http://lornajane.net </li></ul>
  5. 5. Web Services <ul><li>Provide information in machine-readable format
  6. 6. For local or remote consumption
  7. 7. For consumption by discrete/modular systems </li></ul>
  8. 8. Why Web Services
  9. 9. Why Web Services
  10. 10. Why Web Services
  11. 11. Why Web Services
  12. 12. Service Types <ul><li>RPC (Remote Procedure Call)
  13. 13. SOAP
  14. 14. REST (REpresentational State Transfer) </li></ul>
  15. 15. RPC <ul><li>All URLs point to a single endpoint
  16. 16. Parameters give method names
  17. 17. Request body can take a variety of formats </li></ul>
  18. 18. RPC Advantages <ul><li>RPC is a great format for wrapping existing functionality
  19. 19. Can abstract between existing systems
  20. 20. Familiar functional paradigm </li></ul>
  21. 21. RPC Example Flickr's XML-RPC Request <methodCall> <methodName> flickr.test.echo </methodName> <params> <param><value><struct> <member> <name> name </name> <value><string> value </string></value> </member> <member> <name> name2 </name> <value><string> value2 </string></value> </member> </struct></value></param> </params> </methodCall>
  22. 22. RPC Example Flickr's XML-RPC Response <?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?> <methodResponse> <params> <param> <value> <string> [escaped-xml-payload] </string> </value> </param> </params> </methodResponse>
  23. 23. Delivering RPC <ul><li>Consumers will need </li></ul><ul><ul><li>Service URL
  24. 24. Docs of functions and arguments
  25. 25. If this was an existing system, existing docs may suffice </li></ul></ul>
  26. 26. SOAP <ul><li>Special case of RPC using XML
  27. 27. Has given formats for messages and errors
  28. 28. Libraries exist for creating server and client in most languages </li></ul>
  29. 29. PHP SOAP Server Example require_once('lib/myClass.php'); ini_set(&quot;soap.wsdl_cache_enabled&quot;, &quot;0&quot;); $server = new SoapServer(&quot;service.wsdl&quot;); $server->setClass(&quot;MyClass&quot;); $server->handle();
  30. 30. PHP SOAP Client Example ini_set('soap.wsdl_cache_enabled','0'); require_once('lib/Snapshot.php'); $wsdl = &quot;Service.wsdl&quot;; $client = new SoapClient($wsdl, $params); $output = $client->requestShot( 'http://www.php.net','', 300, 400);
  31. 31. WSDL <ul><li>Web Service Description Language
  32. 32. Widely used with SOAP
  33. 33. Describes the methods, arguments and data types available
  34. 34. IDEs can read this and hint
  35. 35. Validity of requests is checked before they are sent </li></ul>
  36. 36. WSDL <?xml version ='1.0' encoding ='UTF-8' ?> <definitions name='MyClass' targetNamespace='urn:MyClassInventory' xmlns:tns='urn:MyClassInventory' xmlns:soap=' http://schemas.xmlsoap.org/wsdl/soap/ ' xmlns:xsd=' http://www.w3.org/2001/XMLSchema ' xmlns:soapenc=' http://schemas.xmlsoap.org/soap/encoding/ ' xmlns:wsdl=' http://schemas.xmlsoap.org/wsdl/ ' xmlns='http://schemas.xmlsoap.org/wsdl/'> <message name='getAccountStatusRequest'> <part name='accountID' type='xsd:string'/> </message> <message name='getAccountStatusResponse'> <part name='accountID' type='xsd:string'/> <part name='counter' type='xsd:float' /> </message> <portType name='MyClassPortType'> <operation name='getAccountStatus'> <input message='tns:getAccountStatusRequest'/> <output message='tns:getAccountStatusResponse'/> </operation> </portType> <binding name='MyClassBinding' type='tns:MyClassPortType'> <soap:binding style='rpc' transport='http://schemas.xmlsoap.org/soap/http'/> <operation name='getAccountStatus'> <soap:operation soapAction='urn:xmethods-delayed-quotes#getAccountStatus'/> <input> <soap:body use='encoded' namespace='urn:xmethods-delayed-quotes' encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/> </input> <output> <soap:body use='encoded' namespace='urn:xmethods-delayed-quotes' encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/> </output> </operation> </binding> <service name='MyClassService'> <port name='MyClassPort' binding='tns:MyClassBinding'> <soap:address location='http://rivendell.local:10002/MyClassServiceServer.php'/> </port> </service> </definitions>
  37. 37. Delivering SOAP <ul><li>In WSDL mode, only the WSDL needs to be supplied
  38. 38. Otherwise method names, arguments and types will be needed </li></ul>
  39. 39. REST <ul><li>A series of concepts
  40. 40. Generally uses HTTP (HyperText Transfer Protocol)
  41. 41. URLs are resource locations
  42. 42. Verbs tell the service what to do
  43. 43. Status codes indicate what the outcome was </li></ul>
  44. 44. Implementing REST <ul><li>Standard application architecture
  45. 45. Routing to map requests to internal functionality
  46. 46. Output not always HTML </li></ul>
  47. 47. REST Examples <ul><li>GET http://example.com/users/lorna
  48. 48. POST http://example.com/users
  49. 49. PUT http://example.com/users/lorna
  50. 50. GET http://example.com/users </li></ul>
  51. 51. Delivering REST <ul><li>Full documentation including URL formats, data types, and response formats
  52. 52. Must include information about error handling </li></ul>
  53. 53. REST as an inspiration <ul><li>RESTful is a strict definition
  54. 54. REST is full of great ideas
  55. 55. REST is great for clean, simple, robust services
  56. 56. Cherry-pick the bits that work </li><ul><li>Just don't call it &quot;RESTful&quot; :) </li></ul></ul>
  57. 57. General Architecture Considerations
  58. 58. Machine-Readable Formats 1111011110101000001101011011110001001101011111011000101010001011010100001110110111101001111110011100110010100110011000111100011000000111100000011001001101000001011100101101011011100010010111000001111010000100100010010101010101110110000000100101101110100000111001000010100010011111111010001010110000010100000101011000001000000100110000100100110010101001110101100001010110001111000101110111011110010011110101101100110111100111101000001010100100110111001111111010000000000111000000011101000000010011001101100110000101011111010100111011100100000000111010010110100011110110111000011100000010111010010011111011001001010110111011111101110000011111100010010000011010100010010011100000111111101100111111000001000100101011011100001101111011100010101010011000000100011011010000111010000000001100010011011011010010000101110111110110111101110111000111010100001001101011010101110101010100111000010110001110001111001011100011110100000110100110000000100011101011010010011100111011001111111011111000011101000111100110
  59. 59. Machine-Readable Formats <ul><li>XML (eXtensible Markup Language)
  60. 60. JSON (JavaScript Object Notation)
  61. 61. Key/value pairs
  62. 62. Form variables </li></ul>
  63. 63. Background: XML <menu id=&quot;file&quot; value=&quot;File&quot;> <popup> <menuitem value=&quot;New&quot; onclick=&quot;CreateNewDoc()&quot; /> <menuitem value=&quot;Open&quot; onclick=&quot;OpenDoc()&quot; /> <menuitem value=&quot;Close&quot; onclick=&quot;CloseDoc()&quot; /> </popup> </menu>
  64. 64. Background: JSON {&quot;menu&quot;: { &quot;id&quot;: &quot;file&quot;, &quot;value&quot;: &quot;File&quot;, &quot;popup&quot;: { &quot;menuitem&quot;: [ {&quot;value&quot;: &quot;New&quot;, &quot;onclick&quot;: &quot;CreateNewDoc()&quot;}, {&quot;value&quot;: &quot;Open&quot;, &quot;onclick&quot;: &quot;OpenDoc()&quot;}, {&quot;value&quot;: &quot;Close&quot;, &quot;onclick&quot;: &quot;CloseDoc()&quot;} ] } }}
  65. 65. Choosing Formats <ul><li>XML needed for SOAP, widely supported in most languages
  66. 66. JSON easier for JavaScript, use with AJAX-esque requests
  67. 67. Or make both available
  68. 68. Use built-in libraries for your platform </li></ul>
  69. 69. Error Handling <ul><li>Will you ignore extra fields? Error?
  70. 70. How about incorrect data types? Cast or reject?
  71. 71. Make error messages meaningful and unique </li></ul>
  72. 72. Asynchronous Handling <ul><li>Consider swift response and offline processing
  73. 73. Manage job queues and retries
  74. 74. Will users poll for a change?
  75. 75. Could implement callbacks </li></ul>
  76. 76. Versions and Formats <ul><li>Include as parameters to your service: </li></ul><ul><ul><li>The service version (allows for future upgrades)
  77. 77. The preferred response format </li></ul></ul>
  78. 78. Building Blocks <ul><li>Some frameworks have functionality built-in for services
  79. 79. Can be convenient
  80. 80. Consider performance </li></ul>
  81. 81. Resources <ul><li>RESTful Web Services – Leonard Richardson and Sam Ruby
  82. 82. http://uk.php.net/sca
  83. 83. http://benramsey.com
  84. 84. http://lornajane.net </li></ul>
  85. 86. WSDL <?xml version ='1.0' encoding ='UTF-8' ?> <definitions name='MyClass' targetNamespace='urn:MyClassInventory' xmlns:tns='urn:MyClassInventory' xmlns:soap=' http://schemas.xmlsoap.org/wsdl/soap/ ' xmlns:xsd=' http://www.w3.org/2001/XMLSchema ' xmlns:soapenc=' http://schemas.xmlsoap.org/soap/encoding/ ' xmlns:wsdl=' http://schemas.xmlsoap.org/wsdl/ ' xmlns='http://schemas.xmlsoap.org/wsdl/'> <message name='getAccountStatusRequest'> <part name='accountID' type='xsd:string'/> </message> <message name='getAccountStatusResponse'> <part name='accountID' type='xsd:string'/> <part name='counter' type='xsd:float' /> </message> <portType name='MyClassPortType'> <operation name='getAccountStatus'> <input message='tns:getAccountStatusRequest'/> <output message='tns:getAccountStatusResponse'/> </operation> </portType> <binding name='MyClassBinding' type='tns:MyClassPortType'> <soap:binding style='rpc' transport='http://schemas.xmlsoap.org/soap/http'/> <operation name='getAccountStatus'> <soap:operation soapAction='urn:xmethods-delayed-quotes#getAccountStatus'/> <input> <soap:body use='encoded' namespace='urn:xmethods-delayed-quotes' encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/> </input> <output> <soap:body use='encoded' namespace='urn:xmethods-delayed-quotes' encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/> </output> </operation> </binding> <service name='MyClassService'> <port name='MyClassPort' binding='tns:MyClassBinding'> <soap:address location='http://rivendell.local:10002/MyClassServiceServer.php'/> </port> </service> </definitions>
  86. 87. WSDL: Service <service name='MyClassService'> <port name='MyClassPort' binding='tns:MyClassBinding'> <soap:address location='http://rivendell.local:10002/MyClassServiceServer.php'/> </port> </service>
  87. 88. WSDL <?xml version ='1.0' encoding ='UTF-8' ?> <definitions name='MyClass' targetNamespace='urn:MyClassInventory' xmlns:tns='urn:MyClassInventory' xmlns:soap=' http://schemas.xmlsoap.org/wsdl/soap/ ' xmlns:xsd=' http://www.w3.org/2001/XMLSchema ' xmlns:soapenc=' http://schemas.xmlsoap.org/soap/encoding/ ' xmlns:wsdl=' http://schemas.xmlsoap.org/wsdl/ ' xmlns='http://schemas.xmlsoap.org/wsdl/'> <message name='getAccountStatusRequest'> <part name='accountID' type='xsd:string'/> </message> <message name='getAccountStatusResponse'> <part name='accountID' type='xsd:string'/> <part name='counter' type='xsd:float' /> </message> <portType name='MyClassPortType'> <operation name='getAccountStatus'> <input message='tns:getAccountStatusRequest'/> <output message='tns:getAccountStatusResponse'/> </operation> </portType> <binding name='MyClassBinding' type='tns:MyClassPortType'> <soap:binding style='rpc' transport='http://schemas.xmlsoap.org/soap/http'/> <operation name='getAccountStatus'> <soap:operation soapAction='urn:xmethods-delayed-quotes#getAccountStatus'/> <input> <soap:body use='encoded' namespace='urn:xmethods-delayed-quotes' encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/> </input> <output> <soap:body use='encoded' namespace='urn:xmethods-delayed-quotes' encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/> </output> </operation> </binding> <service name='MyClassService'> <port name='MyClassPort' binding='tns:MyClassBinding'> <soap:address location='http://rivendell.local:10002/MyClassServiceServer.php'/> </port> </service> </definitions>
  88. 89. WSDL: Binding <binding name='MyClassBinding' type='tns:MyClassPortType'> <soap:binding style='rpc' transport='http://schemas.xmlsoap.org/soap/http'/> <operation name='getAccountStatus'> <soap:operation soapAction='urn:xmethods-delayed-quotes#getAccountStatus'/> <input> <soap:body use='encoded' namespace='urn:xmethods-delayed-quotes' encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/> </input> <output> <soap:body use='encoded' namespace='urn:xmethods-delayed-quotes' encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/> </output> </operation> </binding>
  89. 90. WSDL <?xml version ='1.0' encoding ='UTF-8' ?> <definitions name='MyClass' targetNamespace='urn:MyClassInventory' xmlns:tns='urn:MyClassInventory' xmlns:soap=' http://schemas.xmlsoap.org/wsdl/soap/ ' xmlns:xsd=' http://www.w3.org/2001/XMLSchema ' xmlns:soapenc=' http://schemas.xmlsoap.org/soap/encoding/ ' xmlns:wsdl=' http://schemas.xmlsoap.org/wsdl/ ' xmlns='http://schemas.xmlsoap.org/wsdl/'> <message name='getAccountStatusRequest'> <part name='accountID' type='xsd:string'/> </message> <message name='getAccountStatusResponse'> <part name='accountID' type='xsd:string'/> <part name='counter' type='xsd:float' /> </message> <portType name='MyClassPortType'> <operation name='getAccountStatus'> <input message='tns:getAccountStatusRequest'/> <output message='tns:getAccountStatusResponse'/> </operation> </portType> <binding name='MyClassBinding' type='tns:MyClassPortType'> <soap:binding style='rpc' transport='http://schemas.xmlsoap.org/soap/http'/> <operation name='getAccountStatus'> <soap:operation soapAction='urn:xmethods-delayed-quotes#getAccountStatus'/> <input> <soap:body use='encoded' namespace='urn:xmethods-delayed-quotes' encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/> </input> <output> <soap:body use='encoded' namespace='urn:xmethods-delayed-quotes' encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/> </output> </operation> </binding> <service name='MyClassService'> <port name='MyClassPort' binding='tns:MyClassBinding'> <soap:address location='http://rivendell.local:10002/MyClassServiceServer.php'/> </port> </service> </definitions>
  90. 91. WSDL: Port Type <portType name='MyClassPortType'> <operation name='getAccountStatus'> <input message='tns:getAccountStatusRequest'/> <output message='tns:getAccountStatusResponse'/> </operation> </portType>
  91. 92. WSDL <?xml version ='1.0' encoding ='UTF-8' ?> <definitions name='MyClass' targetNamespace='urn:MyClassInventory' xmlns:tns='urn:MyClassInventory' xmlns:soap=' http://schemas.xmlsoap.org/wsdl/soap/ ' xmlns:xsd=' http://www.w3.org/2001/XMLSchema ' xmlns:soapenc=' http://schemas.xmlsoap.org/soap/encoding/ ' xmlns:wsdl=' http://schemas.xmlsoap.org/wsdl/ ' xmlns='http://schemas.xmlsoap.org/wsdl/'> <message name='getAccountStatusRequest'> <part name='accountID' type='xsd:string'/> </message> <message name='getAccountStatusResponse'> <part name='accountID' type='xsd:string'/> <part name='counter' type='xsd:float' /> </message> <portType name='MyClassPortType'> <operation name='getAccountStatus'> <input message='tns:getAccountStatusRequest'/> <output message='tns:getAccountStatusResponse'/> </operation> </portType> <binding name='MyClassBinding' type='tns:MyClassPortType'> <soap:binding style='rpc' transport='http://schemas.xmlsoap.org/soap/http'/> <operation name='getAccountStatus'> <soap:operation soapAction='urn:xmethods-delayed-quotes#getAccountStatus'/> <input> <soap:body use='encoded' namespace='urn:xmethods-delayed-quotes' encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/> </input> <output> <soap:body use='encoded' namespace='urn:xmethods-delayed-quotes' encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/> </output> </operation> </binding> <service name='MyClassService'> <port name='MyClassPort' binding='tns:MyClassBinding'> <soap:address location='http://rivendell.local:10002/MyClassServiceServer.php'/> </port> </service> </definitions>
  92. 93. WSDL: Message <message name='getAccountStatusRequest'> <part name='accountID' type='xsd:string'/> </message> <message name='getAccountStatusResponse'> <part name='accountID' type='xsd:string'/> <part name='counter' type='xsd:float' /> </message>

Editor's Notes

×