Server Services == Description == A //service// is a special function that resides on the server and that can be invoked from client. This page describes how to create and how to use //services// on the servers and how to invoke them from servers and clients. == Synopsis == === Server === (service (arg ...) ...) (define-service (name arg ...) ...) (service-resource svc ...) (service-base-url svc req) (procedure->service proc) (hop-autoload-directories) (hop-autoload-directory-add! path) (hop-autoload-directories-set! list) === Server & Client === (with-hop (svc arg ...) [attributes ...] [success] [failure]) === Client === (with-hop-default-anim) (with-hop-default-anim-set! anim) == Examples == service == Server Definitions == A service is a function on that resides on the server. In most cases, a service returns an HTML tree (i.e., any object constructed by any markup), a string, or a number. An instance of any subclass of ::%http-response is also permitted as return value. Other values are automatically converted into instances of this class. See the description of ++with-hop++ for a detailed presentation of automatic coercions that take place when a service is invoked. === ++(service [:timeout tm] [:ttl tl] [:url u] (arg0 ...) body)++ === service ^ arguments ^ type ^ short description ^ | :timeout | integer | An optional timeout. | | :ttl | integer | An optional time-to-live. | | :url | string | An optional associated url. | | :name | string | An optional associated url. | | arg0 | symbol | the first argument identifier. | | body | expression | the body of the service. | This special form defines an //anonymous// service on the client. That is, no public URL is associated with this service. ~~ The :timeout argument controls how long this service is valid. When the timeout (a number of seconds) is expired the service is invalidated. ~~ the :ttl argument controls how many the service can be invoked before being invalidated. ~~ the :url argument specifies a full URL that can be used to invoke the service. ~~ the :name argument specifies a relative URL suffix that can be used to invoke the service. The whole URL is produced by the expression ++(make-hop-url-name name)++ === ++(define-service (name arg0 ...) body)++ === define-service ^ arguments ^ type ^ short description ^ | name | symbol | the name of the service. | | arg0 | symbol | the first argument identifier. | | body | expression | the body of the service. | The ++name++ is a symbol containing only letters, digits and, at most, on slash (++/++) character. A service whose name contains no slash character is called a **//weblet//**. This special form defines an //named// service on the client. It differs from the form ++service++ in two respects: * it binds the service to a global variable ++name++. * it binds the service with a public URL that can be used to invoke the service. The URL is forged by containing the value returned by ++hop-service-base++, the separator ++/++, and the ++name++ of the service. In the current setting ++hop-service-base++ being ++",(hop-service-base)"++, The form ++(define-service (foo/bar ...) ..)++ would bind the service to the URL ++",(string-append (hop-service-base) "/foo/bar")"++. === ++(service-resource svc [file])++ === service-resource ^ arguments ^ type ^ short description ^ | svc | service | the service. | | file | ::bstring or #f | a relative file name. | The function ++service-resource++ constructs a file name that is relative to the //resource directory// of the service ++svc++. The service resource directory is the directory that contains the source file of the service. Typically this is the directory where the autoload service source file is stored. See also ++service-base-url++. ~~ let's suppose a service ++foo++ implemented in a file ++dir/foo.hop++ that uses an image ++img.jpg++ stored inside the directory ++dir/images++ and a HSS file ++dir/foo.hss++. Referring to ++img.jpg++ and ++foo.hss++ could be done via ++(service-resource foo ...)++. This is illustrated by the following example. (define-service (foo) ( ( :css (service-resource foo "foo.hss") ...) ( ... ( :src (service-resource foo "images/img.jpg")) ...))) === ++(service-base-url svc req)++ === service-base-url ^ arguments ^ type ^ short description ^ | svc | service | the service. | | req | ::http-request | a request. | The function ++service-base-url++ computes the URL that denotes the file implementing the service ++svc++. It differs from ++service-resource++ by constructing an absolute URL with a protocol, a host name, a host port, and a file name. ~~ In general ++service-base-url++ is used inside the ++++ markup :base attribute. Using the base associated with a service is useful when that service requires local resources such as images and when it is convenient to store these resources one a directory containing the implementation of ++svc++. For instance, let's suppose a service ++foo++ implemented in a file ++dir/foo.hop++ that uses an image ++img.jpg++ stored inside the directory ++dir/images++. In order to use the relative reference ++images/imp.jpg++ for denoting the image, it is required to define a ++++ element whose :base attribute is given by ++(service-base-url foo (current-request))++. (define-service (foo) ( ( :base (service-base-url foo (current-request)) :css "foo.hss" ...) ( ... ( :src "images/img.jpg") ...))) ~~ One has to keep in mind that setting the :base of a document affects **all** its relative references. In particular, in the following example: ( ( :base (service-base-url foo (current-request)) ...) ( ... ( :href "#lbl1"))) the URI ++"#lbl1"++ no longer refers to the current document URL. It actually refers to ++http://XXX/dir/#lbl1++ which is probably not a valid URL! The :base attribute has to be used cautionly. ~~ Some web browsers poorly implement the ++++ markup of the ++++ section. These browsers (typically [[http://www.mozilla.org|Firefox]]) requires the base URI to a a URL. Which such browsers the :base attribute cannot be produce by the function ++(service-resource ...)++ which produces a relative URI. === ++(procedure->service proc)++ === procedure->service ^ arguments ^ type ^ short description ^ | proc | procedure | a procedure. | The function ++procedure->service++ creates an anonymous service that wraps the procedure ++proc++. === ++(hop-autoload-directories)++ === === ++(hop-autoload-directory-add! string)++ === === ++(hop-autoload-directories-set! list)++ === hop-autoload-directories hop-autoload-directory-add! hop-autoload-directories-set! This parameter specifies the path scanned by HOP on startup to find all the currently available weblets. These are automatically //autoloaded//. That is, they are automatically loaded on demand. ~~ The current value of ++hop-autoload-directories++ is: ,(
:align "center" (
 
	   (with-output-to-string 
	      (lambda () 
		 (print "(")
		 (for-each (lambda (v) (display " ") (write v) (newline))
			   (hop-autoload-directories))
		 (display ")")))))






== Server & Client Definitions ==




=== (with-hop (svc v0 ...) [attributes ...] [success] [fail]) ===
 with-hop
 with-hop

^  arguments       ^   type              ^  short description               ^
| svc              |  service            | the invoked service.             |
| v0    |  obj                | the first argument.              |
| ...              |  ...                | ...                              |
| vn    |  obj                | the nth argument.     |
| success          |  procedure          | a procedure of one argument.     |
| fail             |  procedure          | a procedure of one argument.     |



^  common attributes  ^   type           ^  short description               ^
| :name             |  string            | a remote user name.              |
| :password         |  string            | a remote user password.          |
| :authorization    |  string            | a remote authorization.          |
| :timeout          |  integer           | An optional timeout.             |
| :host             |  string             | a remote server name.        |
| :port             |  integer            | a remote server port.        |
| :abspath          |  string             | the abspath of the service.  |



^  client arguments  ^   type   ^  short description  ^
| :anim        |  procedure or bool  | the animation to play while calling.  |



~~ The special form ++with-hop++ invokes the server service ++svc++ with
arguments ++v0++, ... On success, it then invokes the
function ++success++ with an object constructed from the service
answer. On failure, it invokes ++failure++. 

~~ When a remote ++host++ may be specified, the service is executed on
the remote host.  Otherwise, when ++with-hop++ is used from a server
without specifying a remote ++host++, the service is executed
locally.

~~ When used from a client **only**, an animation procedure can be
specified. This procedure of one argument should return a DOM object
that is inserted in the document during a ++with-hop++ call. This
object is automatically hidden when the call completes. If no :anim
attributed is specified, then the value return by ++((with-hop-default-anim))++
is used as animation.
o

~~ The evaluation of the service ++svc++ produce a response.  If its
type is not an instance of ::%http-response HOP performs automatic
casts for converting value into instance of ::%http-response. For an
object ++res++, here are the rules that are applied:

  * if ++res++ is an XML object (built by a markup), it is automatically
 converted into an instance of ::http-response-hop.
  * if ++res++ is a pair for which at least one element is an XML object, they
 whole result is converted into an instance of ::http-response-hop.
  * if ++res++ is a string, it is converted into an instance of 
 ::http-response-string.
  * otherwise, ++res++ is converted into an instance of ::http-response-js.


If the response is an instance of ::http-response-js then result it is
interpreted by the client object as a compound object (i.e., a list, a
vector, ...). It it is an instance of the ::http-response-hop or
::http-response-string, it is interpreted as a string.

==== Examples =====

We present various examples that illustrates the different ways to
use the ++with-hop++ form.

===== 1. Sending HTML tree from the server to the client =====

In this first example, an anonymous service send a HTML table to
a client. The return type of the service is an XML element, as
constructed by any markup.

Sending a HTML tree

===== 2. Sending Complex Values =====

In this second example, the server send to the client a instance of a local
class. In this example, the client receives a object that it discriminates
(using the ++obj.x++ and ++obj.y++ expressions) for building a string
that is injected inside the currently visualized HTML tree.

Sending complex values

===== 3. Invoking Services From The Server =====

In this example, we invoke a service directly from the server. The form
++with-hop++ is not protected with a ++~++ client escape marker. It is
then evaluated as all expressions on the server.

Invoking a service from the server

===== 4. Invoking Services From Server To Server =====

In this last example, ++with-hop++ is used to invoke a service from
a remote service. As for the previous example, the form ++with-hop++
is not protected with a ++~++ client escape marker, which means that it
is evaluated on the server. Contrary to the previous address a remote
host is specified using the :host argument.

Invoking a remote service from the server

~~ In this last example, we show how server to server service invocation
may transmit compound values. In the example above, one service sends
an HTML tree. The other one sends a list of strings.

Invoking remote services from the server

===== 5. Specifying a custom animation ====

This example shows how to specify a custom animation when calling
a server service.

WITH-HOP animation









== Client Definitions ==

=== (with-hop-default-anim) ===

 with-hop-default-anim

The function ++with-hop-default-anim++ returns the default function for
producing visual animations during ++with-hop++ calls.


=== (with-hop-default-anim-set! procedure) ===
 with-hop-default-anim-set!

^  arguments       ^   type              ^  short description               ^
| anim             |  procedure or bool  | a procedure of one argument.     |



The function ++with-hop-default-anim-set!++ set! the default function for
producing visual animations during ++with-hop++ calls. It returns the
previous default animation function.




== See also ==
service, define-service, procedure->service, hop-autoload, with-hop