guile-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Project Idea: Frontend controlled by the backend aka. how to avoid j


From: Amirouche
Subject: Re: Project Idea: Frontend controlled by the backend aka. how to avoid javascript hell
Date: Sun, 12 Feb 2017 19:57:38 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.7.0

Even if it use a virtual-dom library (ie. snabbdom), it's not like elm [1]
where there is a (complicated) architecture to get true widget composition
working (aka. fractal architecture).

That said, it's similar to ReactJS, in the sens that the backend always
render the whole page and asks the javascript runtime to efficiently update
the old DOM with the new one.

Like explained below, DOM events are transformed to JSON and sent to the
backend via websocket.

The whole thing feels much like desktop development except that the view
(in this case the DOM) is not mutated explicitly.

Basically, a simple counter application can be mocked with the following
code:

```scheme
(define (callback ctx)
   (assoc-set ctx 'counter (1+ (assoc-ref ctx 'counter)))

(define (handler ctx)
  `(button (@ (on-click ,callback)) ,(assoc-ref ctx 'counter)))

(nuweb-serve handler)
```

(To keep thing simple, the above callback is *expected* to return
the new state. You can hook into the system one layer below where
the callback just get CTX and where it's up the callback to send
something to the client if it needs to do so)

What about MVC? Well, nuweb is the "view" part, you are free to
organize your code as you wish.

[1] If you are not familiar with elm/reactjs/redux have a look at
    scheme forward https://forward.frama.io/website/

Le 12/02/2017 à 16:26, Amirouche a écrit :

# guile-nuweb
## Kesako nuweb?
nuweb is guile web framework where the frontend can be controlled by
the backend making it possible to write single page application
lowering the need to write javascript.
This is inspired from Nevow a Python web framework powered by twisted.
## How does it work?
When the client request a page from the server, it's served always the
same minimal page which embeds a javascript runtime. The javascript
runtime kicks in by establishing a websocket link with the server and
sending a `init` message which request the backend the content of the
page [1].
The `init` message comes with the url path, cookies and probably other
stuff.
When the `init` message arrives over the websocket link backend side,
it has the responsibility to send a `update-html` message that is a
json representation of the HTML that must be rendered. The HTML is
described with a superset of the SXML DSL where node can take `on-foo`
attributes associated with a lambda. The backend has the
responsibility to do a bit of bookkeeping to be able to forward `event`
messages to the correct callbacks. SXML nodes can also have a `style`
attribute associated with lambda which has the responsibility to
return the css for that node.
The frontend side, the javascript runtime has the following
responsibilities after the initial `init` message was sent:
- Process messages received from the backend which are mainly
   `update-html` messages but could also be `set-cookie` messages or
   other stuff (not specifed yet).
- When a `update-html` message arrives, it must translate the HTML
   described in the JSON into the proper snabbdom [2] calls. In
   particular, it must register callback to DOM events, serialize them
   and send them over the websocket link so that the backend specified
   callacks can be executed
That's basically all of it.
There is a special `on-submit` event, that can registered backend side
in the SXML that instruct the frontend to retrieve all the content of
the current form via something like jQuery.serializeArray.
Also, backend side there is a state associated with the client that
allows to push `update-html` messages.
[1] This could be improved. When the client request a page the backend
     returns both the content of the page and the javascript
     runtime. Similarly the javascript runtime will kick in and
     establish the websocket link and send the `init` message.
[2] https://github.com/snabbdom/snabbdom/
## Known Limitations
- See note [1], to help with SEO.
- Race conditions can happen, e.g. the frontend can send several
   `event` messages before the backend had the time to process the
   first of this event. That's basically why `on-submit` event
   exists. In particular, it's not a good idea to do *inline form
   validation* using `on-change` events.  This could be handled in
   javascript or better in the javascript runtime using a special node
   attribute.
## Where do we go from here?
There is pieces of here [3] and there [4][5] that could help build such
a framework in GNU Guile.
[3] https://git.dthompson.us/guile-websocket.git
[4] http://git.savannah.gnu.org/cgit/8sync.git
[5] https://github.com/wingo/fibers/
If you are interested by such a project don't hesitate to respond
to this mail.
Best regards,
amz3




reply via email to

[Prev in Thread] Current Thread [Next in Thread]