Reactive Websites (Callers and Listeners)
Introduction
By default, a fast framework based website renders the complete html-output of a web-page server side and sends the full page back to the browser.
Often we want to control user interaction more granular, e.g. we want UI elements to trigger some functionality other than navigating the website, and we just want to update fragments of the page.
fast framework provides tools to set up such "internal APIs". They are flexible enough to cover common use cases with very little code, but is extendable to handle more complex cases.
Its use is best explained by an example:
Example: counter
To demonstrate the concept we will implement a simple counter and its API in 3 different ways. Based on the specific needs of your project you can define your API you can choose which way is the appropriate for the specific implementation.
We will cover 3 approaches for our counter API:
front-end only API: html <-> js <-> html
back-end only API: html <-> php <-> html
full stack API: html <-> js <-> php <-> js <-> html
It is good practice to create separated APIs per project, based on their specific use case and name them according to that scope.
In our "counter" example the components that define the api will be called:
html: data-counter-api
js: counterCaller.js
php: counterListener.php\
Option 1. front-end only API
In a front-end only API only template and front-end interact. No need to define a backend.
To set up the front-end only API we need two files:
File presenters/counter.html
File js/counterCaller.js
The ffCaller.add() function instantiates the caller API and binds clicks on the element with data-counter-api attribute to its actions-functions of the same name.
The logic could then be implemented like this:
File js/counterCaller.js
Since ff does not provide front-end state management out-of-the-box, the counter will not persist a page reload.
Option 2. back-end only API
Connecting front-end directly with back-end allows us to keep the application logic and state management in the back-end.
To set up a back-end only API, we remove the logic from our front-end caller and add it to the listener in the back-end:
First, we add a method hook to the template presenter/counter.html.
We then create the presenter class file presenter/counter.php to access the count state and inject it in the template.
For this example we're using a very simple session-based storage.
Next, we remove all the logic from the caller js/counterCaller.js.
We keep only a skeleton, that serves to instantiate the API.
The counter-logic and state management happens in the file classes/counterListener.php.
A Listener needs to extend the ffListener class.
As the ffListener class opens the door to the back-end, it brings some default security measures.
For our counter example we deactivate those by changing some default properties. This will make the listener respond to any request.
The logic could then be implemented like this:
File classes/counterListener.php
In a back-end only API, each API call triggers a reload of the re-rendered presenter.
Option 3. full stack API
If you need more control (i.e. combine front-end and back-end logic) you can extend the API's functionality.
Starting from Option 2 we can intercept the back-end-call and work with the data by adding the action property:
File js/counterCaller.js
built-in functions:
Form submission
api attributes can also be attached to form elements. In this case the api will use formData to assemble the api's option property