Creating Web Services
	Note: NetTalk Web Services requires xFiles
	
 
	Introduction
		
	
	There are a variety of common features that programs can offer that 
	collectively are known as Web Services. NetTalk 8 introduces two new 
	Procedure templates, called NetWebService and 
	NetWebServiceMethod to assist 
	with creating web services.
A NetWebService
	is the name for a collection of service methods. 
In that 
		application tree you can have multiple NetWebServiceMethods for a single 
		NetWebService. the NetWebService is just a container, and does not 
		include much more than just a list of the methods.
Your 
		application can contain multiple NetWebService procedures (each one with 
		one or more methods.)
	
	
	Example
		
		In NetTalk 7 and earlier a hand-coded approach to web services was 
		demonstrated in an example called SOAPServer (42). 
		This example is included for reference purposes.
However a new 
		example, 		WebService (77) is provided from NetTalk 8 
		and as it makes use of the new templates, is a better example for 
		developing future WebServices.
	Documentation
		
		The service, and each method is self documenting. From any browser you 
		can see the documentation for the service, and for each method. The 
		documentation includes as much information as possible so that other 
		developers can easily make use of your service.
To see the 
		documentation in your browser navigate to one of the following links;
		
www.whatever.com/servicename 
		www.whatever.com/servicename?help
		www.whatever.com/methodname?help
		www.whatever.com/servicename?methodname
	
	
	WSDL
		
		A WSDL file is a formal, computer-readable way of documenting a web 
		service. Using this file, other programmers can write programs that make 
		use of your service, and the existence of this file makes their lives 
		much easier.
NetTalk automatically (and dynamically) generates 
		this file for you when it is requested. A WSDL file for your service can 
		be retrieved by using one of these links;
		www.whatever.com/servicename?wsdl or
www.whatever.com/methodname?wsdl
		
	
	
	Method Data
		
	The method template has a place where you can set the incoming data fields, and the returning 
		data fields. These fields need to be declared in your application either 
		as tables, table fields, global data or local data. 
Incoming fields can 
		be any simple data type or a TABLE, GROUP or  QUEUE structure. (If a QUEUE 
		structure is used then 
		declaring it as a local queue is recommended- global queues are strongly 
		discouraged.)
Like a normal Clarion procedure the method can take 
		multiple incoming parameters and (depending on your code) the caller may 
		only need to send some of them - in other words some of the incoming 
		parameters may be optional.
If a Table is selected as an incoming 
		parameter, then another parameter (
tablename_action) is also 
		expected from the caller. The action parameter informs the server of the 
		nature of the change or fetch.
The template includes validation 
		options for the parameters, but you can also add your own hand-code 
		validation where necessary.
Unlike a normal Clarion procedure, 
		the method can return multiple variables. Return values can be simple 
		fields (including Local or Global variables), Queues, Groups, Tables and 
		Views.
All methods can return one or more errors in place of the 
		declared return values. If any errors exist, then  none of the 
		other declared variables are returned. For more on errors see
		
Errors.
All methods can also make use of 
		the standard 
ServiceResult queue. The 
		template code will especially make use of this when an incoming Table 
		parameter is used. For more on standard results see 
		Results. 
	
Tables
		
		Probably the most common use 
		for a WebServiceMethod is to read and/or write database records. Since 
		this is a common use-case, the templates are aware of this situation, 
		and creating these sorts of methods is very straightforward.
		
			- Create a NetWebServiceMethod procedure. Add it to a 
			NetWebService as normal.
- Create an incoming parameter of type TABLE, and select a Table. 
			Tick on the database actions you want to allow (Inserts, Updates etc)
- If the method allows the user to read the table then create a 
			return value, of type VIEW. Give the view a name, tick on 
			GenerateViewStructure and select the Table to view. If you leave the 
			Fields list blank then all the fields from the table will be 
			exported. Alternatively you can select a subset of fields to send to 
			the client. Also be sure to enter an appropriate filter here.
		The service will look for an additional parameter, called 
		
TableName_Action.
		This parameter is a string and should contain one of 
		
insert, 
update, 
		
get or 
delete.
		
	
Wizard
		
		The wizard can now generate a web service (default name "database") and 
		a web service method for each table that you select.	
	
	
	Calling Methods from a Client program
		
	The above calls are typically made from a browser, and the goal is to 
	determine what the service can do, and how to use it. To actually make use 
	of the service though you need to call one of the methods. 
AA service is a collection of one or more methods. You can create your 
	own methods using the 
NetWebServiceMethod procedure type. 
	You can add as many methods as you like to a service, and your application 
	can contain as many services (ie collections of methods) as you like.
Methods 
	have a name, a list of incoming parameters, and a list of returned data. 
	While a Clarion procedure only returns a single piece of data, a web method 
	can return any amount of data, including GROUP and QUEUE structures.
	The 
NetWebServiceMethod
	procedure type supports a number of calling techniques;
	
	
- 
	Normal HTTP GET. The URL is of the form 
	/service/method. Incoming parameters are passed as part of the URL or 
	as cookies. The returned result is a simple XML structure. For example;
 
 GET /School/GetSchoolTeacher?FromTeacherID=value&ToTeacherId=value&Authenticate=value
 
 It's also possible to call the method using the PUT
	or DELETE commands instead of GET. For 
	example;
 
 PUT /School/GetSchoolTeacher?TeacherID=value&Teacher
 Name=value&
 
 In the method itself you can determine which Verb was 
	used by checking p_web.RequestMethodType. 
	Typical possible values are one of NetWebServer_GET,
	NetWebServer_PUT, 
	NetWebServer_POST and NetWebServer_DELETE.
 
- Normal HTTP POST. The URL is of the form 
	/service/method. Incoming parameters are passed as Post Data, but in 
	addition to the URL and Cookies, data can be passed in as plain "POST Data". 
	For example;
 
 POST /School/GetSchoolTeacher HTTP/1.1
 Content-Type: application/x-www-form-urlencoded
 Content-Length: length
 
 FromTeacherID=value&ToTeacherId=value&Authenticate=value
 
 
- SOAP 1.1. The URL is of the form /service. 
	In this case a POST is used, but the incoming Post Data is formatted as XML, 
	and (optionally) wrapped in a SOAP envelope. A HTTP Header called
	SOAPAction: is also set to the method name.
 
 POST /School HTTP/1.1
 Host: 
	somehost
 Content-Type: text/xml
 Content-Length: length
 SOAPAction: /GetSchoolTeacher
 
 <?xml version="1.0" encoding="utf-8"?>
 <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
 <soap:Body>
 <GetSchoolTeacher xmlns="http://www.capesoft.com">
 <FromTeacherID>value</FromTeacherID>
 <ToTeacherId>value</ToTeacherId>
 <Authenticate>
 <User>value</User>
 <Password>value</Password>
 </Authenticate>
 <AsAtDate>value</AsAtDate>
 <AsAtTime>value</AsAtTime>
 </GetSchoolTeacher>
 </soap:Body>
 </soap:Envelope>
 
 
- SOAP 1.2. The URL is of the 
	form /service. the request is very similar to a 
	SOAP 1.1 request, although the SOAPAction header is not included. the 
	content-type of the SOAP 1.1 request is text/xml whereas the content-type 
	for a SOAP 1.2 request is application/soap+xml. For example;
 
 POST 
	/School HTTP/1.1
 Host: somehost
 Content-Type: application/soap+xml
 Content-Length: 
	length
 
 <?xml version="1.0" encoding="utf-8"?>
 <soap:Envelope 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
	xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
 <soap:Body>
 <GetSchoolTeacher xmlns="http://www.capesoft.com">
 <FromTeacherID>value</FromTeacherID>
 <ToTeacherId>value</ToTeacherId>
 <Authenticate>
 <User>value</User>
 <Password>value</Password>
 </Authenticate>
 <AsAtDate>value</AsAtDate>
 <AsAtTime>value</AsAtTime>
 </GetSchoolTeacher>
 </soap:Body>
 </soap:Envelope>
 
Your Code in the method
		
		Services can include automatically generated methods (more on that in a 
		moment) but a NetWebServiceMethod procedure doesn't actually do anything 
		unless you add the necessary code.
In this sense a method can do 
		"anything" that you code it to do. The template will parse the incoming 
		request, and place it in the Parameter data structures. It will also 
		format the return structures into XML, and return them to the caller. 
		Your job is to write the code that populates the return structures.
		
You add your code to a routine called ServiceMethod. By the time 
		this routine is called the parameter structures have been primed. Once 
		this code is completed another (generated for you) routine will turn the 
		result data structures into XML - you don't need to worry about that, 
		you just write the code to populate the return structures with the 
		correct value. Your code should not need to care about the technique 
		used to call the method.
You add normal Clarion code here, 
		opening tables, reading data and performing calculations, just like you 
		would in any Clarion procedure.
You have access to the 
		SessionQueue here for fetching and storing information using the normal 
		p_web.GetSessionValue and 
		p_web.SetSessionValue methods. However the 
		incoming request will be bound to the session ONLY if the
		sessionID cookie is set in the request. Since the web client accessing this method 
		is usually not a browser, the cookie will not automatically be set. 
		
Aside: If you are using a Clarion program as a client, and you are 
		using the NetWebClient class, then you can set the 
		NetWebClient.OptionAutoCookie property so that multiple webClient 
		request will preserve the cookies, and hence the session ID. If you are 
		using a different tool for the client, then you will need to research 
		that tool to determine how to send the cookie.
If your code does 
		not interact with the session queue, then you don't need to worry about 
		this.
Your code can (and should) generate Errors when things go 
		wrong. See the next section for more on adding errors to your code.
	
	
	Results
		
	
		NetTalk contains a generic Results queue (
p_web.ServiceResultQueue) 
		which is used to pass information back to the caller. This queue is 
		populated when the caller is adding, editing or removing records in the 
		database, using the generated template code.
The Queue contains 
		three fields;
- Action
- TableName
- Description
You can add your own information to the queue 
		if you wish. The method to call is 
		p_web.AddServiceResult (action, tablename, description)
	
	Errors
		
		A method may fail for any number of reasons. Services should return detailed, meaningful
		error information to the client wherever possible. To this end NetTalk Service Methods include
		a built-in, automatic, always consistent queue of errors. 
Errors 
		can be generated automatically by the validation template settings, or 
		they can be generated in your method code. To Generate a method simply 
		call;
p_web.AddServiceError 
		(Number, Position, Description, Recommendation)
You are free 
		to pass whatever you like to the AddServiceError
		method, but the more information passed to the client the better.
		
If any errors are added to the queue in this way, then only the 
		errors list will be returned to the caller. None of the other return 
		values will be included in the reply.
The ServiceErrorQueue 
		is automatically added as a possible reply to the generated WSDL file 
		for all methods in the service.
		
	
	
	
	SOAP versus REST
	
	As you can see from the above your method will happily accept incoming 
		requests formatted as a SOAP XML packet. It is equally happy though to 
		receive the request as a simple GET, PUT, POST or DELETE command. This 
		is sometimes known as a REST request.
Your embed code does not 
		change greatly between creating a SOAP service, or a REST service. REST 
		is basically the same as SOAP without all the SOAP wrapping. Typically a 
		REST client will also use the different HTTP verbs (GET, POST, PUT and 
		DELETE) to match up to regular file activities. A SOAP service on the 
		other hand will typically use a parameter to determine the file action 
		to take.
Your code can easily handle both, for example in your 
		embed code you might have some code like this;
(In this example a 
		parameter called ACTION is assumed. If the 
		parameter is sent, then loc:act is set from 
		that, if the parameter is omitted, or set to 0, then the HTTP verb is 
		checked and the loc:act based on that.)
		
loc:act = action
if loc:act = 0
    
		case p_web.RequestMethodType
    of 'GET'
        
		loc:act = Net:ViewRecord
    of 'DELETE'
        
		loc:act = Net:DeleteRecord
    of 'PUT'
        
		loc:act = Net:ChangeRecord
    of 'POST'
        
		loc:act = Net:InsertRecord
    end
end
    
		
		To be a truly RESTful method you should not need to access the SessionQueue in 
		order for the method to work. Ideally the client should pass you all the 
		information you need in order for the method to work.
		
		
	
		
	Authentication
		
		It is probable that many of the services you are providing will require 
		that the user authenticate themselves in order for the action to 
		complete.
As with normal Web apps, the method of authentication 
		is left largely under your control - you can determine the best approach 
		that suits your situation. Some approaches include (but are not limited to);
		
- Pass the Login and Password as fields on an incoming packet. 
			These fields are then first checked in your code to verify the 
			request before any other action is taken. 
- Allow the user to log in with one request and set the session as 
			logged in (as you would in a normal web app). Then further requests 
			from the client can use the SessionID cookie with further requests. 
			Note however that normal session timeout rules apply here - if no 
			traffic from the service is received for a pre-determined period of 
			time, then the session will timeout. 
	
			Bear in mind
		that because the service will typically be used by some service other 
		than a browser more complicated authentication schemes are possible.
	
[End of this document]