Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Any solution/proposal to work with a rest backend? #2

Open
stephanbuys opened this issue Feb 15, 2017 · 1 comment
Open

Any solution/proposal to work with a rest backend? #2

stephanbuys opened this issue Feb 15, 2017 · 1 comment

Comments

@stephanbuys
Copy link

Hi, I have a small demo due next Friday and I was wondering if I could try quasar? Only catch is that I need to get data from a server (and submit to it) which will probably be done with rocket.rs.

Any pointers would be appreciated, and if I can help I'd be happy to.

@anowell
Copy link
Owner

anowell commented Feb 15, 2017

I believe the right solution is gonna be to get a library like reqwest to target emscripten and compile down to some web API. I'd like to see it target the Fetch API but there is also a more stable wget API. I know the reqwest author has expressed being open to something like this. Depending on how that works, there might be some integration work to make sure you can access quasar state when the HTTP request completes. But I can't imagine that happening too quickly.


Coming up with a short-term solution probably involves forking my fork of webplatform to add methods like http_get and http_post to Document. This [untested] snippet should make a synchronous XMLHttpRequest (false for the async arg to open() - doing this asynchronously requires a bit more plumbing - similar to how the on methods accept callback closures).

    // this is a bit lazy: it ignores response code and headers
    // and blindly assume the response is a string, but it's a start
    pub fn http_get(&self, url: &str) -> String {
        let response = js! { (url) b"\
            var xmlHttp = new XMLHttpRequest();\
            xmlHttp.open("GET", url, false);\
            xmlHttp.send(null);\
            return allocate(intArrayFromString(xmlHttp.responseText), 'i8', ALLOC_STACK);\
        \0" };
        unsafe {
            str::from_utf8(CStr::from_ptr(response as *const libc::c_char).to_bytes()).unwrap().to_owned()
        }
}

Then you could add a more ergonomic wrapper function to Quasar. It'd probably need added to AppContext which is available in event handlers via evt.app. Given that it's synchronous, it'd probably be a bad idea to add it to QuasarApp since it would block app loading. It'd probably look something like this:

    // also a bit lazy: it assumes the response was JSON without ever checking content-type
    // and no real error handling :-(
    pub fn http_get<T, U>(&self, url: U) -> T where T: Deserialize, U: IntoUrl {
        let url_string = url.into_url().unwrap().serialize();
        let response_text = self.app.document.http_get(&url_string);
        serde_json::from_str(&response_text).unwrap()
    }

Then in theory an app could use it like this.

    app.query("#fetch-button").expect("missing #fetch-button")
        .on(Event::Click, |mut evt| {
            let things: Vec<Thing> = evt.app.http_get("http://example.com/things");
            evt.app.data_mut("things").map(|mut t| *t = things);
            // and now any views that were using `app.data("things")` would be rerendered
            // alternatively, i could have just updated the current component via `evt.binding.data_mut()`
        });

Then repeat for POST, PUT, etc.. Of course, none of that is tested, and you'd probably hit a few other snags in Quasar along the way, but it's probably possible to get something fairly basic, and it would provide more insights into where quasar is still pretty painful. That said, while I find it encouraging that you want to try and use quasar, the pragmatist in me thinks it unwise to gamble a deadline on quasar's current state... but I certainly won't stop you. ;-)

(and even for such short-term solutions, I'd accept PRs given that it's not clear when a better solution will be ready.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants