Skip to content
This repository has been archived by the owner on Sep 28, 2022. It is now read-only.

Commit

Permalink
working on doc
Browse files Browse the repository at this point in the history
  • Loading branch information
jstoiko committed Sep 15, 2015
1 parent d64f555 commit 94e95e3
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 77 deletions.
71 changes: 35 additions & 36 deletions docs/source/crud_events.rst → docs/source/event_handlers.rst
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
CRUD Events
===========
Event Handlers
==============

Ramses supports Nefertari CRUD events. The following documentation describes how to define and connect them.
Ramses supports Nefertari event handlers. The following documentation describes how to define and connect them.

Writing Processors
------------------

You can write custom functions inside your ``__init__.py`` file, then add the ``@registry.add`` decorator before the functions that you'd like to turn into CRUD event subscribers. Ramses CRUD event subscribers has the same API as Nefertari CRUD event subscribers. Check Nefertari CRUD Events doc for more details on events API.
Writing Event Handlers
----------------------

You can write custom functions inside your ``__init__.py`` file, then add the ``@registry.add`` decorator before the functions that you'd like to turn into CRUD event handlers. Ramses CRUD event handlers has the same API as Nefertari CRUD event handlers. Check Nefertari CRUD Events doc for more details on events API.

E.g.

Expand All @@ -19,19 +20,16 @@ E.g.
event.set_field_value(value)
Connecting event subscribers
----------------------------

When you define event subscribers in your ``__init__.py`` as described above, you can apply them on either a per-model or a per-field basis.
Connecting Event Handlers
-------------------------

Subscribers are defined using the ``_event_handlers`` property. This property is an object, keys of which are called "event tags" and values are lists of subscriber names. Event tags are constructed of two parts: ``<type>_<action>`` whereby:
When you define event handlers in your ``__init__.py`` as described above, you can apply them on either a per-model or a per-field basis. If multiple handlers are listed, they are executed in the order in which they are listed. Handlers are defined using the ``_event_handlers`` property. This property is an object, keys of which are called "event tags" and values are lists of handler names. Event tags are constructed of two parts: ``<type>_<action>`` whereby:

**type**
Is either ``before`` or ``after``, depending on when subscriber should run - before view method call or after respectively.
Is either ``before`` or ``after``, depending on when handler should run - before view method call or after respectively.
**action**
Exact name of Nefertari view method that processes the request (action)
Exact name of Nefertari view method that processes the request (action).

Complete list of actions:
* **index** - Collection GET
* **create** - Collection POST
* **update_many** - Collection PATCH/PUT
Expand All @@ -42,25 +40,26 @@ Complete list of actions:
* **replace** - Item PUT
* **delete** - Item DELETE
* **item_options** - Item OPTIONS
* **set** - triggers on all the following actions: ``create``, ``update``, ``replace`` and ``update_many``

And one special action:
* **set** - triggers on either of the following actions: ``create``, ``update``, ``replace`` and ``update_many``

E.g. The following example connects the ``lowercase`` subscriber to the ``before_set`` event and the subscriber will run before any of the following requests are processed:
* Collection POST
* Item PATCH
* Item PUT
* Collection PATCH
* Collection PUT
E.g. This example connects the ``lowercase`` handler to the ``before_set`` event.

.. code-block:: json
"_event_handlers": {
"before_set": ["lowercase"]
}
The ``lowercase`` handler will run before any of the following requests are processed:

We will use the following subscriber to demonstrate how to connect subscribers to events. This subscriber logs ``request``.
* Collection POST
* Item PATCH
* Item PUT
* Collection PATCH
* Collection PUT


We will use the following handler to demonstrate how to connect handlers to events. This handler logs ``request``.

.. code-block:: python
Expand All @@ -72,23 +71,23 @@ We will use the following subscriber to demonstrate how to connect subscribers t
log.debug(event.view.request)
Using before/after events
-------------------------
Before vs After
---------------

``before`` events should be used to:
``Before`` events should be used to:
* Transform input
* Perform validation
* Apply changes to object that is being affected by the request using the ``event.set_field_value`` method

``after`` events should be used to:
``After`` events should be used to:
* Change DB objects which are not affected by the request
* Perform notifications/logging


Per-model subscribers
---------------------
Per-model Handlers
------------------

To register subscribers on a per-model basis, you can define the ``_event_handlers`` property at the root of your model's JSON schema. For example, if we have a JSON schema for the model ``User`` and we want to log all collection GET requests to the ``User`` model after they were processed (using the ``log_request`` subscriber), we can register the subscriber in the JSON schema like this:
To register handlers on a per-model basis, you can define the ``_event_handlers`` property at the root of your model's JSON schema. For example, if we have a JSON schema for the model ``User`` and we want to log all collection GET requests to the ``User`` model after they were processed (using the ``log_request`` handler), we can register the handler in the JSON schema like this:

.. code-block:: json
Expand All @@ -103,12 +102,12 @@ To register subscribers on a per-model basis, you can define the ``_event_handle
}
Per-field subscribers
---------------------
Per-field Handlers
------------------

To register subscribers on a per-field basis, you can define the ``_event_handlers`` property inside the fields of your JSON schema (same level as ``_db_settings``).
To register handlers on a per-field basis, you can define the ``_event_handlers`` property inside the fields of your JSON schema (same level as ``_db_settings``).

E.g. if our model ``User`` has a field ``username`` we might want to make sure that ``username`` is not a reserved name. If ``username`` is a reserved name, we want to raise an exception to interrupt the request.
E.g. if our model ``User`` has a field ``username``, we might want to make sure that ``username`` is not a reserved name. If ``username`` is a reserved name, we want to raise an exception to interrupt the request.

.. code-block:: python
Expand All @@ -120,7 +119,7 @@ E.g. if our model ``User`` has a field ``username`` we might want to make sure t
raise ValueError('Reserved username: {}'.format(username))
The following JSON schema registers ``before_set`` on the field ``User.username``. When connected this way, the ``check_username`` subscriber will only be executed if the request has the field ``username`` passed to it:
The following JSON schema registers ``before_set`` on the field ``User.username``. When connected this way, the ``check_username`` handler will only be executed if the request has the field ``username`` passed to it:

.. code-block:: json
Expand Down
35 changes: 0 additions & 35 deletions docs/source/fields.rst
Original file line number Diff line number Diff line change
Expand Up @@ -101,41 +101,6 @@ You can set a minimum and/or maximum length of your field by setting the ``min_l
}
}
.. _field-processors:

Field Processors
----------------

Field processors are custom functions that are called upon validation of a field. You can write those functions inside your ``__init__.py``. You can reference processors in the ``before_validation`` and ``after_validation`` properties under ``_db_settings``. The `before_` and `after_` prefixes refer to when those processors are executed, either before or after database validation. You can define more than one processor in each of those arguments in a comma-separated list. If multiple processors are listed, they are executed in the order in which they are listed.

.. code-block:: json
"password": {
(...)
"_db_settings": {
(...)
"before_validation": ["validate_password_format", "crypt"],
"after_validation": ["email_password_changed"]
}
}
For 'relationship' fields, you can also add processors to your backref field by adding the ``backref_`` prefix.

.. code-block:: json
"parents": {
(...)
"_db_settings": {
"type": "relationship",
"document": "Parent",
"backref_name": "child",
"backref_before_validation": ["verify_filiation"],
"backref_after_validation": ["copy_parents_lastname"]
}
}
To learn more about writing custom processors, see the :ref:`Writing Processors documentation<writing-processors>`.

Default Value
-------------
Expand Down
2 changes: 1 addition & 1 deletion docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Table of Contents
raml
schemas
fields
crud_events
event_handlers
relationships
changelog

Expand Down
2 changes: 1 addition & 1 deletion docs/source/raml.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ You can read the full RAML specs `here <http://raml.org/spec.html>`_.
Authentication
--------------

In order to enable authentication, add the ``auth`` paramer to your .ini file:
In order to enable authentication, add the ``auth`` parameter to your .ini file:

.. code-block:: ini
Expand Down
8 changes: 4 additions & 4 deletions docs/source/relationships.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ file and schemas.
Example code is the very minimum needed to explain the subject. We will be referring to the examples along all the tutorial.


relationship
------------
Field "type": "relationship"
----------------------------

Must be defined on the *One* side of OneToOne or OneToMany
relationship (``User`` in our example). Relationships are created as
Expand Down Expand Up @@ -50,8 +50,8 @@ Example of using ``relationship`` field (defined on ``User`` model in our exampl
String. Name of *back reference* field. This field will be auto-generated on model we set up relationship to and will hold the instance of model we are defining. In our example, field ``Story.owner`` will be generated and it will hold instance of ``User`` model to which story instance belongs. **Use this field to change relationships between objects.**


foreign_key
-----------
Field "type": "foreign_key"
---------------------------

This represents a Foreign Key constraint in SQL and is only required
when using ``nefertari_sqla`` engine. It is used in conjunction with
Expand Down

0 comments on commit 94e95e3

Please sign in to comment.