Water 5-System Interfaces-HTTPContract| Parameter key | Default value | Type | | root | req | | port | 80 | integer | | server_base_uri | null | type.<one_of request_or_response.uri string/> | | listen | true | boolean | | multi_thread | false | boolean | | debug | false | boolean | | root_folder | false | boolean | | host_name | "localhost" | string | | extension | null | | host | opt | | relative_uri | false | boolean | | default_server | false | boolean | | header | opt | | return_type | opt | | machine | null | | env | null | | session_id_cookie_name | "my_session_id" | string | | session_cookie_name | "my_session" | string | | sessions | opt | | session_type | true | boolean | | a_request | opt | type.<one_of request_or_response.uri string/> | | a_response | null | | requested_object | null | | subject | opt | | args | null | | Water Contract<class server
root =req
port =80
server_base_uri=null=<type.one_of request_or_response.uri string/>
listen =true
multi_thread =false
debug =false
root_folder =false
host_name ="localhost"
extension =null
host =opt
relative_uri =false
default_server=false
_default_server=<server root=wob port=8081 listen=true multi_thread=false host_name="localhost" host="localhost:8081" default_server=true sessions=<thing 374058681=<wob _name="my" cookie=<thing my_session_id=873225448/> _last_used=<datetime year=2007 month=10 day=13 hour=19 minute=18 second=36 millisecond=448/> _created_on=<datetime year=2007 month=10 day=13 hour=19 minute=18 second=36 millisecond=444/> id=374058681/> 457689001=<wob _name="my" cookie=<thing my_session_id=873225448/> _last_used=<datetime year=2007 month=10 day=13 hour=19 minute=19 second=28 millisecond=50/> _created_on=<datetime year=2007 month=10 day=13 hour=19 minute=19 second=28 millisecond=46/> id=457689001/> 552925765=<wob _name="my" cookie=<thing my_session_id=873225448/> _last_used=<datetime year=2007 month=10 day=13 hour=19 minute=18 second=21 millisecond=465/> _created_on=<datetime year=2007 month=10 day=13 hour=19 minute=18 second=21 millisecond=461/> id=552925765/> 777539830=<wob _name="my" cookie=<thing my_session_id=873225448/> _last_used=<datetime year=2007 month=10 day=13 hour=19 minute=18 second=43 millisecond=763/> _created_on=<datetime year=2007 month=10 day=13 hour=19 minute=18 second=43 millisecond=759/> id=777539830/> 774370541=<wob _name="my" cookie=<thing my_session_id=873225448/> _last_used=<datetime year=2007 month=10 day=13 hour=19 minute=10 second=7 millisecond=17/> _created_on=<datetime year=2007 month=10 day=13 hour=19 minute=10 second=7 millisecond=12/> id=774370541/> 509312100=<wob _name="my" cookie=<thing my_session_id=873225448/> _last_used=<datetime year=2007 month=10 day=13 hour=19 minute=18 second=27 millisecond=122/> _created_on=<datetime year=2007 month=10 day=13 hour=19 minute=18 second=27 millisecond=119/> id=509312100/> 535645858=<wob _name="my" cookie=<thing my_session_id=873225448/> _last_used=<datetime year=2007 month=10 day=13 hour=19 minute=18 second=37 millisecond=730/> _created_on=<datetime year=2007 month=10 day=13 hour=19 minute=18 second=37 millisecond=725/> id=535645858/> 705696771=<wob _name="my" cookie=<thing my_session_id=873225448/> _last_used=<datetime year=2007 month=10 day=13 hour=19 minute=18 second=42 millisecond=65/> _created_on=<datetime year=2007 month=10 day=13 hour=19 minute=18 second=42 millisecond=61/> id=705696771/> 313031867=<wob _name="my" cookie=<thing my_session_id=873225448/> _last_used=<datetime year=2007 month=10 day=13 hour=19 minute=18 second=42 millisecond=834/> _created_on=<datetime year=2007 month=10 day=13 hour=19 minute=18 second=42 millisecond=829/> id=313031867/> 741656256=<wob _name="my" cookie=<thing my_session_id=873225448/> _last_used=<datetime year=2007 month=10 day=13 hour=19 minute=15 second=14 millisecond=319/> _created_on=<datetime year=2007 month=10 day=13 hour=19 minute=15 second=14 millisecond=315/> id=741656256/> 214992087=<wob _name="my" cookie=<thing my_session_id=873225448/> _last_used=<datetime year=2007 month=10 day=13 hour=19 minute=18 second=39 millisecond=613/> _created_on=<datetime year=2007 month=10 day=13 hour=19 minute=18 second=39 millisecond=609/> id=214992087/> 503552892=<wob _name="my" cookie=<thing/> _last_used=<datetime year=2007 month=10 day=13 hour=19 minute=44 second=32 millisecond=283/> _created_on=<datetime year=2007 month=10 day=13 hour=19 minute=44 second=32 millisecond=280/> id=503552892/>/> limit_access=ide.only_local_requests thread=<ja.org.waterlang.Server/> _name="localhost:8081"/>
header =opt
return_type =opt
machine =null
env =null
session_id_cookie_name="my_session_id"
session_cookie_name="my_session"
sessions =opt
session_type =true
a_request =opt=<type.one_of request_or_response.uri string/>
a_response =null
requested_object=null
subject =opt
args =null
_part_name_key="host"
/> | |
A call to server creates an http server on the given port (default 80)
that serves out the object given as the first argument, the 'root_object'.
<server root=<H1>Hello World</H1> port=8080/>
Once a server is running you can call it from water like so:
<resource "http://localhost:8080"/>.content
 | "<h1>Hello World</h1>" |
Use an extension to get back a formatted value:
<resource "http://localhost:8080/.htm"/>.content
 | '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<h1>Hello World</h1>' |
Or call it from a web browser like so:
<open_browser_window "http://localhost:8080"/>
 | "http://localhost:8080" |
Server can serve out static objects as well:
<server <thing temp=76 humidity=51/> port=8080/>
<resource "http://localhost:8080/temp.xml"/>.content
 | 76 |
<resource "http://localhost:8080/humidity"/>.<execute/>
 | 51 |
A more useful thing to do is to serve a method like so:
<server plus port=8080/>
<resource "http://localhost:8080/?0=4&1=5"/>.<execute/>
 | 9 |
Call/invoke from browser:
<open_browser_window "http://localhost:8080/?0=4&1=5"/>
The question mark in the url indicates that we are calling a method.
We are passing 4 as the value of the 0 parameter and
we are passing 5 as the value of the 1 parameter.
Since plus takes _vector_fields args, we can pass as many as we like:
<resource "http://localhost:8080/?0=4&1=5&2=6"/>.<execute/>
 | 15 |
We can also make our web service look like a local method like so:
wob.<set remote_plus=<resource "http://localhost:8080"/>/>
<remote_plus 0=3 1=4/>
 | 7 |
<remote_plus 3 4/>
7 <server <thing add=plus multiply=times/> port=8080/>
<resource "http://localhost:8080/add?0=4&1=5"/>.<execute/>
 | 9 |
Its time to build an interactive web page and a server that can read user input.
First we define a class that's going to have one method for each of the two pages
we are going to serve. Each method returns a hypertext object.
The server will call to_html on this object and deliver the resulting string
to the browser.
<class my_first_app> <!-- define the app -->
<method htm_class>
<FORM action="/simple_action.htm">
Type in some text:<INPUT name="a_value"/>
<INPUT type="submit" value="Do It"/>
</FORM>
</method>
<method simple_action a_value=req>
<H1> You entered: <do a_value/> </H1>
</method>
</class> my_first_app.<simple_action a_value="hi ben"/>
 | You entered: hi ben |
Launch the server:
<server my_first_app port=9090/>
<open_browser_window "http://localhost:9090"/>
When we call the server with no path in the url as we have done above,
the server looks for a htm_large method in the
server root which will call htm_class when
showing the class.
So the page we see in the browser contains one text input field and
one submit button named "Do it".
The user then types in some text and clicks on the button.
Notice the value of the action attribute to the FORM object
in the htm_class method.
That is the method that the server will call in response to the user clicking
on the submit button. In this case its called simple_action
Note that in the form action, it must be preceded by a slash.
The arguments passed to the method will be from the
controls, i.e. input tags in the content of the FORM call.
The mapping between the method parameters and the controls in the FORM is:
For each parameter in the method, look for a corresponding control of that name.
If it finds one, use the value of that control as the value to pass in to the
the method. Above you'll see the input attribute of name="a_value" and note
that the simple_action method has a corresponding parameter a_value
The browser passes only strings from the web page to the server,
but the Water server converts strings into data so that strings
that look like numbers or booleans are converted into numbers
or booleans before being passed to the method.
If the method has a required argument that is not supplied by the browser, error.
If the method has an optional argument that is not supplied by the browser,
its value is simply the default value of the parameter like normal method calls.
If the form has a control with no name, nothing will be sent to the server
The Water server can pass values from all HTML controls to Water methods including
checkboxes, radio buttons, password fields, text areas and select tags.
Checkboxes are particularly tricky because browsers do not pass back anything for
a checkbox that is unchecked. To deal with such situations, when you are defining
a method that will take the value of a checkbox, give it a default value of
false and/or declare it to be of type boolean The server will then makes
sure it gets passed true or false
Here is an example with many different control types:
<class lotsa_controls>
<method htm_class>
<form action="/register_user">
Your first name: <input type="text" name="first_name" value="Joe"/> <BR/>
Enter your password: <input type="password" name="a_password"/> <BR/>
<input type="checkbox" name="likes_ice_cream" checked=false/>
Do you like ice cream? <BR/>
<input type="radio" name="flavor" checked=false value="ya"/> chocolate <BR/>
<input type="radio" name="flavor" checked=true value="nah"/> vanilla <BR/>
Sport of choice? <select name="sport" size=1> <br/>
<option>baseball</>
<option>basketball</>
<option>knitting</>
</select> <br/>
Who do you admire?<TEXTAREA name="admire" cols=40 rows=3>Jimmy Page</TEXTAREA> <BR/>
<INPUT type="hidden" name="user_id" value="user_143"/>
<INPUT type="submit" name="registration" value="Register Me"/>
<INPUT type="submit" name="registration" value="Do Not Register Me"/>
</form>
</method>
<method register_user first_name=req a_password=req
flavor=req sport=req admire=req user_id=req registration=req
likes_ice_cream=false=boolean
>
<vector first_name " " a_password " " likes_ice_cream " " flavor
" " sport " " admire " " user_id " " registration/>
</>
</class> <server lotsa_controls/>
<open_browser_window "http://localhost"/>
The browser will show a page with:
- A one line text input field whose initial value is "Joe".
- A blank password field. Typing into this field will disguise
the characters you type.
- A checkbox whose initial state is unchecked.
- Two radio buttons, the second of which is selected.
- A drop down list of three sports. Since none are indicated as selected, the
first one will be selected by default.
- A 3 line text area with initial contents of "Jimmy Page".
- The hidden input field will not be shown on the page but will supply a
value to the server when the user chooses submit
- Two buttons.
If the user clicks the "Register Me" button without changing any of the controls,
the second page will have on it:
Joe false nah baseball Jimmy Page user_143 Register Me
Clicking the checkbox, choosing basketball, replacing Jimmy Page with Jeff Beck
and clicking on the Do Not Register Me button will show:
Joe true nah basketball Jeff Beck user_143 Do Not Register Me
Remember that each method that generates a hypertext object for a server
must return that object. In most cases this means that the object must be
made by the LAST expression in the body of the method.
Conversion of arguments
The Water server uses the types of fields for automatically converting
string argument values into other objects.
If you do not want the conversion to occur, set the type of a field to string
If a field has a default value but no type, the conversion will be based on
the type of the default value. For example, if the default value is true ,
then the field type is considered boolean and a string value of "off"
will be converted to false .
The conversion process calls from on the type and the first argument is
the submitted string value. The converted value is returned and passed to
the method.
If the field type is thing , a value that starts and ends with
angle-brackets will be converted into an object. At no time will any
methods or constructors be called during the conversion due to security
issues.
Serving Files
The Water server can also serve out files simila to the way a standard server does.
Here's how to make a server that can only server out one file.
(Not something you usually want to do, but instructive none the less.)
Example: serve one file only
<server <file "logical://user/images/wrightplane.jpg"/> port=8080/>
<open_browser_window "http://localhost:8080"/>
 | "http://localhost:8080" |
The one file should be shown in the browser.
Next a more usual case of serving a folder by having the folder be the
server root object.
Example: serve a folder
<server <folder "logical://user"/> port=8080/>
<open_browser_window "http://localhost:8080/images/wrightplane.jpg"/>
 | "http://localhost:8080/images/wrightplane.jpg" |
Again the requested file, ad1.jpg should show as an image in the file.
We can also have a file be the value of a field inside an object
that we are serving like so:
test case a file inside an object like so
Example: Serve a file inside an object
thing.<set my_file=<file "logical://user/images/wrightplane.jpg"/>/>
<server wob port=8080/>
<open_browser_window "http://localhost:8080/thing/my_file.jpg"/>
 | "http://localhost:8080/thing/my_file" |
Above we are serving out wob, the root object.
We have set wonb.thing.my_file to a Water file object.
Our url form the browser, http://localhost:8080/thing/my_file
references that file and it should be shown in the browser.
Instead of just a file being served out, a folder
can be part of a path of an object being servered out.
In this case, the path elements after the folder must all be subfolders,
except that the last one must be a file.
So below wob.thing.my_fold executes to a folder, the water user folder,
and we go down into the images subfolder and find the file ad1.jpg,
which should be shown in the browser.
Example: serve a nested folder
thing.<set my_fold=<folder "logical://user"/>/>
<server wob port=8080/>
<open_browser_window "http://localhost:8080/thing/my_fold/images/wrightplane.jpg"/>
 | "http://localhost:8080/thing/my_fold/images/wrightplane.jpg" |
You can decide how to divide up the subfolders between the object in the
Water object tree in the "my_fold" field and the url
passed to the browser. Below we make the url passed to the browser
shorter by including "images" in my_fold .
Example: serve a nested folder
thing.<set my_fold=<folder "logical://user/images"/>/>
<server wob port=8080/>
<open_browser_window "http://localhost:8080/thing/my_fold/wrightplane.jpg"/>
 | "http://localhost:8080/thing/my_fold/images/wrightplane.jpg" |
Methods Returning Files
If a method that the server calls reurns a file, that
file is served out.
Example: method returns file that is serverd.
<method get_image>
<file "logical://user/images/wrightplane.jpg"/>
</>
<server wob port=8080/>
<open_browser_window "http://localhost:8080/get_image?"/>
 | "http://localhost:8080/get_image?" |
We can parameterize our method so that it serves out a
different file depending on its argument. Here the
method dictates the folder, but the argument to it
tells us which file in the folder is to be served.
Example: parametize method that servers a file
<method get_image filename=req=string>
<file <join "logical://user/images/" filename/> />
</>
<server wob port=8080/>
<open_browser_window "http://localhost:8080/get_image?filename=wrightplane.jpg"/>
 | "http://localhost:8080/get_image?filename=ad2.jpg" |
Below we wrap some HTML around the image and use an IMG tag to
tell the server to get the image. The src of the IMG tag
references the get_image method which produces our image.
Note that our get_image method is very simple but it can
contain any Water code to dynamically compute what
image is to be served.
Example: use img src with url to method to get the file.
<method get_image filename=req=string>
<file <join "logical://user/images/" filename/> />
</>
<method test_image>
<DIV>
Here's an image:
<IMG src="/get_image?filename=wrightplane.jpg"/>
</DIV>
</method>
<server wob port=8080/>
<open_browser_window "http://localhost:8080/test_image.htm?"/>
 | "http://localhost:8080/test_image.htm?" |
© Copyright 2007 Clear Methods, Inc.