.. _serverside_callbacks: Serverside Callbacks ==================== Since version **0.9.8**, Toscawidgets allows the registration of serverside callbacks. These are a powerful feature, intended to aid the development of self-contained widgets which need support-methods on the server-side, such as AJAX-driven search pages and the like. As usual, an introductionary example explains things better that thousand words: .. literalinclude:: examples/serverside.py :linenos: Most of the code is just to create a testing-harness - you don't need to worry about it. There are three new concepts though, and these need to be addressed: * declaring callbacks with ``serverside_callback``. * getting the url a callback is registered under. * protecting the callbacks with ``callback_authorization``. Also, please note that the widget needs to be subclassed from :class:`~tw.core.server.ServerSideCallbackMixin`. Declaring a Callback -------------------- A callback is a normal instance-method which is decorated with the decorator ``serverside_callback``. It will always only have one argument, a :class:`webob.Request`-instance which can be used to get access to all parameters and other attributes of the request. It must return a :class:`webob.Response`-instance to render it's output. Of course the callback can invoke all methods a widget has by itself. Getting callback urls --------------------- The above toy-example shows how to reach a widget's callback. To do so, one needs to know where the callback is mapped to. In a real-world example, this would then be passed to javascript-code, or rendered into links in the widget-template. The url in our example is :: /toscawidgets/resources/__callback__/serverside_widget/test_callback Pretty straightforward - so why not hardcode them? Because that would fail if the widget is registered in an application that is not mounted as root! So, whenever you need a callback-url, use :method:`tw.core.server.ServerSideCallbackMixin.url_for_callback`. Callback security ----------------- An important topic is how to prevent unauthorized access to serverside-callbacks. To govern this, there are two hooks: - a global one that is passed on middleware-creation. It defaults to denying all access. - a per-widget-one that is a parameter to the widget called ``callback_authorization``. In both cases the authorization handler is a function that has the following signature:: (instancemethodf, webob.Request) -> webob.Response So it takes the callback in question and the current request, and must return a response which is used to convey the results of checking the authorization via it's status: - **200** if it's ok for the current request to call the callback. - everything else is reported back as result of the request. As you can see in the example, the authorization is conceived as subclassed method. This works as well as passing a parameter to the constructor, it's up to you what you prefer. And there are two built-in checkers, ``always_allow`` and ``always_deny`` that serve as model how to implement authorization checkers.