/[svn]/website/trunk/web/cduce_ws.xml
ViewVC logotype

Contents of /website/trunk/web/cduce_ws.xml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4059 - (show annotations)
Mon Oct 17 12:43:39 2011 UTC (19 months, 1 week ago) by jmaloberti
File MIME type: text/xml
File size: 11581 byte(s)
Add CDuce_WS.
1 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
2 <page name="cduce_ws">
3
4 <title>CDuce_WS</title>
5 <left>
6 <p>
7 This page is an introduction to CDuce_WS.
8 </p>
9 <boxes-toc/>
10 <p>See also:</p>
11 <local-links href="index,memento,manual,tutorial"/>
12 </left>
13
14 <box title="Introduction" link="intro">
15
16 <p>
17 CDuce_WS is library for Web Services creation. It can be used alone
18 for the creation of clients programs, and
19 with <a href="http://ocsigen.org/occduce">OcCDuce</a> for servers.
20 </p>
21 <p> Basically, CDuce_WS is a CDuce representation of the SOAP protocol
22 structures (SOAP Envelope, SOAP Encoding, etc.) with some helper
23 functions to ease the programmation of Web Services.
24 Additionally, a WSDL structure is also provided, as well as some
25 functions (adapted from
26 <a href="http://forge.ocamlcore.org/projects/ocsoap/">OCSoap</a>) to
27 extract useful information from a WSDL file.
28 </p>
29 </box>
30 <box title="First example" link="first">
31 <p>
32 This example corresponds to the example in the directory: examples/echo/.
33 <br/>
34 It is a very simple service that receive an integer from a client and
35 send it back.
36 <br/>
37 The first file, <b>common.cd</b>, contains all the declarations used by
38 the client and the server, and is included by all other files.
39 The type <b>Msg</b> corresponds to the information that a client send
40 to the server, while the type <b>Answer</b> embeds the response from
41 the server to the client.
42 </p>
43 <sample><![CDATA[namespace on;;
44 using SoapEnv = "soapenv";;
45 namespace ns = "urn:echo"
46
47 type Msg = <ns:echoInteger>[
48 <inputInteger>Latin1
49 ];;
50
51 type Answer = <ns:echoIntegerResponse> [
52 <return>Latin1
53 ];;
54 ]]></sample>
55
56 <p>The next file, <b>ws_echo.cd</b>, contains the code necessary
57 to register a web service in Ocsigen, via OcCduce.
58 <br/>
59 The call to <b>Lib.register_webservice</b> registers 2
60 services in Ocsigen:
61 </p>
62 <ul>
63 <li> <code>wsEcho</code>, which is called when a client requests the URL with
64 the POST method. The first argument corresponds to the POST
65 parameters, the second argument to the GET parameters and the third
66 one is the content of the request. POST and GET parameters are
67 empty in case of a web service. The content of the request is the
68 SOAP message as a string (actually a Latin1 string).</li>
69 <li> <code>wsError</code>, which is called if the client uses the
70 GET method (hopefully, it should not happen). </li>
71 </ul>
72 <p><b>NOTE1:</b> it is not possible to load more than once the same
73 CDuce program in OcCDuce. Therefore, you should never give the same
74 name to the source files of different services if you plan to load
75 them simultaneously.
76 </p>
77 <p>
78 <b>NOTE2:</b>Sometimes, the namespaces used by the client and the
79 server do not match. This problem can be avoided by using 3
80 functions:<code>Cduce_ws.load_xml_subst</code>,
81 <code>Cduce_ws.print_xml_subst</code>,
82 and <code>Occduce_lib.set_subst_uri</code>.
83 Both load_xml_subst and print_xml_subst are equivalent to load_xml and
84 print_xml with an additional parameter, a list of pairs of URIs. For
85 each pair of URIs, the first one is the original (i.e. used in the
86 in the other parameter), and the second URI is the new URI. Every
87 original URI will be substituted by the new one in the returned
88 value.
89 <br/>
90 <code>set_subst_uri</code> also takes a list of pairs of URIs as a
91 parameter, and it must be used <b>before</b> returning the
92 XML value in the server. The namespaces of the XML value returned
93 will be converted before it is sent to the client.
94 </p>
95
96 <sample><![CDATA[include "../common.cd"
97 using Echo = "echo";;
98 using Lib = "occduce_lib";;
99
100 let wsError (_ : []) : AnyXml =
101 SoapEnv.std_soap_fault;;
102
103 let wsEcho (_ : []) (_ : []) (content : Latin1) : AnyXml =
104 Occduce.debug_string "wsEcho\n";
105 try
106 (let a = Echo.echo content in
107 Occduce.set_subst_uri
108 [("http://schemas.xmlsoap.org/soap/envelope",
109 "http://schemas.xmlsoap.org/soap/envelope/")];
110 a)
111 with err & Latin1 ->
112 Occduce.debug_string [ 'Cduce exception: ' !err '\n'];
113 exit 2;;
114
115 let ws_echo =
116 Lib.register_webservice
117 { path = ["ws_echo"]; serviceName = "wsEcho" }
118 wsEcho wsError
119 ]]></sample>
120 <p>
121 The next file, <b>echo.cd</b>, contains the processing of the SOAP
122 message and the generation of the response message.
123 <br/>
124 <code>load_xml_subst</code> converts the string containing the SOAP
125 message in a SOAP XML structure after the substitution of the URIs
126 (obviously, using namespaces substitution in the server and client
127 code is not useful).
128 <br/>
129 The body of the SOAP structure, a list of AnyXml, is extracted with the
130 function <code>SoapEnv.extract_message</code>, while the
131 function <code>SoapEnv.hd</code> returns the first XML structure in
132 the list.
133 <br/>
134 After the processing of the message and the creation of the response
135 message, <code>SoapEnv.to_soap</code> embeds it in a SOAP envelope.
136 </p>
137 <sample><![CDATA[include "../common.cd"
138
139 let echo (s : Latin1) : SoapEnv.Envelope =
140 let xml = Cduce_ws.load_xml_subst [ 'string:' !s]
141 [("http://schemas.xmlsoap.org/soap/envelope",
142 "http://schemas.xmlsoap.org/soap/envelope/")]
143 in
144 let res = SoapEnv.hd (SoapEnv.extract_message xml) in
145 let tmp :? Msg = res in
146 let number = (match tmp with <ns:echoInteger>[<inputInteger>n] -> n)
147 in
148 let msg =
149 <ns:echoIntegerResponse>[
150 <return> number
151 ] in
152 SoapEnv.to_soap msg;;
153 ]]></sample>
154 <p>
155 The last file, <b>client.cd</b>, executes the following steps:
156 </p>
157 <ul>
158 <li>it creates a message of type Msg. <b>NOTE:</b>Since we need to
159 use load_xml or load_xml_subst to convert the string in XML, it is
160 not possible to use primitive types such as integer in the types
161 transmitted between the client and the server. We can only use
162 Latin1 strings</li>
163 <li>the message is embedded in a SOAP envelope
164 using <code>SoapEnv.to_soap</code>, and converted as a string by
165 <code>print_xml_subst</code>.</li>
166 <li>the string message is sent to the server
167 with <code>Cduce_ws.send</code>, where the parameters are: the
168 message string, the host address, the soap action, and the content
169 type.
170 <br/> The returned value of <code>send</code> is a Latin1 string
171 with the response message in SOAP.
172 </li>
173 <li>the response message is converted back in XML by <code>load_xml_subst</code>.</li>
174 <li>the body part of the SOAP response is extracted
175 using <code>SoapEnv.extract_message</code>, and printed.</li>
176 </ul>
177 <sample><![CDATA[include "../common.cd"
178 let msg : Msg =
179 <ns:echoInteger>[
180 <inputInteger>['1234567890']
181 ];;
182
183 let _ =
184 let string_msg = Cduce_ws.print_xml_subst (SoapEnv.to_soap msg)
185 [("http://schemas.xmlsoap.org/soap/envelope/",
186 "http://schemas.xmlsoap.org/soap/envelope")]
187 in
188 let answer_string = Cduce_ws.send string_msg
189 "http://localhost/ws/ws_echo" "" "text/xml; charset=utf-8" in
190 print [ 'CDuce: ' !answer_string '\n'];
191 let xml = Cduce_ws.load_xml_subst [ 'string:' !answer_string]
192 [("http://schemas.xmlsoap.org/soap/envelope",
193 "http://schemas.xmlsoap.org/soap/envelope/")]
194 in
195 print (string_of (SoapEnv.extract_message xml));;
196 ]]></sample>
197 </box>
198 <box title="A more advanced example" link="calc">
199 <p>
200 This example corresponds to the example in the directory: examples/calc/.
201 <br/>
202 It is a simple calculator over integer values that receive two values
203 with an operator from a client and return the result.
204 <br/>
205 The first file, <b>common.cd</b>, contains all the declarations used by
206 the client and the server, and is included by all other files.
207 The type <b>Operation</b> corresponds to all possible operations that
208 a client can send
209 to the server, while the type <b>Response</b> embeds the result sent by
210 the server to the client.
211 </p>
212
213 <sample><![CDATA[namespace on;;
214 namespace ns = "urn:calc"
215 using SoapEnv = "soapenv";;
216
217 type Params = [ <a>Latin1 <b>Latin1 ];;
218 type AddIn = <ns:add>Params;;
219 type SubIn = <ns:sub>Params;;
220 type MulIn = <ns:mul>Params;;
221 type DivIn = <ns:div>Params;;
222 type Result = <result>Latin1;;
223 type AddOut = <ns:addResponse>[Result];;
224 type SubOut = <ns:subResponse>[Result];;
225 type MulOut = <ns:mulResponse>[Result];;
226 type DivOut = <ns:divResponse>[Result];;
227 type Operation = AddIn | SubIn | MulIn | DivIn;;
228 type Response = AddOut | SubOut | MulOut | DivOut;;
229 ]]></sample>
230
231 <p>The next file, <b>ws_calc.cd</b>, contains the code necessary
232 to register a web service in Ocsigen, via OcCduce.
233 <br/>
234 It is quite similar to the code from the previous example.
235 </p>
236
237 <sample><![CDATA[include "../common.cd"
238 using Calc = "calc";;
239 using Lib = "occduce_lib";;
240
241 let wsError (_ : []) : AnyXml =
242 SoapEnv.std_soap_fault;;
243
244 let wsCalc (_ : []) (_ : []) (content : Latin1) : AnyXml =
245 Occduce.debug_string "wsCalc\n";
246 try (Calc.calc content)
247 with err & Latin1 ->
248 Occduce.debug_string [ 'Cduce exception: ' !err '\n'];
249 exit 2;;
250
251 let ws_calc =
252 Lib.register_webservice
253 { path = ["ws_calc"]; serviceName = "wsCalc" }
254 wsCalc wsError
255 ]]></sample>
256
257 <p>
258 The next file, <b>calc.cd</b>, contains the processing of the SOAP
259 message and the generation of the response message.
260 <br/>
261 <code>load_xml</code> converts the string containing the SOAP
262 message in a SOAP XML structure which is passed
263 to <code>SoapEnv.extract_message</code> and <code>SoapEnv.hd</code> to
264 extract the content of the body of the SOAP structure.
265 <br/>
266 The function <code>compute</code> processes the message and returns a
267 result in a response message, which is embedded in a SOAP envelope by <code>SoapEnv.to_soap</code>.
268 </p>
269
270 <sample><![CDATA[include "../common.cd"
271 using SoapEnv = "soapenv";;
272
273 let compute (op : Operation) : Response =
274 match op with
275 <ns:add>[<a>a <b>b] ->
276 <ns:addResponse>[<result>(string_of ((int_of a) + (int_of b)))]
277 | <ns:sub>[<a>a <b>b] ->
278 <ns:subResponse>[<result>(string_of ((int_of a) - (int_of b)))]
279 | <ns:mul>[<a>a <b>b] ->
280 <ns:mulResponse>[<result>(string_of ((int_of a) * (int_of b)))]
281 | <ns:div>[<a>a <b>b] ->
282 <ns:divResponse>[<result>(string_of ((int_of a) div (int_of b)))];;
283
284 let calc (s : Latin1) : SoapEnv.Envelope =
285 let xml = load_xml [ 'string:' !s] in
286 let res = SoapEnv.hd (SoapEnv.extract_message xml) in
287 let op :? Operation = res in
288 let answer = compute op in
289 SoapEnv.to_soap answer;;
290 ]]></sample>
291
292 <p>
293 The last file, <b>client.cd</b>, executes the following steps:
294 </p>
295 <ul>
296 <li>it creates a message of type Operation. </li>
297 <li>the message is embedded in a SOAP envelope
298 using <code>SoapEnv.to_soap</code></li>
299 <li>it is then converted as a string by
300 <code>print_xml</code> and sent to the server
301 with <code>Cduce_ws.send</code>, where the parameters are: the
302 message string, the host address, the soap action, and the content
303 type.
304 <br/> The returned value of <code>send</code> is a Latin1 string
305 with the response message in SOAP.
306 </li>
307 <li>the response message is converted back in XML by <code>load_xml</code>.</li>
308 <li>the body part of the SOAP response is extracted
309 using <code>SoapEnv.extract_message</code>, and printed.</li>
310 </ul>
311
312 <sample><![CDATA[include "../common.cd"
313 using SoapEnv = "soapenv";;
314
315 let msg :? Operation = <ns:add>[ <a>"24" <b>"18" ];;
316
317 let _ =
318 let msg_soap = SoapEnv.to_soap msg in
319 let answer_string = Cduce_ws.send (print_xml msg_soap)
320 "http://localhost/ws/ws_calc" "" "text/xml; charset=utf-8" in
321 print [ 'CDuce: ' !answer_string '\n'];
322 let xml = load_xml [ 'string:' !answer_string ] in
323 let soap_answer :? SoapEnv.Envelope = xml in
324 print (string_of (SoapEnv.extract_message xml));;
325 ]]></sample>
326
327 </box>
328
329 </page>
330
331

CVS Admin">CVS Admin
ViewVC Help
Powered by ViewVC 1.1.5