# Creating a Tcl Web Service

## Loading the Webservices Server Package

To load the webservices server package, do:

     package require WS::Server

This command will only load the server the first time it is used, so it causes no ill effects to put this in each file declaring a service or service procedure.

### Using as part of TclHttpd

The Web Services package, WS::Server, is not a standalone application, but rather is designed to be a "module" of TclHttpd. The following command is normally placed in httpdthread.tcl:

### Embedding in a Standalone Application

To embed a Web Service into an application, the application needs to be event driven and you also need to use the WS::Embeded package. You also must define the service with the -mode=embedded option.

See also Embedding a Web Service into an application.

### Using with Apache Rivet

Apache Rivet is a module (mod_rivet) that can be loaded by Apache httpd server to allow web pages to run embedded Tcl commands in a way similar to PHP. To create a Web Service in Rivet, use the example EchoRivetService.rvt as a starting point by simply copying it into any directory served by your Apache instance. You should be able to immediately access that new location at the following URLs:

                   /path/to/EchoRivetService.rvt/doc
                         Displays an HTML page describing the service
                   /path/to/EchoRivetService.rvt/wsdl
                         Returns a WSDL describing the service
                   /path/to/EchoRivetService.rvt/op
                         Invoke an operation

If you would prefer to expose the published URLs of your service differently, you can use the standard Apache mod_rewrite or mod_alias modules to transparently map any other URL to those locations.

## Defining a Service

The code that defines a service is normally placed in one or more files in the custom directory.

Procedure Name : ::WS::Server::Service

Description : Declare a Web Service, the following URLs will exist

                   /service/<ServiceName>
                         Displays an HTML page describing the service
                   /service/<ServiceName>/wsdl
                         Returns a WSDL describing the service
                   /service/<ServiceName>/op
                         Invoke an operation

Arguments : this procedure uses position independent arguments, they are:

                 -host           - The host name for this service.
                                   Defaults to "ip:port" in embedded mode,
                                   and to "localhost" otherwise."
                 -description    - The HTML description for this service
                 -xmlnamespace   - Extra XML namespaces used by the service
                 -service        - The service name (this will also be used for
                                     the Tcl namespace of the procedures that implement
                                     the operations.
                 -premonitor     - This is a command prefix to be called before
                                     an operation is called.  The following arguments are
                                     added to the command prefix:
                                        PRE serviceName operationName operArgList
                 -postmonitor    - This is a command prefix to be called after
                                     an operation is called.  The following arguments are
                                     added to the command prefix:
                                        POST serviceName operationName OK|ERROR results
                 -inheaders      - List of input header types.
                 -outheaders     - List of output header types.
                 -intransform    - Inbound (request) transform procedure (2.0.3 and later).
                                    The signature of the command must be:
                                         cmd \
                                             mode (REQUEST) \
                                             xml \
                                             notUsed_1 \
                                             notUsed_2
                 -outtransform   - Outbound (reply) transform procedure (2.0.3 and later).
                                    The signature of the command must be:
                                         cmd \
                                             mode (REPLY) \
                                             xml \
                                             operation \
                                             resultDict
                 -checkheader    - Command prefix to check headers.
                                       If the call is not to be allowed, this command
                                       should raise an error.
                                       The signature of the command must be:
                                         cmd \
                                             service \
                                             operation \
                                             caller_ipaddr \
                                             http_header_list \
                                             soap_header_list
                -mode           - Mode that service is running in.  Must be one of:
                                       tclhttpd  -- running inside of tclhttpd or an
                                                    environment that supplies a
                                                    compatible Url_PrefixInstall
                                                    and Httpd_ReturnData commands
                                       embedded  -- using the ::WS::Embedded package
                                       aolserver -- using the ::WS::AolServer package
                                       wub       -- using the ::WS::Wub package
                                       wibble    -- running inside wibble
                                       rivet     -- running inside Apache Rivet (mod_rivet)
                -ports          - List of ports for embedded mode. Default: 80
                                        NOTE -- a call should be to
                                                ::WS::Embedded::Listen for each port
                                                in this list prior to calling ::WS::Embeded::Start
                -prefix         - Path prefix used for the namespace and endpoint
                                  Defaults to "/service/" plus the service name
                -traceEnabled   - Boolean to enable/disable trace being passed back in exception
                                  Defaults to "Y"
                -docFormat      - Format of the documentation for operations ("text" or "html").
                                  Defaults to "text"
                -stylesheet     - The CSS stylesheet URL used in the HTML documentation

                -errorCallback  - Callback to be invoked in the event of an error being produced
                -verifyUserArgs - Boolean to enable/disable validating user supplied arguments
                                  Defaults to "N"
                -enforceRequired - Throw an error if a required field is not included in the
                                   response.
                                   Defaults to "N"

Returns : Nothing

Side-Effects : None

Exception Conditions :

         MISSREQARG -- Missing required arguments

Pre-requisite Conditions : None

## Defining an Operation (aka a Service Procedure)

Procedure Name : ::WS::Server::ServiceProc

Description : Register an operation for a service and declare the procedure to handle the operations.

Arguments :

         ServiceName     -- Name of the service this operation is for
         NameInfo        -- List of two elements:
                                 1) OperationName -- the name of the operation
                                 2) ReturnType    -- the type of the procedure return,
                                                     this can be a simple or complex type
         Arglist         -- List of argument definitions,
                             each list element must be of the form:
                                 1) ArgumentName -- the name of the argument
                                 2) ArgumentTypeInfo -- -- A list of:
                                        {type typeName comment commentString}
                                             typeName can be any simple or defined type.
                                             commentString is a quoted string describing the field
         Documentation   -- HTML describing what this operation does
         Body            -- The tcl code to be called when the operation is invoked. This
                                code should return a dictionary with <OperationName>Result as a
                                key and the operation's result as the value.

Available simple types are:

- anyType, string, boolean, decimal, float, double, duration, dateTime, time, date, gYearMonth, gYear, gMonthDay, gDay, gMonth, hexBinary, base64Binary, anyURI, QName, NOTATION, normalizedString, token, language, NMTOKEN, NMTOKENS, Name, NCName, ID, IDREF, IDREFS, ENTITY, ENTITIES, integer, nonPositiveInteger, negativeInteger, long, int, short, byte, nonNegativeInteger, unsignedLong, unsignedInt, unsignedShort, unsignedByte, positiveInteger

The typeName may contain the following suffixes:

- () : type is an array
- ? : type is an optional parameter

Returns : Nothing

Side-Effects :

       A procedure named "<ServiceName>::<OperationName>" defined
       A type name with the name <OperationName>Result is defined.

Exception Conditions : None

Pre-requisite Conditions : ::WS::Server::Server must have been called for the ServiceName

## Declaring Complex Types

See: Creating a Web Service Type from Tcl