- Notifications
You must be signed in to change notification settings - Fork4
(Wannabe-awesome) list of methods to make outbound HTTP(S) requests from within WebAssembly in many languages
License
vasilev/HTTP-request-from-inside-WASM
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
(Wannabe-awesome) list of approaches (recipes, frameworks, http client libraries, etc) to send outbound HTTP(S) requests from inside WebAssembly.
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
L :aliased Listener;xhr : Web.XHR.Requests.XML_Http_Request;overridingprocedureHandle_Event (Self :inout Listener; Event :inout Web.DOM.Events.Event'Class)isusetype Web.XHR.Requests.State;beginif xhr.Get_Ready_State = Web.XHR.Requests.DONEthen WASM.Console.Log (xhr.Get_Response_Text);endif;endHandle_Event;procedureInitialize_Exampleisbegin xhr := Web.XHR.Requests.Constructors.New_XML_Http_Request; xhr.Open ("GET","https://httpbin.org/anything"); xhr.Send (""); xhr.Add_Event_Listener ("readystatechange", L'Access);endInitialize_Example; | Browser | Manual JS |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
import{fetch}from"as-fetch/assembly";export{responseHandler}from"as-fetch/assembly";fetch("https://httpbin.org/anything",{method:"GET",mode:"no-cors",headers:[],body:null,}).then((resp)=>{consttext=resp.text();}); | Browser, Node.js, and Deno | JS |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
DIM resAS STRING' Custom functionres= HTTPGET("https://httpbin.org/anything")PRINT res | Type | Browser | ||||
REM Custom functionres$= HTTPGET ("https://httpbin.org/anything")PRINT res$ | UsesGolang's |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
# custom functionprint(httpget('https://httpbin.org/anything')) | Browser | JS |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
@usingSystem.Net.Http.Json@inject HttpClient HttpClient@code{vardata=awaitHttpClient.GetFromJsonAsync<JsonElement>("https://httpbin.org/anything");} | Demoby JasonWatmoreDemo source | Browser, alsonative server-side | ||||
Silverlight / WPF revived in WASM form | usingSystem;usingSystem.Net.Http;HttpClientclient=newHttpClient();stringuri="https://httpbin.org/anything";stringresponseText=awaitclient.GetStringAsync(uri);Console.WriteLine("text: "+responseText); | Browser |
| |||
usingSystem;usingRestSharp;varclient=newRestClient();varreq=newRestRequest("http://httpbin.org/anything");varres=awaitclient.ExecuteGetAsync(req);Console.WriteLine("text: "+res.Content); | ||||||
Standard library | usingSystem;usingSystem.Net.Http;HttpClientclient=newHttpClient();stringuri="https://httpbin.org/anything";stringresponseText=awaitclient.GetStringAsync(uri);Console.WriteLine("body: "+responseText); | JS | ||||
usingSystem;usingSystem.Net.Http;HttpClientclient=newHttpClient();stringuri="https://httpbin.org/anything";stringtxt=awaitclient.GetStringAsync(uri);Console.WriteLine("text: "+txt); | Browser | Using.NET's |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
#include<emscripten/fetch.h>voidrequestOnSuccess(emscripten_fetch_t*fetch){chardat[fetch->numBytes+1];memcpy(dat,fetch->data,fetch->numBytes);dat[fetch->numBytes]='\0';printf("data: %s \n",dat);emscripten_fetch_close(fetch);}emscripten_fetch_attr_tattr;emscripten_fetch_attr_init(&attr);strcpy(attr.requestMethod,"GET");attr.attributes=EMSCRIPTEN_FETCH_LOAD_TO_MEMORY;attr.onsuccess=requestOnSuccess;emscripten_fetch(&attr,"https://httpbin.org/anything"); | Browser | JS | ||||
#include<xxhr/xxhr.hpp>usingnamespacexxhr;GET("https://httpbin.org/anything"s, on_response = [](auto res) { std::cout << res.text; }); |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
require"js"classXMLHttpRequest <JS::Reference @[JS::Method]defself.new :self<<-js return new XMLHttpRequest(); jsend js_getter responseText :String js_method send js_method open(method :String, url :String, async :Int32)endreq=XMLHttpRequest.newreq.open("GET","https://httpbin.org/anything",0)req.sendJS.console.log req.response_text | Browser, Node.js, and Deno | Manual JS |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
import'package:dio/dio.dart';final dio=Dio();Response response=await dio.get('https://httpbin.org/anything');print(response); | Browser with Wasm-GC support enabled1 | JS | ||||
import'package:fetch_api/fetch_api.dart';final resp=awaitfetch('https://httpbin.org/anything');final txt=await resp.text();print('${txt}'); | JS | |||||
import'package:fetch_client/fetch_client.dart';final client=FetchClient( mode:RequestMode.cors);final uri=Uri.parse('https://httpbin.org/anything');final resp=await client.get(uri);print('${resp.body}');client.close(); | ||||||
import'package:http/http.dart'as http;final resp=await http.get(Uri.parse('https://httpbin.org/anything'));print('${resp.body}'); | Browser with Wasm-GC support enabled1 | JS | ||||
import'package:requests/requests.dart';final resp=awaitRequests.get('https://httpbin.org/anything');print('body: ${resp.content()}'); | Browser with Wasm-GC support enabled1 | Wrapper overpackage:http. | ||||
import'package:web/web.dart'as web;final resp=await web.window.fetch('https://httpbin.org/anything'.toJS).toDart;final txt=await resp.text().toDart;print('${txt}'); | Browser with Wasm-GC support enabled1 | Direct | ||||
import'dart:js_interop';@JS()externalJSPromise<Response>fetch(JSString _);extension typeResponse(JSObject _)implementsJSObject {@JS()externalJSPromise<JSString>text();}finalResponse resp=awaitfetch('https://httpbin.org/anything'.toJS).toDart;final txt=await resp.text().toDart;print('body: ${txt}'); | Direct JS | |||||
SDK for writing Cloudflare Workers in Dart aka cf_workers.dart | import'package:http/http.dart';import'package:cf_workers/cf_workers.dart';import'package:cf_workers/http.dart';Future<void>main() {returnWorkers((JSRequest req)async {returnfetch(Request('GET',Uri.parse('https://httpbin.org/anything')).toJS); }).serve();} | JS |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
Common Expression Language | // two custom functionsprintln(httpget('https://httpbin.org/anything')) | UsingGolang's | ||||
// two custom functionsprintln(httpget('https://httpbin.org/anything')) | UsingGolang's |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
: URL$S" https://httpbin.org/anything" ;( custom word )URL$ HTTPGET | JS |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
import"net/http"resp,err:=http.Get("https://httpbin.org/anything") | Browser andNode.js | |||||
Save 4 MB of wasm binary size | import"marwan.io/wasm-fetch"resp,err:=fetch.Fetch("https://httpbin.org/anything",&fetch.Opts{})iferr==nil {println(string(resp.Body))} | Browser andNode.js | DirectJS | |||
import"github.com/Nigel2392/requester"varclient=requester.NewAPIClient()client.Get("https://httpbin.org/anything").Do(func(response*http.Response) {body,err:=io.ReadAll(response.Body)iferr==nil {fmt.Println(string(body)) } }) | Browser and maybe Node.js | UsesGolang's | ||||
SPA framework | import ("github.com/realPy/hogosuru""github.com/realPy/hogosuru/base/fetch""github.com/realPy/hogosuru/base/promise""github.com/realPy/hogosuru/base/response")f,err:=fetch.New("https://httpbin.org/anything",nil)f.Then(func(r response.Response)*promise.Promise {txtpromise,_:=f.Then(func(r response.Response)*promise.Promise {ifprm,err:=r.Text();hogosuru.AssertErr(err) {return&prm }returnnil },nil)txtpromise.Then(func(iinterface{})*promise.Promise {fmt.Println(i.(string))returnnil },nil)returnnil},nil) | Browser | Manual low-level JS | |||
UI library | import"io"import"log"import"net/http"gofunc() {resp,_:=http.Get(action.Url)deferresp.Body.Close()body,_:=io.ReadAll(resp.Body)log.Println(string(body))}() | Browser | Has no built-in solutions, just directlyinvokingGolang's | |||
UI library | import"io"import"log"import"net/http"resp,_:=http.Get("https://httpbin.org/anything")deferresp.Body.Close()body,_:=io.ReadAll(resp.Body)log.Println(string(body)) | Possible withDev Container | Browser | Has no built-in solutions, just directly invoking Golang's | ||
It's VM / interpreter | import ("fmt";"io";"net/http")resp,_:=http.Get("https://httpbin.org/anything")deferresp.Body.Close()body,_:=io.ReadAll(resp.Body)fmt.Println(string(body)) | Directly invokingGolang's |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
varhttp=import("net/http")varioutil=import("io/ioutil")varurl="https://httpbin.org/anything"res,_=http.DefaultClient.Get(url)b,_=ioutil.ReadAll(res.Body)println(toString(b))res.Body.Close() | Browser and maybe Node | Directly invokingGolang's | ||||
url:="https://httpbin.org/anything"resp:=fetch(url)print(resp.text()) | Browser and maybe Node | UsingGolang's | ||||
forTengo | fmt:=import("fmt")http:=import("httpclient")resp:=http.request("https://httpbin.org/anything","GET")fmt.print(is_error(resp) ?resp :resp.body) | UsingGolang's |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
transpile JVM bytecode to Wasm | importde.mirkosertic.bytecoder.api.web.*;finalWindowwin =Window.window();finalConsolecon =Console.console();win.fetch("https://httpbin.org/anything").then(newPromise.Handler<Response>() {@OverridepublicvoidhandleObject(finalResponseresp) {resp.text().then(newStringPromise.Handler() {@OverridepublicvoidhandleString(finalStringtext) {con.log(text); } }); }}); | Browser, Node.js, and Deno |
Possible, but why?
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
Requires server-side counterpart | libcurl.set_websocket('wss://your-wisp-proxy.yoursite.tld/');letres=awaitlibcurl.fetch('https://httpbin.org/anything');console.log(awaitres.text()); | Browser | Tunneling TCP to WebSocket using protocols "wisp" or "wsproxy" . |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
// Host functionconsttxt=awaitfetch('https://httpbin.org/anything');console.log(txt); | JS | |||||
constfn=async()=>{// Host functionconstres=awaitfetch('https://httpbin.org/anything');returnres.text();}exportdefaultawaitfn(); | Wrapper overquickjs-emscripten.Uses host function |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
// custom objecthttp.get('https://httpbin.org/anything'); | Browser | Using.NET's |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
constres=httpget('https://httpbin.org/anything');console.log(res); | UsingGolang's | |||||
fetch('https://httpbin.org/anything').then(function(res){returnres.text();}).then(function(txt){console.log(txt);exitloop();}); | Injecting a custom function into JS.That funcuses the goproxy as HTTP client,which is awrapper for Golang's | |||||
constres=httpget('https://httpbin.org/anything');console.log(res); | UsingGolang's |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
still Alpha | importkotlinx.browser.windowwindow.fetch("https://httpbin.org/anything").then {if (it.ok) { it.text().then {println(it)null } }null} | Browser with Wasm-GC and Wasm-Exception-Handling support enabled1, Node v21 and above, Deno v1.38 and above. | Direct |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
# custom function(print (httpget`https://httpbin.org/anything`)) | Browser and maybe Node | JS |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
localresp=fetch('https://httpbin.org/anything'):await()localtext=resp:text():await()print(text) | Direct |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
localhttp=require('http')localres,err=http.request('GET','https://httpbin.org/anything', {headers={ ['User-Agent']='gluahttp/wasm' }})print(res.body) | Browser and maybe Node | UsingGolang's | ||||
localhttp=require('http')localclient=http.client()localreq=http.request('GET','https://httpbin.org/anything')localres,err=client:do_request(req)print(res.body) | Browser and maybe Node | UsingGolang's | ||||
erdian718/lmodhttpclientaka ofunc/lmodhttpclient | localio=require('io')localhttpclient=require('http/client')localres=httpclient.get('https://httpbin.org/anything')io.copy(res,io.stdout)res:close() | Browser and maybe Node | UsingGolang's |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
localhttp=require'pluto:http'http.request('https://httpbin.org/anything')|>print | Browser and maybe Node. | JS |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
Fork ofPIB | $url ='https://httpbin.org/anything';$window =newVrzno();$window->fetch($url)->then(function($res) {return$res->text(); })->then(var_dump(...)); |
| Browser,Bun,Deno,Node,andCloudFlare Workers. | Manual JS |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
functionhttpGet(url: ShortString;Var str_out: ShortString): ShortString;external'js';var out_str : ShortString;begin out_str:= DupeString('' ,255 ); httpGet('https://httpbin.org/anything', out_str); writeln(out_str);end. | Browser and maybe Node | Direct |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
use WebPerlqw/js js_new sub_once/;my$xhr = js_new('XMLHttpRequest');$xhr->addEventListener('load', sub_once {print'Done:'.$xhr->{responseText};});$xhr->open('GET','https://httpbin.org/anything', 0);$xhr->send(); | Browser, Node.js, and Deno | Manual JS |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
:-use_module(library(wasm)). ?- js_eval("const xhr=new XMLHttpRequest(); xhr.open('GET','https://httpbin.org/anything',false); xhr.send(); xhr.responseText;", Txt), format("~s", [Txt]). | <-- |
| Browser | Manual JS | ||
fetch('https://httpbin.org/anything',text,Out). | <-- |
| Browser and Node | |||
js_eval("return fetch('https://httpbin.org/anything').then(r => r.text());",Txt). | Example code works inPlayground | Browser andNode | Manual invoking of JS |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
% custom predicatehttpget("https://httpbin.org/anything",RespTxt). | UsingGolang's |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
frombrowserimportfetchfetch('https://httpbin.org/anything').then(lambdaresp:print((resp))) | Browser,Node.js, and maybe Deno | |||||
frompyodide.httpimportpyfetchresponse=awaitpyfetch("https://httpbin.org/anything") Also note that thepyodide-http isbundled in Pyodide. | Browser, Node.js, andmaybe Deno | |||||
# needs `await micropip.install(['pyodide-http', 'requests'])`importpyodide_httppyodide_http.patch_all()importrequestsresponse=requests.get("https://httpbin.org/anything") |
| Browser and maybe Node.js | JS | |||
Since2.2.0 | importmicropipawaitmicropip.install('urllib3')importurllib3res=urllib3.request('GET','https://httpbin.org/anything')print(res.data.decode('utf-8')) # using requestsimportmicropipawaitmicropip.install('requests')importrequestsres=requests.get('https://httpbin.org/anything')print(res.text) | Browseronly (yet) | JS | |||
importhttpclientprint(httpclient.Get('https://httpbin.org/anything')) | UsingGolang's | |||||
frompyodide.httpimportpyfetch,FetchResponseimportasyncioasyncdefreq()->FetchResponse:response=awaitpyfetch("https://httpbin.org/anything")print(awaitresponse.string())asyncio.ensure_future(req()) | Browser | |||||
response=requests.get("https://httpbin.org/anything") | Browser | Employskoenvo/pyodide-http. Also direct | ||||
# using Pandasimportpyodide_http;pyodide_http.patch_all()importpandasaspddata=pd.read_json('https://httpbin.org/json')data # using js.fetchfromjsimportfetchres=awaitfetch('https://httpbin.org/anything')text=awaitres.text()print(text) # using requestsimportmicropip;awaitmicropip.install(['requests'])importpyodide_http;pyodide_http.patch_all()importrequestsres=requests.get("https://httpbin.org/anything")print(res.text) | Browser | Employing | ||||
importjsfetch=JS('fetch')response=fetch('https://httpbin.org/anything').wait()text=response.text().wait()print(text) | Browser and Node.js | Direct | ||||
a port ofStreamlit to Wasm | frompyodide.httpimportpyfetchimportstreamlitasstresponse=awaitpyfetch("https://httpbin.org/anything")body=awaitresponse.string()st.write(body) | Browser | ||||
lightweight Python 3.x | # custom moduleimporthttpprint(http.get('https://httpbin.org/anything')) | Browser | JS |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
It's compiler | fromjavascriptimportObject,asynchronous,JSON@asynchronousdefsend_request(url):fetch=Object('fetch')res=fetch.call(url).wait()text=res['text'].call().wait()print(text)returntextdeftarget(*args):returnmain,Nonedefmain(argv):send_request('https://httpbin.org/anything')return0if__name__=='__main__':importsysmain(sys.argv) | Browser, Node.js, and Deno | Direct |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
df<- read.csv("https://httpbin.org/anything")print(df)//Allworks: read.table()variants, download.file(), scan(), url(),etc | Browser and Node | Implemented |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
go does { get https://httpbin.org/anything |print } | Browser | UsingGolang's |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
require'js'resp=JS.global.fetch('https://httpbin.org/anything').awaitputsresp.text.await | DirectJS |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
let window = web_sys::window().unwrap();let resp_val =JsFuture::from( window.fetch_with_str("https://httpbin.org/anything")).await?; | Prints to browserconsole,source | |||||
letmut resp =Fetch::Url("https://httpbin.org/anything".parse().unwrap(),).send().await?;let txt = resp.text().await?; | ||||||
let request = ehttp::Request::get("https://httpbin.org/anything");ehttp::fetch(request,move |result: ehttp::Result<ehttp::Response>|{println!("Text: {:?}", result.unwrap().text());}); | Browser, Node.js, and Deno. Alsonative | |||||
let uri =Uri::from_static("https://httpbin.org/anything");let req =Request::get(uri).body(None).unwrap();let client = web_sys::window();let resp = client.issue(req).await.unwrap();println!("{}", resp.body()); | Browser, Node.js, and Deno. Alsonative | |||||
use http_client::HttpClient;use http_types::{Method,Request};use http_client::wasm::WasmClientasClient;let client =Client::new();let req =Request::new(Method::Get,"https://httpbin.org/anything");client.send(req).await.unwrap();dbg!(client); | Browser, Node.js, and Deno Alsonative (and others). | |||||
use gloo_net::http::Request;let resp =Request::get("https://httpbin.org/anything").send().await.unwrap(); | Browser, Node.js, and Deno | |||||
// uses reqwestlet txt = reqwest::get("https://httpbin.org/anything").await?.text().await?;log::info!("text: {}", txt); | Browser | Has no built-in solutions, just uses any suitable 3rd-party lib, such as:reqwest. | ||||
// uses reqwasm or gloo_net for CSRuse leptos_dom::logging::console_log;let txt = reqwasm::http::Request::get("https://httpbin.org/anything").send().await?.text().await?;console_log(txt.as_str()); | Browser Also server-side rendering (SSR) | Has no built-in solutions, just uses any suitable 3rd-party lib, such as:reqwest,gloo_net,reqwasm. | ||||
use localghost::prelude::*;use localghost::{log, net};let res = net::Request::get("https://httpbin.org/anything").send().await?;log::info!("text: {:?}", res.body_string().await?); | Browser and maybe Node | |||||
use zoon::{println,*};let txt = reqwest::get("https://httpbin.org/anything").await?.error_for_status()?.text().await?;println!("text: {}", txt); | Browser | Has no built-in solutions, just uses any suitable 3rd-party lib, such as:reqwest. | ||||
use quad_net::http_request::RequestBuilder;letmut request =RequestBuilder::new("https://httpbin.org/anything").send();loop{ifletSome(data) = request.try_recv(){info!("Done! {}", data.unwrap());}next_frame().await;} | Browser | |||||
let txt = reqwest::get("https://httpbin.org/anything").await?.text().await?;println!("Text: {:?}", txt); | Browser, Node.js, and Deno Alsonative | |||||
use reqwasm::http::Request;let resp =Request::get("https://httpbin.org/anything").send().await.unwrap(); | Browser, Node.js, and Deno | |||||
use sauron::dom::{Http, spawn_local};spawn_local(asyncmove{let txt =Http::fetch_text("https://httpbin.org/anything").await.unwrap(); log::trace!("{}", txt);}); | Browser Also server-side rendering (SSR) | |||||
use seed::{prelude::*,*};let response =fetch("https://httpbin.org/anything").await?;let body = response.text().await?; | Browser, Node.js, and Deno | |||||
letmut resp = surf::get("https://httpbin.org/anything").await?;println!("{}", resp.body_string().await?); | Browser, Node.js, and Deno Alsonative | Useshttp-rs/http-client as WASM backend | ||||
// uses reqwasmuse reqwasm::http::Request;let url ="https://httpbin.org/anything";let res =Request::get(&url).send().await?;let txt = res.text().await?;log::info!("{}", txt); | Browser | Has no built-in solutions, just uses any suitable 3rd-party lib, such as:reqwasm. |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
let req = http::get("https://httpbin.org/anything").await?;let txt = req.text().await?;println(txt); | Browser |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
# custom functionprint(httpget('https://httpbin.org/anything')) | UsingGolang's | |||||
res=http.get('https://httpbin.org/anything')print(res.body) | UsingGolang's | |||||
"Starlark's missing stdlib" | load('http.star','http')res=http.get('https://httpbin.org/anything')print(res.body()) | UsingGolang's | ||||
# custom functionprint(httpget('https://httpbin.org/anything')) | UsingGolang's | |||||
Maintained fork of Starlight | # custom functionprint(httpget('https://httpbin.org/anything')) | UsingGolang's |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
import JavaScriptEventLoopimport JavaScriptKitJavaScriptEventLoop.installGlobalExecutor()letfetch=JSObject.global.fetch.function!letresp=try!awaitJSPromise(fetch("https://httpbin.org/anything").object!)!.valuelettext=try!awaitJSPromise(resp.text().object!)!.valueprint(text) | Browser,Node.js, and Deno | Direct |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
# custom commandputs [httpget"https://httpbin.org/anything"] | UsesGolang's | |||||
set func_ptr_number 2puts [::wacl::jscall$func_ptr_number"string""string""https://httpbin.org/anything"] Needs a JavaScript-side function registered using wacl.onReady(function(interpreter){constwrappedFuncName=interpreter.jswrap(function(ptrUrl){consturl=interpreter.ptr2str(ptrUrl);constxhr=newXMLHttpRequest();xhr.open('GET',url,false);xhr.send();returninterpreter.str2ptr(xhr.responseText);},'string','string');}); | Browser | Manual JS |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
Local request:=New HttpRequestrequest.ReadyStateChanged= Lambda()If request.ReadyState= ReadyState.DoneThenPrint"Body:"+ request.ResponseTextEndEndrequest.Open("GET","https://httpbin.org/anything")request.Send() | Browser | JS |
Standalone and server-side runtimes (mostly WASI and WASI-Socket-enabled), incl containers, FaaS, Edge Computing, etc
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
implementations: | import{Console}from"as-wasi/assembly";import{request}from"./request";exportfunctioncabi_realloc(a:usize,b:usize,c:usize,len:usize):usize{returnheap.alloc(len);}letresponse=request("GET","https://httpbin.org/anything",null,[{name:"User-Agent",value:"wasi-http"}]);Console.log(response.Body); | Dev Containerby brendandburns |
|
|
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
usingExtism;varreq=newHttpRequest("https://httpbin.org/anything"){Method=HttpMethod.GET};varres=Pdk.SendRequest(req);Pdk.SetOutput(res.Body); | CallingC-level-importedruntime'shost functionexported for plugins,whichmakes actual request using | |||||
usingFermyon.Spin.Sdk;usingSystem.Net;varreq=newHttpRequest{Url="https://httpbin.org/anything"};varresp=HttpOutbound.Send(req); | C levelbinding to | |||||
implementations: | // *Still* identical to wasi-experimental-http's code.usingWasi.Http;varclient=newHttpClient(newWasiHttpHandler());varresult=awaitclient.GetAsync("https://httpbin.org/anything",System.Threading.CancellationToken.None);varcontent=awaitresult.Content.ReadAsStringAsync();Console.WriteLine(content); | Dev Containerby brendandburns |
| Sequence: .Net -> C -> WASI CallingimportedC-levelMono bindingwhichcallsgenerated(by
|
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
#defineEXTISM_IMPLEMENTATION#include"extism-pdk.h"#include<stdint.h>#include<string.h>int32_tEXTISM_EXPORTED_FUNCTION(httpget) {constchar *r ="{\"url\":\"https://httpbin.org/anything\"}"; ExtismHandle req =extism_alloc_buf_from_sz(r); ExtismHandle res =extism_http_request(req,0);extism_output_set_from_handle(res,0,extism_length(res));return0;} | CallingC-level-importedruntime'shost functionexported for plugins,whichmakes actual request using | |||||
// no SSL support yetstd::array<char,4096> buf{};fetchIO *io = fetchGetURL("http://httpbin.org/anything","4");int nbytes = fetchIO_read(io, buf.data(), buf.size());fetchIO_close(io);std::cout << buf.data() << std::endl; | Rawsocket writeusingWasmEdge Socket SDK for C/C++, whichimports Wasmedge's implementation of WASI Socket | |||||
implementations: |
// snippet, expand it for full codetypes_outgoing_request_trequest=types_new_outgoing_request(&method,&path,&query,&scheme,&domain,headers);response=default_outgoing_http_handle(request,NULL);types_future_incoming_response_get(response,&result);types_incoming_response_consume(result.val.ok,&stream);streams_read(stream,len,&body_res,&err); #include"proxy.h"// Generated by wit-bindgen// from https://github.com/WebAssembly/wasi-http/tree/main/wit#include<stdio.h>voidhttp_handle(uint32_targ,uint32_targ0) {}intmain() {types_headers_theaders=types_new_fields(NULL);types_method_tmethod= {.tag=TYPES_METHOD_GET};types_scheme_tscheme= {.tag=TYPES_SCHEME_HTTPS};proxy_string_tpath,domain,query;proxy_string_set(&domain,"httpbin.org");proxy_string_set(&path,"/anything");proxy_string_set(&query,"");types_outgoing_request_trequest=types_new_outgoing_request(&method,&path,&query,&scheme,&domain,headers);types_future_incoming_response_tresponse;response=default_outgoing_http_handle(request,NULL);proxy_result_incoming_response_error_tresult;types_future_incoming_response_get(response,&result);types_incoming_stream_tstream;types_incoming_response_consume(result.val.ok,&stream);int32_tlen=16*1024;proxy_tuple2_list_u8_bool_tbody_res;streams_stream_error_terr;streams_read(stream,len,&body_res,&err);printf("Response body: %s\n",body_res.f0.ptr);proxy_tuple2_list_u8_bool_free(&body_res);types_drop_outgoing_request(request);streams_drop_input_stream(stream);types_drop_incoming_response(result.val.ok);return0;} | Dev Containerby brendandburns |
| Callinga functiongeneratedby
|
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
import ( hf"github.com/bots-garden/capsule/capsulemodule/hostfunctions")res,err:=hf.Http("https://httpbin.org/anything","GET",nil,"") | ||||||
import"github.com/extism/go-pdk"req:=pdk.NewHTTPRequest("GET","https://httpbin.org/anything")resp:=req.Send()pdk.OutputMemory(resp.Memory()) | Extismuses Wasmtime | CallingC-level-importedruntime'shost functionexported for plugins,whichmakes actual request using | ||||
hostFunctions:=protobufs.NewHostFunctions()resp,err:=hostFunctions.HttpGet(ctx,&protobufs.HttpGetRequest{Url:"https://httpbin.org/anything"}) | go-pluginuses wazero | |||||
import ( spinhttp"github.com/fermyon/spin/sdk/go/http")resp,err:=spinhttp.Get("https://httpbin.org/anything") | C levelbinding to | |||||
implementations: | import ("io/ioutil""net/http" wasiclient"github.com/dev-wasm/dev-wasm-go/client")client:= http.Client{Transport: wasiclient.WasiRoundTripper{},}response,err:=client.Get("https://httpbin.org/anything")deferresponse.Body.Close()body,err:=ioutil.ReadAll(response.Body)iferr==nil {println(string(body))} | Dev Containerby brendandburnsneeds plenty of RAM to compile (~4G), so may cause OOM on 2-core instance |
| Sequence: Go -> C -> WASI Callingamethodgeneratedby
| ||
import ("io";"log";"net/http" _"github.com/ydnar/wasi-http-go/wasihttp")req,_:=http.NewRequest("GET","https://httpbin.org/anything",http.NoBody)resp,_:=http.DefaultClient.Do(req)deferresp.Body.Close()body,_:=io.ReadAll(resp.Body)log.Println(string(body)) | Runtime supporting wasip2-http (only Wasmtime at the moment) | |||||
f.k.a. stealthrocket/net | import ("fmt" ;"io" ;"net/http" _"github.com/dispatchrun/net/http")response,err:=http.Get("http://httpbin.org/anything")iferr!=nil {fmt.Println(err)}deferresponse.Body.Close()body,err:=io.ReadAll(response.Body)iferr==nil {fmt.Println(string(body))} | Hotpatching on module import | ||||
import ("log";"net/http""github.com/vmware-labs/wasm-workers-server/kits/go/worker")req,_:=http.NewRequest(http.MethodGet,"https://httpbin.org/anything",nil)res,_:=worker.SendHttpRequest(req)deferres.Body.Close()body,_:=io.ReadAll(res.Body)log.Println(string(body)) | Calling toGo-wrapped, toC-wrapped, toC-level importedhost functionwhichmakesrequest usingreqwest. |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
moduleMainwhereimportExtism.PDKimportExtism.PDK.HTTPhttps_get=dolet url="https://httpbin.org/anything"let req= newRequest url resp<- sendRequest reqNothing outputMemory (memory resp)foreignexport ccall"https_get" https_get::IO()main= https_get | Extismuses Wasmtime | Callingimportedruntime'shost functionexported for plugins,whichmakes actual request using |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
Usesforked TeaVM as compiler. | importwit_wasi_outbound_http.WasiOutboundHttp.*;Result<Response,HttpError>result =WasiOutboundHttp.request(newRequest(Method.GET,"https://httpbin.org/anything",newArrayList<>(),newArrayList<>(),null));Responseresp =result.getOk();Stringbody =newString(resp.body,UTF_8); | DirectinvocationofimportedSpin'shost function. |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
import{fetch}from'http'constres=awaitfetch('https://httpbin.org/anything')print(awaitres.text()) | Distinguished by URL schemeraw socket writeto(1) | |||||
functionhttps_get(){letresp=Http.request({url:'https://httpbin.org/anything',method:'GET',headers:{'User-Agent':'extism_pdk'}},null);Host.outputString(resp.body);}module.exports={ https_get} | Extismuses Wasmtime |
| ||||
constresp=awaitfetch('https://httpbin.org/anything');constdecoder=newTextDecoder('utf-8');constbody=decoder.decode(awaitresp.arrayBuffer()); | InvocationofboundJS SDK function,whichcallsviaRust Spin SDKSpin'shost function. | |||||
constresp=awaitfetch('https://httpbin.org/anything');constbody=awaitresp.text(); | InvocationofboundJS SDK function,whichcallsviaRust Spin SDKSpin'shost function. | |||||
constresp=awaitfetch('https://httpbin.org/anything');consttxt=awaitresp.text();console.log(txt); | Callingbound to JS |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
Extism Plug-in Development Kit (PDK) for MoonBit Experimental | pubfnhttps_get() ->Int{let req:Unit = @http.new_request( @http.Method::GET,"https://httpbin.org/anything",)let resp:Unit = req.send() resp.output()return0} | Callingimportedruntime'shost functionexported for plugins,whichmakes actual request using |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
Spin SDK for Prolog | :-use_module(library(spin)).http_fetch("https://httpbin.org/anything",Resp,[]),write(Resp),nl. | Invoking |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
importpoll_loopfromproxy.imports.typesimport (SchemeHttps,OutgoingRequest )req=OutgoingRequest(Fields.from_list([]))req.set_scheme(SchemeHttps())req.set_authority('httpbin.org')req.set_path_with_query('/anything')resp=awaitpoll_loop.send(req)stream=poll_loop.Stream(resp.consume())buf=b''whileTrue:chunk=awaitstream.next()ifchunkisNone:breakelse:buf+=chunkprint(buf.decode('utf-8')) | Wasmtime version 15.0, maybe incl. Spin. | Genetaring Python bindings to wasi-http based onwit files under the scenes during | ||||
importextism@extism.plugin_fndefhttpget():res=extism.Http.request('https://httpbin.org/anything')extism.output_str(res.data_str()) |
| |||||
fromspin_httpimportRequest,http_sendresponse=http_send(Request('GET','https://httpbin.org/anything', {},None))print(str(response.body,'utf-8')) | A Python |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
use extism_pdk::*;#[plugin_fn]pubfnhttps_get(_:()) ->FnResult<Memory>{let req =HttpRequest::new("https://httpbin.org/anything");let resp = http::request::<()>(&req,None)?;Ok(resp.into_memory())} | Possible withDev Containerby brendandburns | CallingC-level-importedruntime'shost functionexported for plugins,whichmakes actual request using | ||||
use http_req::request;letmut writer =Vec::new();let res = request::get("https://httpbin.org/anything",&mut writer).unwrap();println!("body: {}",String::from_utf8_lossy(&writer)); | Writes to | |||||
letmut res = spin_sdk::http::send( http::Request::builder().method("GET").uri("https://httpbin.org/anything").body(None)?,)?; | CallingimportedSpin'shost function. | |||||
as part of Any code based on WasmEdge's forks oftokio-rsormioisexpected to work in Wasmedge runtime | let res = reqwest::get("https://httpbin.org/anything").await?;let body = res.text().await?;println!("text: {}", body); | Wrappinginternal stream withWasmEdgeTls, which is built on top ofWasmEdge's implementation of WASI Socket. | ||||
new gen ofwasi-http-client | use waki::Client;let res =Client::new().get("https://httpbin.org/anything").send().unwrap();let body =String::from_utf8( res.body().unwrap()).unwrap();println!("body:{}", body); | Wasmtime version17 and above | ||||
implementations: | let headers = types::new_fields(&[("User-agent","WASI-HTTP")]);let request = types::new_outgoing_request( types::MethodParam::Get,"/anything","",Some(types::SchemeParam::Https),"httpbin.org", headers,);let future_response = default_outgoing_http::handle(request,None);types::drop_outgoing_request(request);let response = types::future_incoming_response_get(future_response).ok_or_else(||anyhow!("response is available immediately"))?.map_err(|err|anyhow!("response error: {err:?}"))?;types::drop_future_incoming_response(future_response);let stream = types::incoming_response_consume(response).map_err(|()|anyhow!("response has no body stream"))?;letmut body =Vec::new();letmut is_eof =false;while !is_eof{let(mut chunk, stream_at_end) = streams::read(stream, u64::MAX)?; is_eof = stream_at_end; body.append(&mut chunk);}streams::drop_input_stream(stream);types::drop_incoming_response(response);println!("body: {}",str::from_utf8(&body).unwrap()); | Possible withDev Containerby brendandburns |
| Rust codegenerated(by
| ||
let req =Request::builder().uri("https://httpbin.org/anything").body(String::new()).unwrap();let res = bindings::send_http_request(req).unwrap();let data = res.body();let txt =String::from_utf8_lossy(&data);println!("text: {txt}"); | Callingimportedhost functionwhichmakesrequest usingreqwest. |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
varreq=Http.newRequest(Method.GET,"https://httpbin.org/anything");defres=req.send(null);res.output(); | CallingC-level-importedruntime'shost functionexported for plugins,whichmakes actual request using |
Product / Implementation | TLDR: Usage | TLDR: Example code | Doc | Online demo | WASM Runtime | Internals: method to do real request |
---|---|---|---|---|---|---|
conststd=@import("std");constextism_pdk=@import("extism-pdk");constallocator=std.heap.wasm_allocator;exportfnhttps_get()i32 {constplugin=extism_pdk.Plugin.init(allocator);varreq=extism_pdk.http.HttpRequest.init(allocator,"GET","https://httpbin.org/anything");deferreq.deinit();req.setHeader("User-Agent","extism_pdk")catchunreachable;constresp=plugin.request(req,null)catchunreachable;deferresp.deinit();plugin.outputMemory(resp.memory);return0;} | Extismuses Wasmtime | Callingimportedruntime'shost functionexported for plugins,whichmakes actual request using | ||||
| constspin=@import("spin");constreq=spin.http.Request{ .method=.GET, .url="https://httpbin.org/anything" };constres=spin.http.send(req)catchunreachable; | Callingto C-levelimportofSpin'shost function. |
Footnotes
About
(Wannabe-awesome) list of methods to make outbound HTTP(S) requests from within WebAssembly in many languages
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.