Creating MapFish Web Services
-----------------------------

The framework provides a command for automatically generating web services for
creating, reading, updating and deleting geographic objects (features). Web
services generated with the framework implement specific HTTP interfaces.
These interfaces are described in `Protocol page <../protocol.html>`_.

.. note::
    MapFish web services are also called `layers`, both terms will be used
    interchangeably in the rest of this documentation.

A MapFish web service generated by the framework operates on the data of a
geographic database table. Because MapFish uses `GeoAlchemy <http://geoalchemy.org/>`_
several databases are supported (as of today: PostgreSQL/PostGIS, MySQL, SQLite/Spatialite
and Oracle).

It is important to note that the code of generated web services belongs to the
application. You, as the application developer, can therefore customize the generated
web services at will. You are completely free to not rely on code generation,
and manually create your web services.

Before you can have working MapFish web services you need to configure a
database connection in the application's configuration file (``development.ini``).
A database connection is set through the ``sqlalchemy.url`` property. This
specifies the data source name (DSN) for the database, for PostgreSQL/PostGIS 
it looks like this::

    sqlalchemy.url = postgresql://username:password@host:port/database


Creating a MapFish web service is done in two steps. The first step involves
describing the database table in the ``layers.ini`` configuration file. The
second step involves invoking the ``paster mf-layer`` command.

.. _layer-ini-2-0:

``layers.ini``
    The ``layers.ini`` file is the layer configuration file. Its syntax is as
    defined in the `documentation
    <http://docs.python.org/library/configparser.html>`_  of the Python
    Standard Library's Configuration file parser module.

    As an example, here is what would the description of a table named
    ``users`` look like in the ``layers.ini`` file::

        [users]
        singular=user
        plural=users
        table=users
        epsg=4326
        geomcolumn=the_geom
        geomtype=Point
        schema=people

    The name given in the square brackets, ``users`` in the above example, is
    the identifier of the layer. It will be used in the command when generating
    the web service.

    We describe below each layer property:

    ``singular``
        The ``singular`` property provides a singular name for the layer. This
        is used by the framework for naming variables and classes in the
        generated code.

    ``plural``
        The ``plural`` property provides a plural name for the layer. Likewise
        ``singular`` this is used by the framework for naming variables and
        classes in the generated code.

    ``table``
        The ``table`` property provides the name of database table.

    ``epsg``
        The ``epsg`` property provides the EPSG code of the spatial reference
        system (SRS) of the table data.

    ``geomcolumn``
        The ``geomcolumn`` property provides the name of the table's
        geometry column.

    ``geomtype`` (optional)
        The ``geomtype`` property provides the geometry type of the table's
        geometry column (for example ``Point`` or ``Polygon``). If no value is
        given, ``Geometry`` is used as geometry type. 

    ``schema`` (optional)
        The ``schema`` property provides the name of the table's
        schema.

``paster mf-layer``
    The second step involves entering the ``paster mf-layer`` command with the
    layer identifier as the argument to the command. This command must be
    entered from within the application's main directory (``HelloWorld`` in our
    example).  The command used to generate the ``users`` web service is::

        (venv) $ paster mf-layer users

    The output of the command looks like this::

        Creating /home/elem/HelloWorld/helloworld/controllers/users.py
        Creating /home/elem/HelloWorld/helloworld/tests/functional/test_users.py

        To create the appropriate RESTful mapping, add a map statement to your
        config/routing.py file in the CUSTOM ROUTES section like this:

        map.resource("user", "users")

        Creating /home/elem/HelloWorld/helloworld/model/users.py

    As indicated in the output the ``mf-layer`` command generates three files: a
    controller file, a model file and a test file. The output also indicates to
    edit the ``helloworld/config/routing.py`` file and add a route to the ``users``
    controller in this file. The CUSTOM ROUTES section should look like this::

        # CUSTOM ROUTES HERE
        map.resource("user", "users")
        map.connect('/{controller}/{action}')
        map.connect('/{controller}/{action}/{id}')

You can now visit, for example, http://localhost:5000/users?limit=3 in your
browser. You should get a `GeoJSON <http://geojson.org>`_ representation of the
first three users of the ``users`` table. Look at the `Protocol page
<../protocol.html>`_ to know more about parameters that can be passed to MapFish
web services.

.. hint::
   Recommended reading:

   * `Pylons Book Chapter 9: URLs, Routing and Dispatch <http://pylonsbook.com/en/1.0/urls-routing-and-dispatch.html>`_ 
   * `Routes docs <http://routes.groovie.org/>`_