wasmedge-quickjs icon indicating copy to clipboard operation
wasmedge-quickjs copied to clipboard

Implementing Fetch

Open tpmccallum opened this issue 3 years ago • 2 comments

Client side interaction (fetch)

Ideally it will be great if a user is able to action the fetch functionality from their web browser. For example, the user clicks "Display Data" button and then the app goes and fetches data which it displays to the user's browser.

The best way I can think of to achieve this is to have another listening port in the server/index.js file, as shown below.

async function fetch_start() {
  print('listen 8003...');
  try {
    let s = new net.WasiTcpServer(8003);
    for (var i = 0; ; i++) {
      let cs = await s.accept();
      handle_fetch();
    }
  } catch (e) {
    print(e);
  }
}
fetch_start()

This allows port 8003 to listen for URLs to fetch, when asked by the client's browser.

The handle_fetch code in the server/index.js file which processes these requests could look like the following.

// Implement Fetch
import { fetch } from 'http';

async function handle_fetch() {
  try {
    console.log("Testing 123");
    let resp = new http.WasiResponse();
    let r = await fetch("http://httpbin.org/get?id=1")
    console.log("Testing 456");
    print('test_fetch\n', await r.text())
    console.log("Testing 789");
  } catch (e) {
    print(e)
  }
}

I have tested the above and we are able to listen and respond on port 8003 (albeit only in the terminal's output for now). Below is the output for your convenience.

Testing 123
Testing 456
test_fetch
 {
  "args": {
    "id": "1"
  }, 
  "headers": {
    "Accept": "*/*", 
    "Host": "httpbin.org", 
    "X-Amzn-Trace-Id": "Root=1-628878d7-0914ef354f63f7d655346fdc"
  }, 
  "origin": "27.33.80.26", 
  "url": "http://httpbin.org/get?id=1"
}
Testing 789

Questions

This leads to the following 2 part question. What would be your preferred design choice to:

  1. provide the URL from the browser's request to the listening server?
  2. identify the HTML element which is going to be updated with the new data from the fetch?

Ideas

  1. The URL could be passed from the browser's request to the server as a simple string.
  2. The client side could fill a specific HTML element by making the request and then updating the element's contents.

Both of these are really leaning towards client-side rendering though.

Perhaps another way, which leans more towards SSR is for the browser to perform a HTTP POST request (as per this WasmEdge demo). Specifically, the request could use multi-part form data which could pass in both the URL endpoint to fetch as well as the HTML element which is to be updated/altered. This way the server-side will have the ability to fetch and render the new data (leaving as little as possible to the client-side). The server/index.js file would just need the required functionality to process the multi-part form request.

Just FYI, the recent issue regarding the hydrate error has been resolved. We can now hydrate in the src/index.js file using the following syntax without error.

import { hydrateRoot } from 'react-dom/client';
const container = document.getElementById('root');
const root = hydrateRoot(container, <App />);

I am not sure why the new React 8.x.x function is called hydrateRoot and not just hydrate. I am assuming that hydrateRoot can hydrate any element in the HTML (as long as the handle is fetched by document.getElementById and then passed to the hydrateRoot function call).

Hope this all makes sense. I would love to hear any thoughts and ideas on this.

Kind regards Tim

tpmccallum avatar May 21 '22 06:05 tpmccallum

I think we should support the model of:

  • Server fetches data from external services or databases.
  • Server renders the DOM with the fetched data.
  • Hydrate and display the rendered DOM in the browser.

This type of apps will be tailor/made for WasmEdge SSR. And that is fine.

For pure CSR apps, the browser will make fetch() calls once the UI is rendered. The dynamic content is fetched and rendered in the browser not on the server. It is a less interesting use case for us.

juntao avatar May 21 '22 17:05 juntao

If fetch support existed. It would allow us to deploy it to cloudflare edge workers and circumvent all the imposed limits of their v8 instances

ScriptedAlchemy avatar Nov 07 '22 08:11 ScriptedAlchemy