Web::DataService - a framework for building data service applications for the Web


Version 0.42


This module provides a framework for you to use in building data service applications for the World Wide Web. Such applications sit between a data storage and retrieval system on one hand and the Web on the other, and fulfill HTTP-based data requests. Each valid request is handled by fetching or storing the appropriate data using the backend data system and serializing the output in a format such as JSON, CSV, or XML.

Using the methods provided by this module, you start by defining a set of data service elements: output formats, output blocks, vocabularies, and parameter rules, followed by a set of data service nodes representing the various operations to be provided by your service. Each of these objects is configured by a set of attributes, optionally including documentation strings. You continue by writing one or more modules whose methods will carry out the core part of each data service operation: talking to the backend data system to fetch and/or store the relevant data, based on the parameter values provided in a data service request.

The Web::DataService code then takes care of most of the work necessary for handling each request, including checking the parameter values, determining the response format, calling your operation method at the appropriate time, and serializing the result. It also generates appropriate error messages when necessary. Finally, it auto-generates documentation pages for each operation based on the elements you have defined, so that your data service is always fully and correctly documented.

A Web::DataService application is built on top of a "foundation framework" that provides the basic functionality of parsing HTTP requests and constructing responses. At the present time, the only one that can be used is Dancer. However, we plan to add compatibility with other frameworks such as Mojolicious and Catalyst soon.


This documentation describes the methods of class Web::DataService. For additional documentation, see the following pages:


A description of the request-handling process, along with detailed documentation of the methods that can be called with request objects.


A detailed description of this module and its reasons for existence.


A step-by-step guide to the example application included with this distribution.


A detailed description of how to configure a data service using this framework. This page includes sub-pages for each different type of data service element.


An overview of the elements available for use in documentation templates.


Features that are available for debugging your application.



new ( { attributes ... } )

This class method defines a new data service instance. Calling it is generally the first step in configuring a data service application. The available attributes are described in ""Data service instantiation:" in Web::DataService::Configuration. The attribute name is required; the others are optional, and some of them may be specified in the application configuration file instead.

Once you have a data service instance, the next step is to configure it by adding various data service elements. This is done by calling the methods listed below.


The following methods are used to configure a data service application. For a list of the available attributes for each method, and an overview of the calling convention, see Web::DataService::Configuration. For detailed instructions on how to set up a data service application, see Web::DataService::Tutorial.

set_foundation ( module_name )

You can call this as a class method if you wish to use a custom foundation framework. The argument must be the module name, which will be require'd. This call must occur before any data services are defined.

define_vocab ( { attributes ... }, documentation ... )

Defines one or more vocabularies, using the specified attributes and documentation strings. Each vocabulary represents a different set of terms by which to label and express the returned data.

define_format ( { attributes ... }, documentation ... )

Defines one or more output formats, using the specified attributes and documentation strings. Each of these formats represents a configuration of one of the available serialization modules.

define_node ( { attributes ... }, documentation ... )

Defines one or more data service nodes, using the specified attributes and documentation strings. Each of these nodes represents either an operation provided by the data service or a page of documentation.

list_node ( { attributes ... }, documentation ... )

Adds one or more entries to a node list, which can be used to document lists of related nodes. You can use this to document node relationships that are not strictly hierarchical.

define_block ( block_name, { attributes ... }, documentation ... )

Defines an output block with the given name, containing the specified output fields and documentation.

define_set ( set_name, { attributes ... }, documentation ... )

Defines a named set of values, possibly with a mapping to some other list of values. These can be used to specify the acceptable values for request parameters, to translate data values into different vocabularies, or to specify optional output blocks.

define_output_map ( set_name, { attributes ... }, documentation ... )

This method is an alias for define_set.

define_ruleset ( ruleset_name, { attributes ... }, documentation ... )

Defines a parameter ruleset with the given name, containing the specified rules and documentation. These are used to validate parameter values.


The following methods are available for you to use in the part of your code that handles incoming requests. This will typically be inside one or more "route handlers" or "controllers" defined using the foundation framework.

handle_request ( outer, [ attrs ] )

A call to this method directs the Web::DataService framework to handle the current request. Depending on how your application is configured, one of the data service operation methods that you have written may be called as part of this process.

You may call this either as a class method or an instance method. In the former case, if you have defined more than one data service instance, the method will choose the appropriate instance based on either the path prefix or selector parameter depending upon which features and special parameters you have enabled. If you know exactly which instance is the appropriate one, you may instead call this method on it directly.

The first argument must be the "outer" request object, i.e. the one generated by the foundation framework. This allows the Web::DataService code to obtain details about the request and to compose the response using the functionality provided by that framework. This method will create an "inner" object in a subclass of Web::DataService::Request, with attributes derived from the current request and from the data service node that matches it. If no data service node matches the current request, a 404 error response will be returned to the client.

You may provide a second optional argument, which must be a hashref of request attributes (see Web::DataService::Request). These will be used to initialize the request object, overriding any automatically determined attributes.

This method returns the result of the request (generally the body of the response message), unless an error occurs. In the latter case an exception will be thrown, so your main application should include an appropriate handler to generate a proper error response. See the file lib/ in the tutorial example for more about this.

new_request ( outer, [ attrs ] )

If you wish more control over the request-handling process than is provided by handle_request, you may instead call this method. It returns an object blessed into a subclass of Web::DataService::Request, as described above for handle_request, but does not execute it.

You can then examine and possibly alter any of the request attributes, before calling the request's execute method. This method may, like handle_request, be called either as a class method or an instance method.

execute_request ( request )

This method may be called to execute a request. The argument must belong to a subclass of Web::DataService::Request, created by a previous call to new_request. This method may, like handle_request, be called either as a class method or an instance method.

node_attr ( path, attribute )

Returns the specified attribute of the node with the specified path, if the specified path and attribute are both defined. Returns undef otherwise. You can use this to test whether a particular node is in fact defined, or to retrieve any node attribute.

You will rarely need to call this method, since for any request the relevant attributes of the matching node will be automatically used to instantiate the request object. In almost all cases, you will instead use the attribute accessor methods of the request object.

config_value ( name )

Returns the value (if any) specified for this name in the application configuration file. If the name is found as a sub-entry under the data service name, that value is used. Otherwise, if the name is found as a top-level entry then it is used.

has_feature ( feature_name )

Returns a true value if the specified feature is enabled for this data service. Returns false otherwise.

special_param ( parameter_name )

If the specified special parameter is enabled for this data service, returns the parameter name which clients use. This may be different from the internal name by which this parameter is known, but will always be a true value. Returns false if this parameter is not enabled.

generate_site_url ( attrs )

This method is called by the generate_url method of Web::DataService::Request. You should be aware that if you call it outside of the context of a request it will not be able to generate absolute URLs. In most applications, you will never need to call this directly and can instead use the latter method. The argument must be a hash reference, and the accepted keys are listed in the documentation for the latter method.


If a backend plugin is available, this method obtains a connection handle from it. You can use this method when initializing your operation roles, if your initialization process requires communication with the backend. You are not required to use this mechanism, and may connect to the backend in any way you choose.


Turn on one of the following modes, which are provided primarily for testing and debugging purposes. These modes are set for the entire process, not for a single data service.


Debugging statements will be written to STDERR. Any data service operation code that you write should check for this mode being set, and if it is then call debug_line to write out appropriate debugging information including the text of any SQL statements issued to the database.


All output to STDERR is suppressed, even important warning messages. This is useful mainly during unit tests, where error conditions are explicitly generated to check that the proper response occurs.


This mode should be set when a request is specified via command-line arguments. It causes only those roles necessary for the specified request to be initialized, instead of all roles included in the data service configuration.


This mode should be set when diagnostic output is requested via the command line. It directs the diagnostic routines to be called using the information specified on the command line, rather than the usual request-handling routines.


This mode should be set when a single data service process is run for debugging purposes. It has no effect on the Web::DataService code, but data operation code can check for it and use permanent tables rather than temporary ones, which can make debugging easier.

is_mode ( mode )

Returns true if the specified mode has been enabled for this data service process (not just for this data service). Returns false otherwise.


Returns true if 'debug' mode has been enabled for this process (not just for this data service).

debug_line ( text )

If 'debug' mode is enabled, prints out the specified text followed by a newline to STDERR.

accessor methods

Each of the data service attributes is provided with an accessor method. This method returns the attribute value, but cannot be used to set it. All data service attributes must be set when the data service object is instantiated with new, either specified directly in that call or looked up in the application configuration file provided by the foundation framework.


The following methods are used in generating documentation. If you use documentation templates, you will probably not need to call them directly.

document_vocabs ( path, { options ... } )

Returns a documentation string in Pod for the vocabularies that are allowed for the node corresponding to the specified path. The optional options hash may include the following:


If this option has a true value then all vocabularies are documented, not just those allowed for the given path.


If this option has a true value then the documentation string is included for each vocabulary.

document_formats ( path, { options ... } )

Return a string containing documentation in Pod for the formats that are allowed for the node corresponding to the specified path. The optional options hash may include the following:


If this option has a true value then all formats are documented, not just those allowed for the given path.


If this option has a true value then the documentation string is included for each format.

document_nodelist ( list, { options ... } )

Returns a string containing documentation in Pod for the specified node list. Each node has a default node list whose name is its node path, and you can define other lists arbitrarily by using the method list_node. The optional options hash may include the following:


If this documentation string has a non-empty value, then usage examples will be included if they are specified in the node list entries. The value of this attribute will be included in the result between each node's documentation string and its usage list, so it should be a string such as "For example:".


valid_name ( name )

Returns true if the given string is valid as a Web::DataService name. This means that it begins with a word character and includes only word characters plus the punctuation characters ':', '-' and '.'.

set_mode ( mode ... )

You can call this either as a class method or as an instance method; it has a global effect either way. This method turns on one or more of the following modes:


Produces additional debugging output to STDERR.


Configures the data service to satisfy one request and then exit. This is generally used for testing purposes.

You will typically call this at application startup time.


mmcclenn "at"


Please report any bugs or feature requests to bug-web-dataservice at, or through the web interface at I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.


Copyright 2014 Michael McClennen, all rights reserved.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.