[CORD-2960] Adding documentation for convenience methods
Change-Id: Ia7bf2efd76cd79ca952f32ab004a1b621db04cdc
diff --git a/docs/dev/synchronizers.md b/docs/dev/synchronizers.md
index 100b5cd..e579bf7 100644
--- a/docs/dev/synchronizers.md
+++ b/docs/dev/synchronizers.md
@@ -21,6 +21,50 @@
This section is intended to be a reference for the commonly used APIs exposed
by the synchronizer framework.
+### Convenience Methods
+
+As part of the model definition is possible to extend the autogenerated gRPC APIs
+with custom methods, for example to facilitate access to some kind of data from the
+synchronizers.
+
+`convenience_methods` can be defined in a folder (`convenience`) that needs to be a child of the `models_dir`
+as per your configuration.
+
+> For example if your configuration contains:
+> ```yaml
+> models_dir: "/opt/xos/synchronizers/<synchronizer_name>/models"
+> ```
+> then you `convenience methods` needs to be located in `/opt/xos/synchronizers/<synchronizer_name>/models/convenience`
+
+Assuming our model definition looks like:
+```proto
+message MyModel (XOSBase){
+ required string first_name = 1 [null = False, blank = False];
+ required string last_name = 2 [null = False, blank = False];
+}
+```
+here is an example of a basic convenience methods that will expose a `full_name` property over the APIs used by the synchronizers:
+
+```python
+from xosapi.orm import ORMWrapper, register_convenience_wrapper
+
+from xosconfig import Config
+from multistructlog import create_logger
+
+log = create_logger(Config().get('logging'))
+
+class ORMWrapperMyModel(ORMWrapper):
+
+ @property
+ def full_name(self):
+ return "%s %s" % (self.first_name, self.last_name)
+
+register_convenience_wrapper("MyModel", ORMWrapperMyModel)
+```
+
+> NOTE: The convenience methods will be loaded in all the synchronizer containers
+> so that they can be used in multiple places.
+
### Model Policies
Model Policies can be seen as `post-save` hooks and they are generally defined
@@ -149,7 +193,8 @@
o = MyModel()
# code to fetch information
# populate the model
- o.foo = 'bar'
+ o.first_name = "John"
+ o.last_name = "Doe"
o.no_sync = True # this is required to prevent the synchronizer to be invoked and start a loop
o.save()
```