leontoeides / google_maps

An unofficial Google Maps Platform client library for the Rust programming language.
https://crates.io/crates/google_maps
Apache License 2.0
58 stars 25 forks source link

(full) Web Assembly support #9

Closed E-gy closed 3 years ago

E-gy commented 3 years ago

Currently, enabling enable-reqwest feature enables reqwest/default-tls, which for obvious reasons does not compile on wasm32.

Reqwest works on WASM using JS' fetch API, so usage of a transport features (TLS, gzip, brotli) is not necessary.

Sadly, by disabling the enable-reqwest feature, the get (and execute) extensions to Requests are disabled, altough they would work just fine. This leaves Web Assembly half-supported - the requests can be built and validated, but not executed (they can still be executed manually though).

TLDR: Making enable-reqwest feature not require incompatible extensions on wasm32 target should be enough to enable full Web Assembly support.

PS: One could argue that it is not a good idea to give access to API keys in a client application in the first place ¯\_(ツ)_/¯

leontoeides commented 3 years ago

Never thought of this situation! Later today I will see about issuing an update where:

There is also another option:

use google_maps::prelude::*;

let google_maps_client = ClientSettings::new("YOUR_GOOGLE_API_KEY_HERE");

// Get query string from builder pattern:
let query_string = google_maps_client.time_zone(
     LatLng::try_from(dec!(50.090_903), dec!(14.400_512))?,
     Utc::now()
).query_string();

// Insert your favourite HTTP client here:
let json = reqwest::get(
    // query_string.0 = "https://maps.googleapis.com/maps/api/timezone/json?"
    query_string.0 + &query_string.1
).await?.text().await?;

// Parse JSON string into a TimeZoneResponse structure:
let time_zone: TimeZoneResponse = json.parse()?;

// Dump entire response:
println!("{:#?}", time_zone);

Putting the API key in the client is not necessarily bad practice! Just restrict the key to the necessary API's, and make sure you put quotas you're comfortable with - so you don't get a huge bill. https://console.cloud.google.com/google/maps-apis/quotas

E-gy commented 3 years ago

It looks like this approach isn't the best after all.

See, the Google Maps API this is using seems to be designed for servers first. Trying to access it via fetch simply leads to CORS getting in the way (the servers don't include CORS headers, and getting opaque responses is useless).

The correct way to use Maps API client side, for now at least, is via Google Maps JavaScript API + Rust bindings via wasm_bindgen (which do not seem to exist as a crate at the moment). ... or write a server proxying the requests in Rust, and call that instead.

In light of Google's inherent limitations, i consider this issue as irrelevant to this crate. Sorry for bothering.

leontoeides commented 3 years ago

Just a quick note that I've implemented this change. Sounds like Google Maps Platform API's will have to include CORS headers if they want WASM clients to connect.