-
Notifications
You must be signed in to change notification settings - Fork 32
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 include
d by other bigger service
worlds (e.g. wasi:cloud/service
).
Thoughts?