Download Latest Version XNode-v1.0.zip (40.7 kB)
Email in envelope

Get an email when there's a new version of XNode

Home
Name Modified Size InfoDownloads / Week
XNode-v1.0.zip 2012-04-06 40.7 kB
LICENCE 2012-04-06 31.8 kB
README 2012-04-06 7.9 kB
Totals: 3 Items   80.4 kB 1
XNode Framework v1.0

Copyright (c) 2010-2012 James Watts (SOLFENIX)
http://www.solfenix.com

This is FREE software, licensed under the GNU/GPL
http://www.gnu.org/licenses/gpl.html

This software implements the XHTTP protocol
http://www.xhttp.org


The XNode framework is a server and client implementation of the 
Extended Hypertext Transfer Protocol (XHTTP).


To use the package it's highly recommended to use a PSR-0 compatible 
autoloader for required classes.

You can find a fully compatible autoloader here: https://sourceforge.net/p/php-autoload

Once you've unpacked the files into your include path the package is 
ready for use.


To access the XNode server you must first establish a node to connect 
to. This is refered to as the "end-point" of the node. To setup an 
"end-point" create a new instance of the XNode class and call the 
method process( void ). This will make the server listen for XHTTP 
requests on the URI to this file, for example:


 use Solfenix\XNode\XNode;
 
 $node = new XNode();
 $node->process();


Once your "end-point" is available you can now access the node over a 
network. The package includes a "test" service to check the status of 
the node and run basic unit tests. To test the server call the URI to 
your "end-point" with the following XHTTP headers:


 HTTP/1.1 GET http://%DOMAIN%/%PATH%/%FILE%
 Host: %DOMAIN%
 Version: 1.0
 Service: Test;*.*
 Action: status
 Encoding: x-user-defined


Replace the %VARIABLES% with your values and send the request. If the 
server is ready and working correctly the following response will be 
returned:


 HTTP/1.1 200 OK
 Date: %DATETIME% 
 Return: 1 

 1


If an error occurs a 550 Exception should be returned by the server, 
specifying the reason for the failure.


To create an XHTTP service you will first need to define the XHTTP 
schema. In this case, we'll create a service called "example" with a 
single action, "foo", which expects a required integer argument, 
"value".


 <?xml version="1.0" encoding="UTF-8"?>
 <xhttp xmlns:xhttp="http://www.xhttp.org/schema" version="1.0">
     <xhttp:schema version="1.0">
         <xhttp:info name="service" value="example"/>
         <xhttp:info name="host" value="http://www.solfenix.com/xnode"/>
         <xhttp:info name="port" value="80"/>
         <xhttp:info name="author" value="James Watts"/>
         <xhttp:info name="email" value="contact@jameswatts.info"/>
         <xhttp:info name="link" value="http://www.xhttp.org"/>
         <xhttp:info name="version" value="1.0"/>
         <xhttp:info name="build" value="20120401"/>
         <xhttp:action name="foo" function="fooAction">
             <xhttp:exception code="99" message="Value must be greater than 10"/>
             <xhttp:argument name="value" type="2" use="required"/>
             <xhttp:return type="2"/>
         </xhttp:action>
     </xhttp:schema>
 </xhttp>


Now that we have the *XHTTP* schema we can generate the class for 
this service.

To define the class simply extend the XService class using the name 
of the service in "CamelCase" as the class name, for example, in 
this case:


 class Example extends XService {

     // define your actions here
 }


Our schema defines an action called "foo" with a function name 
"fooAction", so now we'll define this action in our class.


 public function fooAction()
 {
     // define your logic here
 }


When working with XHTTP most of the work is done by the protocol and 
handled by the XNode server, such as processing the request, 
resolving the API version, validating arguments and generating the 
response with the corresponding output. This leaves you to deal with 
just the specific logic of each action.

To access the server from the action the XService class provides a 
reference through the $this->server property.

From the server we can access the arguments received by the action, 
for example:


 $value = $this->server->getArgument( 'value' );


When an error occurs within the logic of your action the function 
should throw an XException with an error message and code as defined 
in the schema for the service, for example:


 public function fooAction()
 {
     $value = $this->server->getArgument( 'value' );
     
     if ( $value < 11 )
     {
         throw new XException( 'Value must be greater than 10', 99 );
     }
        
     echo $value*100;
 }


In this case the "foo" action is quite simple, only checking that 
the integer specified in the "value" argument is greater than 10, and 
if so, multiplying it by 100. However, actions can perform logic as 
complex as required, and even call other services and actions.

To create an XHTTP request we'll use the XRequest class. This creates 
a request object, using setHost( string $host ) for the node to 
connect to, setService( string $service ) for the service to call, 
setAction( string $action ) for the action to perform, and 
setArguments( array $arguments ) to define the arguments to pass to 
the action. For example, if we were to call the service we defined 
previously:


 $request = new XRequest();
 $request->setHost( 'http://www.solfenix.com/xnode?value=33' );
 $request->setService( 'example;*.*' );
 $request->setAction( 'foo' );
 $request->setArguments( array( new XInteger( 'value', 33 ) ) );


When defining the arguments to pass to an action there exist classes 
for each data type available, these are:

- **XNull:** Discriminated null value. Defaults to an empty value (no value).
- **XBoolean:** Boolean logical value (1 or 0). Defaults to 0.
- **XInteger:** Whole number. Defaults to 0.
- **XDouble:** Double precision floating point number. Defaults to 0.0.
- **XString:** String of characters. Defaults to an empty value (no value).
- **XArray:** Array of values, storing no keys. Defaults to []. *
- **XStruct:** Associative array or object. Defaults to {}. *
- **XLambda:** Anonymous or named function. Defaults to {}. *
- **XBase64:** Base64-encoded binary data. Defaults to an empty value (no value).
- **XDateTime:** Date and time in ISO-8601 16 format. Defaults to the current date and time.

Each class construct expects 2 arguments, the "name" of the argument, 
and the "value".

Creating a request object doesn't send the petition to the server 
until you create an XResponse object. The XResponse object can handle 
a single XRequest object or an array of multiple XRequest objects. 
Each XRequest object has an isReady( void ) method to check that the 
request is ready to send and isn't missing require values, such as 
the "host" or the "service".

Once processed by the XResponse object, the isComplete( int $index ) 
method specifies if the response could complete the request 
successfully. And finally, the getReturn( int $index ) gets the 
value returned by the action, for example:


 $response = new XResponse( $request );
 
 if ( $request->isReady() )
 {
     if ( $response->isComplete() )
     {
         $result = $response->getReturn();
     }
 }


In the case of handling multiple requests, each method of the 
XResponse object expects the $index of the array of requests to 
access the data of the specific request.

Handling requests and responses can be a tedious process. However, 
XHTTP provides the functionality of exposing the schema for a 
service. This allows implementations to provide the option to build a 
remote API. The XNode framework provides this specific functionality 
through the XSchema class, for example:


 $example = new XSchema( 'http://www.solfenix.com/xnode', 'example', '1.*' );


The $example object is now an API which models the "example" schema, 
so we can now call the "foo" action as a method of this object:


 $result = $example->foo( new XInteger( 'value', 33 ) );


This overview provides an introduction to the XNode framework. You 
can read more about the Extended Hypertext Transfer Protocol (XHTTP) 
here: http://www.xhttp.org

Source: README, updated 2012-04-06