rustwasm / team

A point of coordination for all things Rust and WebAssembly
MIT License
1.44k stars 60 forks source link

Prototype a combined server and client framework #68

Open fitzgen opened 6 years ago

fitzgen commented 6 years ago

I've been going over rust+wasm discussions across the internet and one idea that has popped up a few times is a framework that straddles across the server and the client, providing tight and smooth integration.

What exactly does this mean? Built on top of tokio and yew? Hyper and stdweb? Maybe even blurring the lines and transparently running futures on etiher the server or client? You figure it out for us! :)

One interesting aspect is that this pretty much sidesteps the whole packaging and bundler integration story, since you'd have full control of the end-to-end pipeline.

Would be awesome to see some experiments in this area.

Diggsey commented 6 years ago

I would like to see a middleware/framework which does server-side rendering of pages. I've never seen a "perfect" solution to the server-side rendering problem, and up until now only the nodejs platform has really even offered it as a possibility at all.

The "holy grail" would have these properties:

1) The raw content from the server consists of fully rendered static HTML 2) The initial HTML contains "normal" hyperlinks 3) Dynamic content is loaded with the initial value rather than just being a placeholder 4) The page works as completely as possible without javascript 5) If the javascript is loaded, it doesn't need to fully re-render the page after load 6) If the javascript is loaded, "normal" hyperlinks become client-side routing hooks 7) Correct caching headers are returned, so that rendered pages can be cached across requests without compromising security

The way I see this working is with a single "application state" object which is JSON serializable and includes the entire virtual DOM. When a request comes in, the request handler initialises the state, and the initial render performed. Next, the state is serialised onto the end of the HTML. When the javascript is loaded, it deserialises this blob of application state, and continues rendering from there, and this should be completely transparent from the actual components being rendered, so that they don't even realise they were sent over the wire. Caching headers would be sent based on the "initial state" that the request handler returned.

NeverGivinUp commented 6 years ago

There are powerful Javascript-frameworks like Angular or Ember, which form rich ecosystems of display components and other kind of add-ins. It will take many years for something equivalent to develop in Rust.

Clients need to do check consistency themselves to avoid making the user wait for the server roundtrip. Servers cannot rely on the consistency of the data they receive. They need to check again, to make certain the data is not compromised. Display and user interaction however need not be integrated with or even aware of the existence of the server. They are solely client side problems.

The pragmatic approach to client/server integration thus seems writing single page applications (SPA) in existing frameworks but writing the model and its consistency checks only once in rust. Some parts of code would be marked to be compiled twice. Once for the server and once for the client, not only conforming to WASM but also to the target javascript framework. This marked code would need to have very few dependencies.

Pauan commented 6 years ago

@fitzgen Maybe even blurring the lines and transparently running futures on etiher the server or client?

Just FYI, thanks to help from @CryZe and @Diggsey (and myself), stdweb now has excellent support for both JavaScript Promises and Rust Futures (and of course converting JavaScript Promises into Rust Futures).

So if anybody wants smooth integration between the client and server, this should help.


As far as client-side DOM rendering libraries go, I am personally strongly in favor of virtual DOM based on observables (not DOM diffing!). I have used this technique to great success in JavaScript, and I think it will work very well in Rust too.

The major benefits of observables are:

I've been planning to make a prototype demonstrating the idea, but I've gotten sidetracked with a bunch of pull requests on stdweb.

sendilkumarn commented 6 years ago

@Pauan this looks really promising. The arguments related to vdom (kinda feels like react) and I always wanted to try this out with rust / wasm in general. exicting times ahead.

Would be very interesting to see / help with that...

davidhewitt commented 6 years ago

Hello! @Pauan I'm also hoping to experiment with observable/computed based web framework for Rust. I very much like Vue.js and intend to use many of it's ideas as prior art. Perhaps we can collaborate?

Pauan commented 6 years ago

I have started work on implementing zero-cost virtual DOM and zero-cost signals / observables for Rust.

It's not ready to publish yet, but you can find the code in the rust-dominator repo.

It works correctly, but it doesn't compile right now (it requires stdweb version 0.4.0, which isn't released yet).

Let's discuss any questions / features / bugs on that repo.

davidhewitt commented 6 years ago

Oh nice, rust-dominator is very cool! I really like what you've done with the signal / state.

For the moment I might keep typing on my own castle, I am aiming for something which has a mix of both yew and dominator about it: vdom diffing with a splash of observables / reactivity mixed in to simplify updates. If my ideas turn out to be trash I'll come out to lend a hand as all these projects mature. Exciting times ahead indeed 😃