Actions

Backend Ajax protocol: Difference between revisions

From LimeSurvey Manual

Line 73: Line 73:
[[File:jsonoutput.png]]
[[File:jsonoutput.png]]


[https://www.draw.io/?state=%7B%22folderId%22:%220AGzfh04EPg7FUk9PVA%22,%22action%22:%22create%22,%22userId%22:%22114389134225826985498%22%7D#G0B2zfh04EPg7FU3BTek83YjlWTjQ Source.]
[https://drive.google.com/file/d/0B2zfh04EPg7FU3BTek83YjlWTjQ/view?usp=sharing Source.]


= Implementation =
= Implementation =

Revision as of 19:44, 1 October 2016

Discussion

There should be a standard JSON protocol between the LS backend and Ajax calls to check for errors, permissions and if the user still is logged in. A suggestion would be to wrap $.ajax in a function that checks this for you, like LS.ajax.

All server Ajax calls must return a JSON in the following format:

{
  type: int,
  result: mixed,
  error: {code: int, message: string},
  loggedIn: boolean,
  hasPermission: boolean,
}

Of course there needs to be server side support for this protocol, too, with helper functions to output correct JSON code, e.g. Ajax::outputResult or Ajax::outputError($code, $message).

Preferably, the function should be able to show an error if server throws 500.

Jonas argue against Backbone giving too much freedom which creates a mess further down the road. He recommends React as an alternative.

Problemet med Backbone är att det inte är speciellt opininerat, man kan med andra ord göra fel på massor med sätt. Oftast bygger folk sig i lite fel riktning i början och så löser man det med att överlagra lite på Backbone och det funkar bra ... Men efter ett par år så har man överlagrat och ändrat på rätt mycket och man kan inte längre förlita sig på dokumentationen eftersom det du har inte är samma som basinstallationen och man kan inte längre uppdatera Backbone heller eftersom det är för mycket jobb och man har en massa konstiga specialfall i koden eftersom man inte visste att när man gjorde enkel fix A för ett år sedan så hade man sönder något som man inte använde då men som man behövde senare etc etc etc.

Message types

Type Fields Description
notloggedin - User is not logged in; the login form should appear in a modal and then continue with the action
nopermission - No permission
success success : string Show success message
error error : string Show error message
custom result : mixed Custom action, meaning a supplied Javascript function will take care of the response from the server, e.g. feeding HTML to a modal body. BUT: Maybe we could have a message type "modal" which sends modal title, body and footer?

Backbone

Since Javascript library Backbone might be used in the future, it would be nice to know how they handle stuff like this.

Some questions:

  • Would we need to duplicate the model code in both backend and frontend? Yes, we would need to code validation in both Backbone model and Yii model. Or, we don't use the module system at all from Backbone, and just send submit data to server (serialized forms).
  • How much of the CRUD will happen on client? All of it. REST is used to sync client to server.
  • How much would backbone replace Yii and things generated with Gii?
  • Would all views be put on the client? I'd prefer if we didn't split views between server and client. Here using Mustache would be a clear advantage, since it easily can be used from both Yii and Backbone. Or we can configure Twig to look like Underscore templates. Olle (talk) 20:43, 28 September 2016 (CEST)
  • LS will probably never be a single-page application, which means Backbone will be used on a per-module or per-page basis, to make Ajax operations more smooth.

Template engines

Underscore

Example:

<script id='my-template' type='text/template'>
  <strong><%= name %></strong> - <%= age %>
</script>

Learning material

Class diagrams

Source.

Implementation

A first prototype of the backend classes can be seen here. Instead of a helper, this class can actually be put into LSYiiController, making it available to all controllers in LS.

Example:

public function indexAction()
{
  $this->ajax->outputSucces(gT('Success!'));
}