Go HTTP Server
This example is a WebAssembly component that implements a simple HTTP server with multiple endpoints for handling various requests.
The application...
- Implements a
wasi:http-compliant HTTP handler - Uses the
httpserverprovider to serve requests - Can be declaratively provisioned in a wasmCloud environment
📦 Dependencies
[!WARNING] Due to incompatibilities introduced in
wasm-toolsv1.226.0, a version ofwasm-tools<= 1.225.0 is required for running this example.You can install
wasm-toolsv1.225.0 from upstream releases, or usecargo(Rust toolchain) -- (i.e.cargo install --locked wasm-tools@1.225.0)
Before starting, ensure that you have the following installed in addition to the Go (1.23+) toolchain:
tinygofor compiling Go (always use the latest version)wasm-toolsfor Go bindings- wasmCloud Shell (
wash) for building and running the components and wasmCloud environment
👟 Run the example
Clone the wasmCloud/go repository:
git clone https://github.com/wasmCloud/go.gitChange directory to examples/component/http-server:
cd examples/component/http-serverIn addition to the standard elements of a Go project, the example directory includes the following files and directories:
build/: Target directory for compiled.wasmbinariesgen/: Target directory for Go bindings of interfaceswit/: Directory for WebAssembly Interface Type (WIT) packages that define interfacesbindings.wadge_test.go: Automatically generated test bindingswadm.yaml: Declarative application manifestwasmcloud.lock: Automatically generated lockfile for WIT packageswasmcloud.toml: Configuration file for a wasmCloud application
Start a local development loop
Run wash dev to start a local development loop:
wash devThe wash dev command will:
- Start a local wasmCloud environment
- Build this component
- Deploy your application and all requirements to run the application locally, including...
- Your locally built component
- The HTTP server provider, which will receive requests from the outside world (on port 8000 by default)
- Necessary links between providers and your component so your component can handle web traffic
- Watch your code for changes and re-deploy when necessary.
Once the application is deployed, open another terminal tab. To ensure that the application has reached Deployed status, you can use wash app list:
wash app listSend a request
You can send a request to the following endpoints:
GET /
Returns a list of available endpoints and their descriptions.
curl http://localhost:8000/ /error - return a 500 error
/form - echo the fields of a POST request
/headers - echo your user agent back as a server side header
/post - echo the body of a POST requestGET /error
Returns a 500 Internal Server Error.
curl -v http://localhost:8000/error* Host localhost:8000 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
* Trying [::1]:8000...
* connect to ::1 port 8000 from ::1 port 51390 failed: Connection refused
* Trying 127.0.0.1:8000...
* Connected to localhost (127.0.0.1) port 8000
> GET /error HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/8.7.1
> Accept: */*
>
* Request completely sent off
< HTTP/1.1 500 Internal Server Error
< content-type: text/plain; charset=utf-8
< x-content-type-options: nosniff
< vary: origin, access-control-request-method, access-control-request-headers
< access-control-allow-origin: *
< access-control-expose-headers: *
< connection: close
< transfer-encoding: chunked
< date: Thu, 19 Dec 2024 23:52:34 GMT
<
Something went wrong
* Closing connectionGET /headers
Returns your User-Agent in the response headers.
curl -v http://localhost:8000/headers* Host localhost:8000 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
* Trying [::1]:8000...
* connect to ::1 port 8000 from ::1 port 51499 failed: Connection refused
* Trying 127.0.0.1:8000...
* Connected to localhost (127.0.0.1) port 8000
> GET /headers HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/8.7.1
> Accept: */*
>
* Request completely sent off
< HTTP/1.1 200 OK
< x-your-user-agent: curl/8.7.1
< vary: origin, access-control-request-method, access-control-request-headers
< access-control-allow-origin: *
< access-control-expose-headers: *
< connection: close
< transfer-encoding: chunked
< date: Thu, 19 Dec 2024 23:53:49 GMT
<
* Closing connection
Check headers!POST /form
Echoes back form data from a POST request.
curl -X POST -d "field1=value1&field2=value2" http://localhost:8000/formfield2: value2
field1: value1POST /post
Echoes back the entire body of a POST request.
curl -X POST -d "Hello World" http://localhost:8000/postHello WorldClean up
You can cancel the wash dev process with Ctrl-C.
⚠️ Issues/FAQ
curl produces a "failed to invoke" error
If curling produces...
failed to invoke `wrpc:http/incoming-handler.handle`: failed to invoke `wrpc:http/incoming-handler@0.1.0.handle`: failed to shutdown synchronous parameter channel: not connected%...the HTTP server may not have finished starting up. You can check that the application has reached Deployed status with wash app list.
If the issue persists, you may have a lingering HTTP server provider running on your system. You can use pgrep to check:
pgrep -la ghcr_io4007604 /tmp/wasmcloudcache/NBCBQOZPJXTJEZDV2VNY32KGEMTLFVP2XJRZJ5FWEJJOXESJXXR2RO46/ghcr_io_wasmcloud_http_server_0_23_1📖 Further reading
To learn how to extend this example with additional capabilities, see the Adding Capabilities section of the wasmCloud documentation.
For more on building components, see the Component Developer Guide in the wasmCloud documentation.