NAME

    wsf - Web Service Faker

VERSION

    This document describes wsf version 0.002.

USAGE

       shell$ WEBSERVICE_FAKE=/path/to/fake.yml wsf daemon

DESCRIPTION

    This application allows building fake web services. Well, they might be
    real... but don't trust the apps you will generate to be too powerful.

 Configuration File Definition

    The input definition file is YAML-formatted and its path is taken from
    environment variable WEBSERVICE_FAKE. By default, file
    webservice-fake.yml in the current directory is used. This file will be
    called configuration file in the following.

    The highest level is a key/value pairs hash. The following keys have a
    special meaning:

    defaults

      key/value pairs that will be taken as default values for some
      elements in the "routes". You can set the following items, see
      "routes" for details on each one:

	* "body_wrapper", a possible wrapper to be applied to each body
	generated by "routes". This can come handy to factor most of your
	response in a single place, and concentrate only on the parts that
	change;

	* "code", defaulting to 200;

	* "headers" - note that in this case the values specified here are
	added to the ones in each specification in "routes", so be sure to
	only put the ones that have to appear in every response;

	* "template_start" for Template::Perlish, defaulting to [%;

	* "template_stop" for Template::Perlish, defaulting to %];

    routes

      an array of route specifications. Each specification is an hash with
      the following possible keys:

      body

	a Template::Perlish text that will be used to generate the body for
	the response (but see also "body_wrapper");

      body_wrapper

	a Template::Perlish text that, if defined, will be used to wrap
	whatever is generated by "body". For example, in the following
	definition:

           # ...
           body: 'id -> [% stash.id %]'
           body_wrapper: >
              Hello, [% recipient %]. Here is what we have:
              [% content %]

	So, whatever is generated by "body" can then be wrapped in
	body_wrapper using the new variable content for espanding its text;

      code

	the code to return for the call

      headers

	array of key/value pairs for defining headers in the response. Each
	value is treated as a Template::Perlish template;

      method

	the HTTP method name. See "methods" if you want to specify more
	than one;

      methods

	an array with the list of HTTP methods;

      path

	the path of the route, anything accepted by Mojolicious will do,
	including placeholders and other amenities (e.g. / or /foo/:bar).

      All Template::Perlish templates have access to the following
      variables:

	* body_params: all parameters in the body of a POST request;

	* config: the configuration file contents

	* controller: the Mojolicious::Controller object that catched the
	request;

	* headers: headers in the request, as Mojo::Headers;

	* params: all parameters from the request (both GET and POST);

	* query_params: all parameters in the query (mostly for a GET
	request);

	* spec: the full specification that originated a specific route;

	* stash: the stash values for the request;

	* v: a shortcut to sub-item v inside the config, to ease your life
	for tracking your own variables.

      In addition, "body_wrapper" can also access whatever is generated by
      "body" through the key content.

 Example

    The following commented example should get you started.

       # vim: ts=2 sw=2 expandtab
       defaults:
         body_wrapper: |
           {
             "status": true,
             "data": [% content %]}
         headers:
           - X-Whatever: hello
             X-Hey: "You [%= join '/', sort keys %{V('headers')} %] rock"
       somestuff: &somestuff >
         {"hey":"joe"}
       v:
         some_array:
           - one
           - two
           - three
         x: starter
       routes:
         # this route gets the same behaviour for GETs and POSTs.
         # Default body_wrapper applies here because there's no overriding
         - path: '/'
           methods: [ GET, post ]
           headers:
             - Server: 'My::Server'
           body: '{"message":"ciao [% query_params.name %]"}'
         # this route gets a custom wrapping and a single method
         - path: '/simple'
           method: get
           headers:
             - Content-Type: text/plain
           body: 'hullo'
           body_wrapper: "I say: [% content %]\n"
         # this route does not get and wrapping at all
         - path: '/nowrap'
           method: get
           headers:
             - Content-Type: text/plain
           body: "LOOK MA', NO WRAP!\n"
           body_wrapper: ~
         # this leverages upon YAML to get stuff around in this file
         - path: '/somestuff'
           body: *somestuff
         # this modifies a variable that can be reused in following requests
         - path: '/add'
           method: post
           code: 201
           headers:
             - Content-Type: text/plain
           body: |
             [%= push @{V "v.some_array"}, time(); "ok" %]
           body_wrapper: ~
         # this prints out the list in v.some_array (see above). It can be
         # used to check that /add actually works
         - path: '/visit-config'
           body: >
             [[%= join ", ", map { qq{"$_"} } A "v.some_array" %]]
         # these two team up. The first one prepares the answer that the second
         # will give out
         - path: '/prepare/:id'
           method: post
           body: '[% V("v")->{x} = (A("v.some_array"))[V "stash.id"]; %]'
           code: 204
           body_wrapper: ~
         - path: '/whatnow'
           method: get
           body: '[% v.x %]'
           body_wrapper: ~

BUGS AND LIMITATIONS

    Report bugs through GitHub (patches welcome).

SEE ALSO

    WebService::Fake.

AUTHOR

    Flavio Poletti <polettix@cpan.org>

COPYRIGHT AND LICENSE

    Copyright (C) 2016 by Flavio Poletti <polettix@cpan.org>

    This module is free software. You can redistribute it and/or modify it
    under the terms of the Artistic License 2.0.

    This program is distributed in the hope that it will be useful, but
    without any warranty; without even the implied warranty of
    merchantability or fitness for a particular purpose.

