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

Make a http request from wasi #4540

Open
dshemin opened this issue Oct 21, 2024 · 1 comment
Open

Make a http request from wasi #4540

dshemin opened this issue Oct 21, 2024 · 1 comment

Comments

@dshemin
Copy link
Contributor

dshemin commented Oct 21, 2024

Hi!

I try to make a http request from WASM module running on wazero and got an error^

Netdev not set

I try to use netdev package but can't find any suitable examples. Can someone tell me is it possible or not?

My module:

package main

import (
	"encoding/json"
	"errors"
	"fmt"
	"net/http"
	"os"
	"time"

	"tinygo.org/x/drivers/netdev"
)

//go:generate easyjson main.go

//export call
func call() {
	netdev.UseNetdev(/* That i should pass here? */)
	resp, err := http.Get("https://swapi.dev/api/people/1")
	handleErr(err, "get")

	if resp.StatusCode != http.StatusOK {
		handleErr(errors.New("not 200"), "check status code")
	}
	defer resp.Body.Close()

	var p People
	err = json.NewDecoder(resp.Body).Decode(&p)
	handleErr(err, "decode")

	fmt.Printf("%#v", p)
}

func handleErr(err error, msg string) {
	if err != nil {
		fmt.Println(msg + ": " + err.Error())
		os.Exit(1)
	}
}

//easyjson:json
type People struct {
	Name      string    `json:"name"`
	Height    string    `json:"height"`
	Mass      string    `json:"mass"`
	HairColor string    `json:"hair_color"`
	SkinColor string    `json:"skin_color"`
	EyeColor  string    `json:"eye_color"`
	BirthYear string    `json:"birth_year"`
	Gender    string    `json:"gender"`
	Homeworld string    `json:"homeworld"`
	Films     []string  `json:"films"`
	Species   []string  `json:"species"`
	Vehicles  []string  `json:"vehicles"`
	Starships []string  `json:"starships"`
	Created   time.Time `json:"created"`
	Edited    time.Time `json:"edited"`
	URL       string    `json:"url"`
}

func main() {

}

This module I build with this command:

tinygo build -o module/http_client.wasm -target=wasip1 module/http_client/main.go

My tingo version is 0.33.0

@elewis787
Copy link

I haven't used wazero a ton but I have worked with HTTP with wasm/wasi a fair amount.

I would suggest taking a look at wasip2 support that was added and wasi-http.

I played around with implementing a custom HTTP transport here https://github.com/hayride-dev/wasi/blob/main/http/transport/transport.go

and you can see how it was used to do an http.client request here https://github.com/hayride-dev/wasi-tinygo/blob/main/main.go

This uses a lot of wasip2 elements, but it is possible to do similar flows in wasip1. I am working on cleaning up the bindings and will be releasing server handler support and client request support here soon.

In my experience, it does involve creating a custom HTTP transport that can do the translation from host ( wazero env ) to guest ( wasm module/component ) or vice versa

I would recommend taking a look at https://extism.org/docs/concepts/runtime-apis ( which if I recall correctly uses wazero ) and if you are looking at wasip2 checking out wasmtime.

Unfortunately, their Golang bindings do not support wasip2 yet tho so you would need to use Rust as your host and deploy a tinygo component that makes an HTTP client request.

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