Form Server-Side Processing

Last edit: Oct 26, 2022

This topic explains form server-side processing in platformOS when a user submits a form.

To understand this topic, you should be familiar with:

1. CSRF Token validation

The very first thing before every POST request is to verify the CSRF token. If it is not provided, the user's session won't be validated and will be discarded.


For AJAX calls make sure to provide the headers X-CSRF-Token: and X-Requested-With: XMLHttpRequest. If you use the form tag, then the authenticity_token is included automatically as a hidden input and no action is needed.

2. Find Form based on form_name or form_id parameter

The first step is to identify the Form to be used to process the user's request. In order to do it, the server checks for the parameter called form_name or form_id, which is automatically added to the page when the form is rendered using the form tag as described in FormTag. If the value is missing or invalid, 404 error is rendered, otherwise you can move on.

3. Check Authorization Policies

The next step is authorization using Authorization Policies. Those are processed in the order in which they were defined - from top to bottom. If the authorization fails, the server stops processing the form and handles authorization policy failure (usually redirect or rendering 403 error).

4. Resource Owner authorization

Once all authorization policies pass, the next check is authorization for the Resource Owner property. It checks if the currently logged in user has access to the resource with given id. If it fails, the server returns a 404 error.


Resource Owner is only relevant for update / delete. It does not matter for create, as there is no resource at that time.

5. Modifying user input with default_payload JSON

The next step is to extend/overwrite the user's input with default_payload. This is the place where Liquid is evaluated on the server side. The most useful variables used to build default_payload are context.params and form variables. If evaluated Liquid is not valid JSON, the server raises a 500 error and automatically creates relevant Log.

6. Validating user input

The result of merging user's input with default_payload is then run against validation rules defined for each field. If at least one validation fails, the server renders response based on the format. For HTML, the errors are added to the form variable inside the relevant field and the server renders Page based on the page_id parameter passed to the server. Additionally, the flash_alert is evaluated and set if provided in the configuration. It is then accessible using the context variable. For JSON, a JSON object is returned with a populated errors key. The status code is 200 in both scenarios.

7. Calculating changes

If validation passes, the changeset between existing state of the resource and user input is calculated, and accessible from now on via the changes variable.

8. Persisting changes

The new state of the resource is persisted in the database. In case of the rare scenario of an internal server error, the changes are rolled back and the server renders a 500 error.

9. Processing Callbacks

The next step is to process the callback synchronously.

10. Schedule processing AsyncCallbacks

The next step is to schedule processing async callbacks in the background.

11. Schedule sending notifications

The next step is to schedule all notifications (email, SMS, API calls) to be processed in the background.

12. Render response

If the format is set to HTML, the flash_notice property is evaluated and set, then redirect_to property is evaluated to determine where the user should be redirected. For a JSON request, the server renders 200 status and serializes the form to JSON a few basic properties (like id) to JSON.


It is possible to send a request via AJAX, but receive HTML response from the server. The trick is to explicitly set the format to HTML by appending to the REST endpoint .html, for example, /api/users.html. The server will render HTML if validation fails (so you could display errors) or will return a JSON including redirect URL upon success.


We are always happy to help with any questions you may have.

contact us