WSO2 announced the release of the Web Services Framework for C++ (WSF/C++) version 2.0.0. Similar to WSF/PHP which is really popular among the PHP community, WSF/CPP is the C++ language binding for the Apache Axis2/C and the other supporting web services projects like Apache Sandesha/C, Apache Rampart/C.

With this release C++ developers will be able to write web services and web service clients to inter-op with .NET/Java/PHP or any other platform built-on web service standards. The release is shiped with a code generation tool that will be used to generate the code for skeletons and stubs from a WSDL, so developers only need to concentrate on their business logic as the generated code will take care of building or parsing xmls and running them on top of the framework.
Here are the key features of the new release.

  1. Support core web service standards like SOAP 1.1, SOAP 1.2, WSDL 1.1, WSDL 2.0, REST
  2. Support for web services QoS specifications.
    • WS-Addressing
    • WS-Security
    • WS-Policy
    • WS-Security-Policy
    • WS-Reliable-Messaging
  3. Support binary attachment with MTOM and SWA (With the Support for large binaries)
  4. Code generation tool.
  5. Proven interoperability with .NET.

As a side note, you will be able to participate to a free summer school training session on the WSF/CPP conducted by Nandika Jayawardane who is the project lead of both WSF/CPP and WSF/PHP on 30th July. You can register to it (for free) from here.

WSO2 has announced the release of WSO2 Mashup Server 1.5.2. This release introduced the support for Data Services (Exposing Database, Excel sheet, CSV as a service), Open ID Logins and personalized dashboards to manage mashups and some security improvements. Just have a look at the release note for all the details about the new features, fixes of the release.

WSO2 Mashup Server enables you to develop your enterprise mashups very easily. You will write your code for the mashups in javascript with the full help of integrated javascript objects to consume Web services or Atom feeds, manage sessions, scrape web pages and manipulate storage. Once your put your .js file in to the mashup server repository, your services automatically will have the WSDLs, ‘Try It’ functionality and SOAP, REST interfaces.

If you are new to Mashup Server or to develop Mashups, just have a look at the series of screenshots released by WSO2 sometime ago. That will no doubt take you from zero knowledge to a comfortable state to write full-fledged mashups.

Now you can view the article I wrote titling “Introduction to PHP Data Services“. There I explain how you can design and implement Data Services in PHP using WSF/PHP Data Services Library.

This article covers,

  1. Designing your Data Service API.
  2. Writing the Data Service.
  3. Deploying and Testing Data Service.
  4. Make the Data Service available in both SOAP and RESTful form.
  5. Use of WS-* features in your Data Service.

If you are thinking of adapting SOA in to your database backed PHP applications, this article will be a good starting point.

PHP is one of the famous choice, when it comes to develop a web site. As the web evolve with the emerge of web service, REST (REpresentational State Transfer) concepts, the PHP language is also adapted to the new requirements specially with the availability of new SOA (Service Oriented Architecture), REST frameworks and libraries. Anyway there were hardly any guides, references or samples that properly describe the methodologies of developing REST applications using PHP.

The book “RESTful PHP Web Services‘ by Samisa Abeysinghe certainly fill this gap. It can be used as a step by step guideline for newbies to learn the concepts and write simple RESTful PHP applications and Mashups. And even experienced developers would find this a great reference to keep nearby while working with RESTful Web Services in PHP. And it has lot of code samples, utility functions that developers can use it in their applications.

RESTful PHP Web Services - Samisa Abeysinghe

About the Author

Samisa Abeysinghe is a well recognized name in the web services world. He lead the development of Apache Axis2/C and WSO2 WSF/PHP, two famous open source web service frameworks for ‘C’ and PHP. In addition to his deep knowledge in the subject, his experience in involving with the community and the enterprise for years and working as a lecturer in universities, should have influenced a lot in writing this book.

The Arrangement and the Content

The arrangement of the book is done really well to make sure the reader can go through it in the right sequence. All the content is bundled just within 200 pages. So you don’t need to allocate a lot of time to go through the whole book. It is organized into 7 chapters and two appendixes which are mostly independent from each other.

The first chapter is completely devoted to explain the concepts of RESTful web services. It basically explains what is RESTful web service and why it is needed. And it briefly mentions about the currently available REST Frameworks for PHP.

The second chapter introduce some PHP codes that do REST web service requests and handles the XML responses using both DOM and SimpleXML APIs. And in the third chapter it shows more code samples specially about consuming real world web services like BBC, Yahoo and an earthquakes information service. Theses codes are written as mashups mostly combining two services to produce more meaningful information.

The forth chapter is about  designing and writing web service providers. Its counterpart, writing web service consumers is described in the chapter five. There it demonstrate a library system that operate using RESTful webservices. You can map this example to any system that you may like to develop to run with RESTful web services. The chapter five of the book is available as a free download, RESTful PHP Web Services – Chapter 5.

The forth and fifth chapters are not using any framework to write the sample codes on consuming and providing web services. But in the sixth chapter it shows the use of Zend framework to do write them. There it rewrites the same example (The RESTful library system) in MVC (Model -View – Controller) approach using the functionalities of Zend framework. (In fact the View in the service is omitted).

The seventh chapter is about debugging web services. Debugging is a much needed step in any software development cycle. So if you are a newbie, you should read this chapter before start writing any of your own code. This introduces tools and methodologies to make your debugging easy and effective.

The book contains two appendixes. They are too really useful as the chapters of the book. In the first appendix it explains another REST web service framework, WSO2 Web Services Framework for PHP (WSF/PHP). To demonstrate it uses, some selected functionalities of the example library system (that is mentioned in chapters 4, 5, 6) is re-implemented using WSF/PHP. And it shows you how you can convert this RESTful system to a SOAP system in a minute. The second appendix provides you a code of a class (RESTClient), that you can use in consuming web services very effectively.

Recommended Readers

This book assume you have some knowledge in PHP. But it doesn’t require you to know anything related to web services, REST or XML. As you read the first few chapters, you will have a good understanding on the concepts and the basic applications of REST and XML using PHP. And the later chapters will guide to get deeper knowledge in writing complex and real world applications.

If you are a professional developer, you can skip the introduction chapters and jump directly to where you need to refer. For an example, if you use this book as a reference in designing and developing RESTful web service providers, you can directly read the chapter4 – Resource Oriented Services, chapter6- Resource Oriented Clients and Services with Zend Framework and probably the chapter 7 – Debugging Web Services.

This book contains the same example system (the library system) written in three different approaches, first without using any framework support, second using the Zend Framework, third using WSF/PHP. Each of them has its own pros and cons. So if you want to determine the approach more suitable to your requirements, or thinking of migrating from one to another, this book will be an ideal resource for you.

As you may have already noticed, this book contains lot of code samples. All the concepts are followed by simple code samples that explain the concept. In appendix it gives you a complete code for RESTClient class that you can use to call any REST service. Apart from the code of the example library system written using different frameworks, it has lot of codes for calling public web service APIs. And the explanation of the code is also done really well.

So it is clear this book is more targetting readers who like to implement PHP RESTful Systems in practice. And it covers enough concepts that you needed to know in writing practicle applications. So this book can take you from the zero knowlege to a deeper knowlege of RESTful PHP Web Services.

LAMP (Linux + Apache + Mysql + PHP) stack powers many servers in the Internet today. For a LAMP  server, PostgreSQL could be the first alternative to Mysql. Similar to PHP + MySQL,  PHP + PostgreSQL too can be easily used in to host data services. Here are the steps to do it.

  1. If you already don’t have Apache + PHP + PostgreSQL download them from the following locations. Apache – http://httpd.apache.org/download.cgi, PHP – http://php.net and PostgreSQL – http://www.postgresql.org/download/
  2. You have to enable the PHP pdo_pgsql, pdo and pgsql plugins. Read here for the instructions to setup these libraries. (For an example: if you are windows you have to set the system ‘PATH’ variable to the <postgresql_installed_dir>/bin directory.
  3. If you already don’t have WSF/PHP, download and install it according to the guidelines provided in wsf/php installation guide.NOTE: You can check pdo_pgsql and wsf/php has properly installed with the help of phpinfo() function.
  4. Now lets start with creating a sample Database table. For this example I created a database called ‘workshop’, schema called ‘workshop’ and inside there the table ‘Employee’ with the following schema.
    Column Name Column Type
    employId integer
    name character varying
    email character varying
    jobTitle character varying
    project character varying

    Note: You can use phpPgAdmin (web based) or pgAdmin III to create tables from GUI

  5. Then you can write a small php script to expose the data in the above table as a web service.
    <?php
    
    //Including the Data Services library
    require_once("wso2/DataServices/DataService.php");
    
    // Including the connection information (i.e. PGSQUL USERNAME
    // and PGSQL_PASSWORD) for my PGSQL Connection
    require_once("constants.php");
    
    // database configurations
    $config = array(
    		"db" => "pgsql",
    		"username" => PGSQL_USERNAME,
    		"password" => PGSQL_PASSWORD,
    		"dbname" => "workshop",
    		"dbhost" => "localhost"
    		);
    
    $output_format = array(
                        "resultElement" => "employees",
                        "rowElement" => "employee",
                        "elements" => array(
    			    "id" => "employeeId",
                                "name" => "name",
                                "email" => "email",
                                "jobTitle" => "jobTitle",
                                "project" => "project"));
    
    $sql = "SELECT * FROM workshop.Employees";
    
    $get_employees_op = array("outputFormat" => $output_format, "sql" => $sql);
    
    $get_employees_url = array("HTTPMethod" => "GET", "RESTLocation" => "employees");
    
    // list of operations
    $operations = array(
                    "getEmployees" => $get_employees_op,
                    );
    
    // list of rest url mappping (operation => url)
    $restmap = array(
                    "getEmployees" => $get_employees_url,
                    );
    
    // creating DSService and reply
    $service = new DataService(array(
             "config" => $config,
             "operations" => $operations, "RESTMapping"=>$restmap));
    $service->reply();
    ?>
  6. We just wrote a PostgreSQL Data Services that provides its service as both REST and SOAP form. To deploy this service, We just need to copy this in to the web root directory. And the web URL for the script will be the endpoint to the web service.
  7. We can test the service either by calling its SOAP interface, which we may need to write a small SOAP client or by calling its REST interface, which only need a GET request from the browser. Say my script name is “my_dataservice.php” and I’ve put it in the web root directory, then the URL to call the REST interface of the service is
    http://localhost/my_dataservice.php/employees

WSDL Generation for PostgreSQL Data Service
You can get the WSDL for the service from the URL formed adding the suffix “?wsdl” (or “?wsdl2″ to wsdl v2.0) to the service URL,

http://localhost/my_dataservice.php?wsdl

Here all the schema data types are shown as xsd:anyType, which may not be the behavior that you want. In fact you can provide the schema data types to the fields from the code itself. Lets change the $outputFormat variable to provide the schema information as well using the following code snip.

$output_format = array(
                    "resultElement" => "employees",
                    "rowElement" => "employee",
                    "elements" => array(
			    "id" => array("column" => "employeeId",
		    			  "xsdType" => "xsd:int"),
			    "name" => array("column" => "name",
		    			  "xsdType" => "xsd:string"),
			    "email" => array("column" => "email",
		    			  "xsdType" => "xsd:string"),
			    "jobTitle" => array("column" => "jobTitle",
		    			  "xsdType" => "xsd:string"),
			    "project" => array("column" => "project",
		    			  "xsdType" => "xsd:string")));

Note that you provide the xsd type for each field explicitly. In fact this change is not needed for mysql pdo extension since it allows identifying field types programatically. Since this feature is not available in all the other pdo drivers, we have to explicitly give xsd type information for them.

If you wan to provide data services with SQLite or MSSQL, You can check my other posts on MSSQL(Microsoft SQL) Data Services In PHP and Data Services with SQLite in PHP.

Database plays a big role in any day-today application. It is a major component from accounting, web portal, CMS, SaaS applications, search engines to all enterprise applications. In traditional MVC(Model-View-Controller) applications we talk about the Model component which represent the database.. And in 3-tier architectural pattern it is the ‘Data layer’ which represent the database and provide data to the ‘Logic Layer’ as per request.

As SOA evolves, database is becoming just one part of the ‘Data Layer’ or the ‘Model’ component. There are many data sources, data providers which are mostly deployed as web services which you can ask for data as you do with traditional databases. This gives you the advantages of the use of web services like interoperability, security and reliability and other WS-* support. And it helps you to get rid of the headache of installing different drivers for different databases and most importantly it removes the tight binding of your application to the database. So with adaption of SOA, the ‘Data Layer’ has been replaced by the ‘Service Consuming Layer’.

The story of the ‘Data Provider’ also changed with the SOA adaption. The new data sources are designed with the SOA in mind. And the legacy systems are wrapped by a service layer to make it more easier to consume. We use the term ‘Data Services’ for the data sources deployed as web services.

There are many public data services available as ‘REST’ which is a lighter way of providing services. The other way is the use of WS-* features like WS-Security, WS-Reliable Messaging to deploy the data services which are mostly adopted by the enterprise.

Today there are many tools around, that helps you to develop data services from existing databases. WSO2 provides an open source data service framework that allows you to build data services from simple xml configuration files without the need of writing a single line of code. And WSF/PHP also packed with a data services library that allow you to write a simple PHP script to build a data service.

PHP is one of the favorite language to write database back-ended web applications. Specially considering the fact that there are thousands of servers powered by the LAMP (Linux  + Apache + MySQL +PHP) stack, PHP data service library would comes useful to build around a web service around these existing data sources and make them SOA-aware.

Few weeks back I wrote a blog post about Writing RESTful Services in C which explain the use of Axis2/C REST API. Basically when you provide a HTTP Method (GET, POST, PUT or DELETE) and a HTTP URL, it is matched with a given HTTP method and a URL pattern in order to identify the operation and extract out the request parameters. For the example mentioned in the above blog, we can summarize the URL mapping like this.

Operation HTTP Method URL Pattern Example Requests
getSubjects GET subjects GET subjects
getSubjectInfoPerName GET subjects/{name} GET subjects/maths
getStudnets GET students GET students
getStudnetsInfoPerName GET students/{name} GET students/john
getMarksPerSubjectPerStudent GET students/{student}/marks/{subject} GET students/john/marks/maths

You can watch an application with this URL mapping in live, written using WSF/PHP which in fact run Axis2/C algorithms underneath.

Last week I updated this REST mapping algorithm and started a discussion about the changes on Axis2/C Dev list. I thought it would be better explain the idea on by blog too.

What the early algorithm (before my changes) did was, it search each pattern in the order it was declared, and returns when a match is found. Sequential searching for a matching pattern can reduce the performance as the number of operations grows. So my solutions was to keep the url pattern in a multi level (recursive) structure and match the url from one level to another.

Here is the structure of the ‘c struct’. (defined in src/core/util/core_utils.c)

/* internal structure to keep the rest map in a multi level hash */
typedef struct {
    /* the structure will keep as many as following fields */

    /* if the mapped value is directly the operation */
    axis2_op_t *op_desc;

    /* if the mapped value is a constant, this keeps a hash map of
    possible constants => corrosponding map_internal structure */
    axutil_hash_t *consts_map;

    /* if the mapped value is a param, this keeps a hash map of
    possible param_values => corrosponding_map_internal structre */
    axutil_hash_t *params_map;

} axutil_core_utils_map_internal_t;

Here is how it will looks like when the above URL pattern set (shown in the above table) is kept inside this multi-level (recursive) structure.

svc->op_rest_map  (hash)
                |
            "GET:students" --------- axutil_core_utils_map_internal_t (instance)
                |                                            |
                |                                        op_desc (axis2_op_t* for "GET students" op)
                |                                            |
                |                                        consts_map (empty hash)
                |                                            |
                |                                        params_map (hash)
                |                                                         |
                |                                                      "{student_id}" ------------- axutil_core_utils_map_internal_t (instance)
                |                                                                                            |
                |                                                                                op_desc (axis2_op_t* for "GET students/{student_id}" op)
                |                                                                                            |
                |                                                                                parms_map (empty hash)
                |                                                                                            |
                |                                                                                 const_map (hash)
                |                                                                                            |
                |                                                                                        "marks" ------------------- axutil_core_utils_map_internal_t (instance)
                |                                                                                                                            |
                |                                                                                                                    op_desc (NULL)
                |                                                                                                                            |
                |                                                                                                                   consts_map (empty hash)
                |                                                                                                                            |
                |                                                                                                                   params_map (hash)
                |                                                                                                                            |
                |                                                                                                                      "{subject_id}" ----------- axutil_core_utils_map_internal_t (instance)
                |                                                                                                                                                                               |
                |                                                                                                                                       op_desc (axis2_op_t* for "GET students/{student_id}/marks/{subject_id}" op)
                |                                                                                                                                                                               |
                |                                                                                                                                                                 consts_map / params_map (Both NULL)
                |
            "GET:students" --------- axutil_core_utils_map_internal_t (instance)
                                                            |
                                                        op_desc (axis2_op_t* for "GET students" op)
                                                            |
                                                        consts_map (empty hash)
                                                            |
                                                        params_map (hash)
                                                            |
                                                      "{student_id}" ------------- axutil_core_utils_map_internal_t (instance)
                                                                                                          |
                                                                                  op_desc (axis2_op_t* for "GET students/{student_id}" op)
                                                                                                          |
                                                                                             consts_map / params_map (Both NULL)

This structure is build at the time the server initialize the services. (from the “axis2_svc_get_rest_op_list_with_method_and_location” function in src/core/description/svc.c)

As each request hit the service, the request HTTP method and the URL is matched (which we call ‘rest dispatching’) with the above structure using the following algorithm. (defined in the “axis2_rest_disp_find_op” function in src/core/engine/rest_disp.c). Note that here we are extracting out the user REST parameters as well, but it is not shown in here.

  1. The request URL is spitted in to URL components from ‘/’ character. Retrive the instance of axutil_core_utils_map_internal_t  from the svc->rest_map to the varaible ‘mapping_struct’.
  2. Check the existance of URL components, count(URL components) > 0.
  3. If it doesn’t exist any URL components, get the value of mapping_struct->op_desc where the mapping_struct is the current mapping instance of axutil_core_utils_map_internal_t. if the mapping_struct->op_desc is not NULL, we found the operation. If it is NULL just exit returning NULL.
  4. Else If some URL component(s) exist, check the most former URL component in the mapping_struct->const_map hash. If mapping_struct->const_map['former_url_component'] is not NULL, assign the mapping struct->const_map['former_url_component'] value to mapping_struct and follow the step 2 with the remaining URL components. (note that here hash['key'] syntax is used to take the value for the key from the hash ‘hash’. If that returns TRUE, we found the opeartion, if not countine to step5.
  5. if mapping_struct->const_map['former_url_component'] is NULL, match the former url component with each key (which is a URL component pattern) in mapping_struct->param_map hash. (We use the function  “axis2_core_utils_match_url_component_with_pattern” in src/core/util/core_utils.c to map URL component with the URL component pattern). If matching pattern found assign the mapping_struct->param_map['key'] to mapping struct and follow the step 2 with the remaining URL components. If that returns TRUE for some key it will be the matching operation.

Where as the earlier algorithm can be simplified to,

  1. Match the request URL with URL patterns of each operation. This will be like calling the function “axis2_core_utils_match_url_component_with_pattern” (mentioned in step5 of the above algorithm) for the complete URL rather than for a URL component
  2. If the pattern is matched, matching operation is the selected operation for the request.

I approximately calculated the time complexity of both of these algorithm.

Here is the time complexity of the later described algorithm.

Average time complexity of iterating ‘n’ number of operations n/2 = O(n)
Time complexity of matching pattern with a URL with the length ‘p’ (complexity of the ‘axis2_core_utils_match_url_component_with_pattern’ function) O(p^2)
Complete time complexity of the algorithm O(n*p^2)

Time complexity of the formerly described algorithm. (which is currently in the SVN).

Time Complexity of a Hash Search O(1)
Average Number of has searches required. This is the average number of levels in the tree of recursive structures drawn above long(n)/2 = O(log(n))
Time complexity of matching pattern with a URL component with the average length ‘d’, d < p (p = the length of the complete URL) O(d^2)
Number of time pattern matching is required = number of param components in the URL = k, k < p/d (p = the length of the url, d = average length of the URL component)/ k = O(k)
Complete time complexity of the algorithm O(log(n)*d^2*k)

Considering the facts, O(logn) < O(n),d < p and k < p/d we can safely conclude

O(long(n)*d^2*k) < O(n*p^2)  => The newer algorithm has better (low) time complexity.

However the time complexity is valid only it takes high values for the parameters. For low values  the actual time taken by the newer algorithm can have high values, considering the constant overhead of the recursions and the hash search. So in order to judge the performance of the algorithm, we have to run some test cases and measure the actual times. Possibly a task for the weekend :)

November 19th, 2008WS-SecurityPolicy With PHP

WS-SecurityPolicy specification defines standards for defining security policies for your web service. WSF/PHP allows you to declare your security policies according to these standards.

You can take one of following approaches to associate policies to your web service or client.

  • PHP Array to represent your policies
  • Policy file compliant with WS-Security Policy.
  • Declaring policies inline with the WSDL.

Declaring Policies with a PHP Array

This is a WSF/PHP specific API to declare policies for a web service. You don’t need to learn WS-Security Policy to write policies with this approach. You can set whether you want to use encryption, signing or usernameToken in a PHP array and create a WSPolicy object using it.

// here is the security array to declare your policies in simple manner
$sec_array = array("encrypt" => TRUE,
 "algorithmSuite" => "Basic256Rsa15",
 "securityTokenReference" => "IssuerSerial");

// creating WSPolicy instance using the policy array
$policy = new WSPolicy(array("security"=> $sec_array));

You can use this policy object to create a service along with a WSSecurityToken which contain the user parameters like the server private key and the client certificate.

$sec_token = new WSSecurityToken(array(
 "privateKey" => $server_pvt_key,
 "receiverCertificate" => $client_pub_key));

$svr = new WSService(array("actions" => $actions,
 "operations" => $operations,
 "policy" => $policy,
 "securityToken" => $sec_token)); // here is the policy object you just created

$svr->reply();

You can invoke this service just by writing a simple web service client. There also you need to provide the policies declared in the service, so the client can build his request to validate with server policies. You will be using a similar WSPolicy object to set these policies at the client side too, as show in the below code segment.

 $sec_token = new WSSecurityToken(array(
   "privateKey" => $pvt_key,
   "receiverCertificate" => $rec_cert));

 $client = new WSClient(array("useWSA" => TRUE,
    "policy" => $policy, /* the policy object */
    "securityToken" => $sec_token));

 $resMessage = $client->request($reqMessage);

Declaring Policies with a Policy File

You can set your policies in the server or client side using a policy file compliant with WS-Security Policy specification. You have to take this approach if your policy requirements are too complicated, like you want to sign only some parts of the message or you want to encrypt some soap headers.

Similar to the above method, here too you will use the WSPolicy object to set your policies. But unlike the above where you give the policies as a PHP array , here you can just give the policy file as an argument to the WSPolicy constructor.

// creating the WSPolicy instance from a policy file
$policy_xml = file_get_contents("policy.xml");
$policy = new WSPolicy($policy_xml);

Here is an example of a complete policy file written according to the WS-Security Policy standards. And you can find a quick guide on WS-Security Policy from the article Understanding WS-Security Policy Language written by Nandana, a key leader of Apache Rampart project.

Declaring Policies inline in a WSDL

We use WSDL to describe our web services. WSDL has the information about the service endpoint, the transport protocols (e.g. http), messaging protocols (e.g. SOAP) and the message schemas and many others about the service. You can attach your policies inside a WSDL.

Here is an example of a WSDL with inline policies. The difference in this approach is you can set your policies separately for each messages or each operations or each endpoints of your service. The following segment of a WSDL shows how you refer to different policies which are declared in the early part of the WSDL.

     <wsdl:binding name="CalendarSOAP12Binding" type="ns1:CalendarPortType">
       <!-- Endpoint policies are declared here.
          these are common to all messages transferring
          through this protocols (i.e. SOAP12, http)-->
        <wsp:PolicyReference URI="#transport_binding_policy"/>
        <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
        <wsdl:operation name="login">
           <soap12:operation soapAction="urn:login" style="document"/>
           <wsdl:input>
              <!-- policy specific to the 'login' operation -->
              <wsp:PolicyReference URI="#username_token_policy"/>
              <soap12:body use="literal"/>
           </wsdl:input>
           <wsdl:output>
              <soap12:body use="literal"/>
           </wsdl:output>
         </wsdl:operation>
         <wsdl:operation name="register">
            <!-- no specific policies are set for the 'register' operation
            <soap12:operation soapAction="urn:register" style="document"/>
            <wsdl:input>
              <soap12:body use="literal"/>
            </wsdl:input>
            <wsdl:output>
               <soap12:body use="literal"/>
            </wsdl:output>
         </wsdl:operation>
           ....
       </wsdl:binding>

This is the binding section of a WSDL where we bind messaging protocol and transport protocols with a service endpoint. Here we have “login” and “register” operations. Note that we are referring to “transport_binding_policy” from the parent level of each operation elements. That means these policies are common to all the operation in that binding. And inside the “login” operation we are referring to “username_token_policy”, so in order to invoke this operation, you have to send username token headers. And “register” doesn’t require any operation specific policies allowing users to register without any prior authentications.

You can select any of the above mentioned approach to define policies of your web service or to invoke a web service that support WS-Policy. If your policy requirements are simple, it will be easy to use the array based approach. If your policy requirements are complex or you have a good understanding of WS-Policy and WS-Security Policy you can rely on the policy file based approach or defining policy inline with WSDL. And the former 2 methods will give you a nice separation of the logic code and security configurations. The selection is yours:)

November 16th, 2008RESTful URL Mapping in WSF/PHP

In a RESTful design, choose of URLs for resources are really important. The URL uniquely represents a resource. Service consumers can change some parts in the URL to access different other resources. So it is clear that the URL consists of some constant parts which describe the resource group or catalog in general and some variable parts which have different and unique values for different resources.

As an example look at the following URL patterns

  • students/{name} – The constant ’students’ represent the students group in general and the variable ‘name’ is used to identify each student individually.
  • students/{name}/marks/{subject} – The constants ’students’ and ‘marks’ shows that this resource is a marks of some students, The two variables ‘name’ and ’subjects’ addresses which student and marks of which subject is presented in the URL.

You can have a look at some of the uses of such mappings from RESTful School demo.

WSF/PHP allows you to create RESTful Web Services and further more RESTful Data Services in PHP.

In a RESTful Data Service you expose a database query as a web service. There you can write a prepared statement and feed arguments for the statement through the variable parameters of the URL. For an example take the RESTfulSchool Demo Code.

To retrieve a particular student, we can use the following prepared statement and the URL pattern ( This URL Pattern+  HTTP ‘GET’ method is matched to execute this query. )

$sql = "SELECT * FROM Students where StudentName = ?"

$get_students_with_name_url = array("HTTPMethod" => "GET",
                 "RESTLocation" => "students/{name}");

So you can execute this prepared statement with the subject name ‘John’ using the following URL.

http://labs.wso2.org/wsf/php/solutions/RESTFulSchool/school_service.php/students/john

If your service is not exposing the database directly, then you have to choose the general web service API rather than the data service specific API. In there you will be able to write your business logic for publishing student information in a PHP function and expose it as a web service.

In such a cas,e your function is taking an argument which of type WSMessage. This structure hold an XML that contains values for all the variable parameters as in the users request URL. For an example for above REST Mapping, we can expect the following XML.

<getSubject>
    <name>Chemistry</name>
</getSubject>

And your function to expose as a service, would be look like this,

function getSubject($input) {
    /* retrieve the subject name from the
       $input xml using simple xml */

    $input_xml = new SimpleXMLElement($input->str);

    $subject_name = $input->name;

    /* write the logic to retrieve subject information
      for the $subject_name */

    ....
}

November 7th, 2008WSF/PHP Samples Explained

Here is a simple categorization of the WSF/PHP samples. You can access all the wsf/php samples from http://labs.wso2.org/wsf/php/solutions/samples/index.html.

Sample Category Example Client Source Code Example Service Source Code Online Demo
Beginners echo_client.php echo_service.php Demo
REST echo_client_rest.php echo_service_with_rest.php Demo
WSDL Mode (Contract First) wsdl_11_client.php wsdl_11_service.php Demo
WSDL Generation (Code First) doclit_client.php doclit_service.php Demo
MTOM Attachments mtom_download_client.php mtom_download_service.php Demo
Security encryption_client.php encryption_service.php Demo
Reliable Messaging echo_client_rm.php echo_service_rm.php Demo
Data Services CustomerDetailsClient.php CustomerDetailsService.php Demo

If you have downloaded the WSF/PHP binaries or souce code package you can find all these samples, inside the ’samples’ directory


© 2007 Dimuthu’s Blog | iKon Wordpress Theme by Windows Vista Administration | Powered by Wordpress