|
| 1 | +# Making outbound HTTP requests from TinyGo Spin components |
| 2 | + |
| 3 | +The TinyGo SDK for building Spin components allows us to granularly allow |
| 4 | +components to send HTTP requests to certain hosts. This is configured in |
| 5 | +`spin.toml`. |
| 6 | + |
| 7 | +> For more information and examples for using TinyGo with WebAssembly, check |
| 8 | +> [the official TinyGo documentation](https://tinygo.org/docs/guides/webassembly/) |
| 9 | +> and |
| 10 | +> [the Wasm examples](https://github.com/tinygo-org/tinygo/tree/release/src/examples/wasm). |
| 11 | +
|
| 12 | +Creating and sending HTTP requests from Spin components closely follows the Go |
| 13 | +`net/http` API. See [tinygo-hello/main.go](./tinygo-hello/main.go). |
| 14 | + |
| 15 | +Building this as a WebAssembly module can be done using the `tinygo` compiler: |
| 16 | + |
| 17 | +```shell |
| 18 | +$ spin build |
| 19 | +Building component outbound-http-to-same-app with `tinygo build -target=wasi -gc=leaking -no-debug -o main.wasm main.go` |
| 20 | +Working directory: "./outbound-http-to-same-app" |
| 21 | +Building component tinygo-hello with `tinygo build -target=wasi -gc=leaking -no-debug -o main.wasm main.go` |
| 22 | +Working directory: "./tinygo-hello" |
| 23 | +Finished building all Spin components |
| 24 | +``` |
| 25 | + |
| 26 | +The component configuration must contain a list of all hosts allowed to send |
| 27 | +HTTP requests to, otherwise sending the request results in an error: |
| 28 | + |
| 29 | +``` |
| 30 | +Cannot send HTTP request: Destination not allowed: <URL> |
| 31 | +``` |
| 32 | + |
| 33 | +The `tinygo-hello` component has the following allowed hosts set: |
| 34 | + |
| 35 | +```toml |
| 36 | +[component.tinygo-hello] |
| 37 | +source = "tinygo-hello/main.wasm" |
| 38 | +allowed_outbound_hosts = [ |
| 39 | + "https://random-data-api.fermyon.app", |
| 40 | + "https://postman-echo.com", |
| 41 | +] |
| 42 | +``` |
| 43 | + |
| 44 | +And the `outbound-http-to-same-app` uses the dedicated `self` keyword to enable making |
| 45 | +a request to another component in this same app, via a relative path (in this case, the component |
| 46 | +is `tinygo-hello` at `/hello`): |
| 47 | + |
| 48 | +```toml |
| 49 | +[component.outbound-http-to-same-app] |
| 50 | +source = "outbound-http-to-same-app/main.wasm" |
| 51 | +# Use self to make outbound requests to components in the same Spin application. |
| 52 | +allowed_outbound_hosts = ["http://self"] |
| 53 | +``` |
| 54 | + |
| 55 | +At this point, we can execute the application with the `spin` CLI: |
| 56 | + |
| 57 | +```shell |
| 58 | +$ RUST_LOG=spin=trace,wasi_outbound_http=trace spin up |
| 59 | +``` |
| 60 | + |
| 61 | +The application can now receive requests on `http://localhost:3000/hello`: |
| 62 | + |
| 63 | +```shell |
| 64 | +$ curl -i localhost:3000/hello -X POST -d "hello there" |
| 65 | +HTTP/1.1 200 OK |
| 66 | +content-length: 976 |
| 67 | +date: Thu, 26 Oct 2023 18:26:17 GMT |
| 68 | + |
| 69 | +{{"timestamp":1698344776965,"fact":"Reindeer grow new antlers every year"}} |
| 70 | +... |
| 71 | +``` |
| 72 | + |
| 73 | +As well as via the `/outbound-http-to-same-app` path to verify outbound http to the `tinygo-hello` component: |
| 74 | + |
| 75 | +```shell |
| 76 | +$ curl -i localhost:3000/outbound-http-to-same-app |
| 77 | +HTTP/1.1 200 OK |
| 78 | +content-length: 946 |
| 79 | +date: Thu, 26 Oct 2023 18:26:53 GMT |
| 80 | + |
| 81 | +{{{"timestamp":1698344813408,"fact":"Some hummingbirds weigh less than a penny"}} |
| 82 | +... |
| 83 | +``` |
| 84 | + |
| 85 | +## Notes |
| 86 | + |
| 87 | +- this only implements sending HTTP/1.1 requests |
| 88 | +- requests are currently blocking and synchronous |
0 commit comments