WebAssembly / WebAssembly/WASI

Consider extending the `proxy` world with an `origin`

Open
#793 11 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

P-http
Dominant language
Rust
Stars
5.8k
Forks
333
Avg merge
2d 13h
Merged PRs (30d)
3

Description

A common pattern for HTTP middleware (like express.js or proxy-wasm) is to create a linear chain of handlers that requests flow down (and responses flow back up) where each handler can manipulate (or block) the request/response before passing it on to the next handler in the chain. While processing a request, a handler can make any number of async "side" HTTP requests that don't flow down the linear chain. Thus there are two ways an HTTP request flows out of a handler: (1) to the next handler in the chain and (2) as a side call. E.g., in proxy-wasm, (2) is expressed by proxy_http_call which is quite separate from all the callbacks used for (1).

Ideally, since components and wasi:http are all about composition, we should be able to capture this pattern directly by simply linking components together (e.g, using wac). However, since wasi:http/proxy only has one way to issue outgoing HTTP requests, there's no simple way to distinguish (1) from (2) via linking (something more dynamic/complex is required).

Before the proposed change, one bit of terminology: RFC 9110 defines a "(reverse) proxy" as a kind of "intermediary" that sits between the client and the "origin". Thus, "proxy" implies the existence of a designated "origin".

Based on this, I thought perhaps we should have two worlds in wasi:http:

package wasi:http;
world service {
  import imports;  // as currently defined
  export handler;
}
world proxy {
  include service;
  import origin;
}
interface origin {
  use types.{request, response, error-code};
  handle: func(r: request) -> result<response, error-code>;
}

or, in summary: rename proxy to service and then define proxy to extend service with an origin (which is structurally the same as handler but with a different interface name). A proxy component thus imports two handle functions and can statically dispatch HTTP requests to either one and forward responses from either one. The distinct handler and origin names allow a WAC user to easily create a middleware chain with side requests.

I'm not especially wed to the name service, so alternative suggestions are welcome, but I kinda like the idea that a component targeting wasi:http/service is a sort of ultra-minimal (serverless) microservice. Moreover, I can see wasi:http/service being included by other bigger service worlds (e.g. wasi:cloud/service).

Thoughts?

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading the wasi:http/proxy proposal and the linked proxy-wasm and RFC 9110 references. Review the comment discussion before changing the proposed service, proxy, and origin worlds or their handle interfaces. Done requires an accepted design for distinguishing chain requests from side requests, including settled naming and interface structure.

Written by the indexing model from the issue text.

Assessment

Tech stack
wasm
Domain
api, backend-api-design
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.