aws-sdk-rust icon indicating copy to clipboard operation
aws-sdk-rust copied to clipboard

WebAssembly support

Open alexkirsz opened this issue 3 years ago • 22 comments

Are you interested in using the Rust SDK in Web Assembly? Please comment on this issue with more details about your potential use case!

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or "me too" comments, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue, please leave a comment

Tell us about your request

The AWS SDK should be usable from a Rust WebAssembly program.

Tell us about the problem you're trying to solve. What are you trying to do, and why is it hard?

I'm building a web application with core logic written in Rust and compiled to Wasm, and I'd like to connect with AWS APIs such as S3 from my Rust program without having to drop down to JavaScript too often (if ever).

Are you currently working around this issue?

Since I'm targeting the web and there's already an extensive AWS SDK for JavaScript, I can delegate all the AWS bits to JavaScript.

alexkirsz avatar May 07 '21 21:05 alexkirsz

Having S3, DynamoDB, and RDS clients available directly in WASM could allow many classes of web application to avoid having a dynamic backend entirely.

tidux avatar May 26 '21 22:05 tidux

We're building a GraphQL API in Rust that we deploy using server-side WebAssembly. Having native support for WASM in the AWS Rust SDK would be great.

fbjork avatar Nov 19 '21 15:11 fbjork

Are you interested in using the Rust SDK in Web Assembly? Please comment on this issue with more details about your potential use case!

rcoh avatar Mar 23 '22 17:03 rcoh

We are working on a sports league app and are interested in using communication and streaming services from AWS for a WebAssembly client.

paulsika avatar May 19 '22 14:05 paulsika

I am trying write a SPA backed by S3, similar to one that I have written in JavaScript using Rust and WASM.

phil-kahrl avatar Jul 03 '22 16:07 phil-kahrl

Wouldn't need the full AWS SDK, but being able to generate pre-signed S3 URLs for PUT/GET would probably cover a lot of my use cases (read/write key values from a private bucket for a WASM based edge function).

geekbeast avatar Aug 07 '22 19:08 geekbeast

We are interested in developing a set of basic operations using the AWS SDK (specially CloudFormation and Service Catalog). Those will be imported by the teams that use different programming languages. Therefore we believe that Webassembly is a perfect fit for that situation. Now that we have the Webassembly Component Model, it should be possible to use a tool such as wit-bindgen combined with Smithy itself to generate the bidings for the languages that we want to support. Additionally, the work that has been happening from the WASI sockets front in the context of Tokio should allow basic networking capabilities to the generated clients.

eduardomourar avatar Aug 27 '22 22:08 eduardomourar

Hello,

We are working with a wasm-based plugin system (with a couple custom runtime hosts and bindings) where we would like to use the SDK to handle with connections to AWS. To be honest our use case is quite close to being fulfilled thanks to the ability to define our own connector_fn that uses our bindings to run the requests. The only issue we have currently is that building for wasm32-unknown-unknown always try to link to wasm-bindgen symbols even if we don't use it, nor want it; that prevents loading any module that uses the SDK in an environment where we do not use wasm-bindgen.

The root cause seems to be this ring issue, which is unconditionally compiled in aws-config crate. I know one solution is to wait for ring to have enough time to release 0.17, and then to have the SDK update to use this version, but it would also be nice to avoid the issue by trying to put as many dependencies behind features as possible I guess: to go back on our use-case, we would have avoided the problem since we do not plan on using SSO credentials in our wasm program.

Cheers, Gerry

gagbo avatar Dec 01 '22 09:12 gagbo

I'm also interested in using s3 when targeting wasm32-unknown-unknown. What is the current status?

Thanks!

benjaminrwilson avatar Apr 15 '23 00:04 benjaminrwilson

We have a library that makes heavy use of the AWS SDK and we want to package/distribute it for multiple languages. WASM running in something like the Wasmer runtimes seems like our best bet for distributing it in a language agnostic way. We don't really have any need for browser support since we generally expect the library to be running in Lambdas or ECS, so wasm32-wasi working is probably enough for us.

landonxjames avatar Jul 10 '23 03:07 landonxjames

I'm also interested in this. Anyone had any success interacting with RDS through a Wasm backend?

omarabid avatar Jul 15 '23 07:07 omarabid

+1 I would really like to see WebAssembly support, especially the ability to move backend code into the web frontend. WASM can improve performance and security, and it can make it easier to develop and deploy web applications. I urge you to consider adding WASM support to your SDK.

cosinusalpha avatar Jul 17 '23 06:07 cosinusalpha

Please!

simbleau avatar Jul 21 '23 00:07 simbleau

In my experience, it is actually quite difficult to convert and existing library that does not support wasm targets to start supporting wasm targets. Dependencies that rely on the system (e.g. system clock), anything that requires multiple threads, dependencies written in C, C++ or Assembly will generally not be able to compile to to wasm targets. So converting the existing AWS SDK to support wasm is likely a very large ask.

The other option we have is to use the AWS Rest APIs directly for the particular AWS service that one is interested in. It is relatively straightforward to construct arbitrary Http requests using wasm-bindgen and web-sys. Deserialization of responses is also straightforward using a serde for XML.

The main difficulty with using the REST APIs is construction the [AWS V4 signature:] (https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html) for use in the Authorization header.

There is at least one existing crate for V4 signatures https://crates.io/crates/aws-sign-v4, however it does not compile to a wasm target. In particular, ring, chrono, and url, do not compile to wasm.

It does seem that the existing code could be forked with wasm compatible dependencies:

ring could be replaced by Rust Crypto chrono could be replaced by js-sys::Date url could be replaced by custom string parsing and encoding.

Such a project would then provide a path for those of us who want to call AWS APIs from the browser to have a path forward, with a reasonable amount of custom code required.

phil-kahrl avatar Jul 21 '23 16:07 phil-kahrl

If you use js-sys::Date though, you would not be able to target wasm32-unknown-unknown right? Since it would always try to link to wasm-bindgen symblols?

For the record, I ended up redoing a client from mostly scratch, as the types in the SDK arent public (so I can't just import the SDK to have serde::Deserialize types), and I didn't want to enable SSO in my use case (so ring is never necessary).

It is a little messy, but you can find everything in that repo, with the custom signing code and a lot of manual "read the docs and rewrite structs" code

gagbo avatar Jul 21 '23 17:07 gagbo

I think we've been bad maintainers by not keeping everyone in the loop here, so here's an update to try and rectify that.

In the last year, people have made significant contributions (shout out to @eduardomourar! ❤️) and we've also done some refactors that bring us closer to realizing WASM support. The SDK now compiles against wasm-unknown-unknown, and there is also a WebAssembly example. As others have called out in this thread, certain standard library features don't exist in WASM, and some C dependencies won't compile to it. These all need to be replaced with configurable components. As a step towards that, our next release will include a configurable TimeSource so that the calls to SystemTime::now() can be eliminated.

We're a small team, and we're primarily focused on getting this SDK to 1.0 right now, so this feature hasn't been getting the love it deserves. However, it is on our minds. We opportunistically chip away at it as time permits, and we try not to write any code that will prohibit it in the future.

This is something we would really like to support, and contributions in smithy-rs, the SDK's code generator, are welcome if someone wants to help out. I've created the aws-sdk-rust/next branch with the latest (unreleased) version of the SDK that has a configurable TimeSource if people want to play around with it and see what's still broken.

Also, regarding the lack of serde::Deserialize on our types, @thomas-k-cameron has been doing a lot of great work in smithy-rs to add that support behind a feature gate. This isn't quite ready to play around with, but we're getting there.

Thanks for all the feedback, everyone!

jdisanti avatar Jul 21 '23 17:07 jdisanti

I've gotten it working in https://github.com/awslabs/smithy-rs/pull/2868! Very hopeful that this will be included in our next release.

rcoh avatar Jul 25 '23 20:07 rcoh

The August 3rd release should fix most of the major issues with getting the SDK to work in WebAssembly. It should compile against wasm32-wasi and wasm32-unknown-unknown, and as far as I know, everything that needs to be swapped out in a WASM environment should be configurable now. Please let us know how it works for you!

jdisanti avatar Aug 03 '23 20:08 jdisanti

Update: I have read the example and fixed it. It occurs if the time_source is not be set.

I'm encountering an issue while using bedrock_runtime SDK without default features and target on wasm:

use aws_config::{
    defaults, identity::IdentityCache, retry::RetryConfig, timeout::TimeoutConfig, BehaviorVersion,
};
use aws_sdk_bedrockruntime::{
    config::{Credentials, StalledStreamProtectionConfig},
    primitives::Blob,
    Client,
};

// ...

    let key = env.secret("AWS_ACCESS_KEY_ID").unwrap().to_string();
    let secret = env.secret("AWS_SECRET_ACCESS_KEY").unwrap().to_string();
    let cred = Credentials::new(key, secret, None, None, "default");
    let config = aws_config::defaults(BehaviorVersion::latest())
        .region("us-east-1")
        .credentials_provider(cred)
        .timeout_config(TimeoutConfig::disabled())
        .retry_config(RetryConfig::disabled())
        .stalled_stream_protection(StalledStreamProtectionConfig::disabled())
        .identity_cache(IdentityCache::no_cache())
        .load()
        .await;
    let client = Client::new(&config);

It panics with:

[ERROR] panicked at library/std/src/sys/pal/wasm/../unsupported/time.rs:31:9:

  time not implemented on this platform

yuchanns avatar Apr 10 '24 09:04 yuchanns

@yuchanns you can configure a custom time source with time_source(). For instance, in one case where I wanted the time to be static within the single use of the AWS config I've configured it like this:

let epoch = (js_sys::Date::now() / 1_000.0) as u64;
aws_config::defaults(aws_config::BehaviorVersion::v2023_11_09())
    …
    .time_source(aws_smithy_async::time::StaticTimeSource::from_secs(epoch))

But you can also provide a value of your own type implementing the aws_smithy_async::TimeSource.

jakubadamw avatar Apr 10 '24 10:04 jakubadamw

I've been trying to get this working, without a lot of luck. Is anybody successfully using this with wasip2? If so, perhaps we could have a "hello world" example using, e.g., cargo-component? :pray:

jeffparsons avatar Apr 15 '24 07:04 jeffparsons

@jeffparsons there is a WASI 0.2 compliant HTTP connector in the aws-smithy-wasm crate: https://docs.rs/aws-smithy-wasm/0.1.2/aws_smithy_wasm/wasi/index.html

I have used it successfully in both Wasmtime and in Node (with jco's WASI bindings) with cargo-component built components. It looks like you're in the BytecodeAlliance Zulip, so would be happy to chat more about it there to avoid pinging everyone on this issue!

landonxjames avatar Apr 15 '24 17:04 landonxjames