router
router copied to clipboard
proposal: create a `dev` plugin
after talking with @BrynCooke this morning, we have come up with a potential development workflow that could work for any router running anywhere (without tunnels).
the idea goes something like this:
- acme-corp has infrastructure for "dev" subgraphs, say
products,films, andusers. they all have dev databases and servers backed by heroku. - acme-corp has published these subgraphs to Apollo Studio and associated them with the
acme-corp@devgraph variant - acme-corp has a router deployed to
https://dev.acmecorp.comwith the dev plugin enabled, and this endpoint is stored in the "connection settings" for a graph ref - mara want to make a change to the
productssubgraph - mara goes to the
productssubgraph on her local machine, and runsrover dev acme-corp@dev --name products --schema ./products.graphql --url http://localhost:4001 rover devrequests a session ID fromhttps://dev.acmecorp.com, which is auto-generated by the dev pluginrover devconnects to the dev router via a websocket connection, which it initializes by sending the session IDrover devsends theproductssubgraph definition (name, url, sdl) to the dev router over the websocket- the dev router receives the incoming subgraph definition over the websocket, and creates an "alternative" supergraph schema associated with the session ID
- if composition succeeds, the router sends an "ok ready" message over the websocket, if it fails, it sends the composition error over the websocket
- the router starts to listen for incoming requests that include an
X-Apollo-Dev-Session-IDheader. - once
rover devhas received the "ok ready", it spins up a local proxy server athttp://localhost:3000 - this proxy server sends all incoming requests to
https://dev.acmecorp.comalong with the session ID - any time the router receives an incoming request with a session ID header, it executes a query plan using the supergraph schema for that session
- the query planner itself may need to route requests to the local machine, in this scenario, the request payload should be sent over the websocket to
rover devwhich will pass along the request to the subgraph - the local subgraph resolves incoming requests from the query planner, and
rover devreturns a regular HTTP response to the request coming from the query planner - the router receives the subgraph response, and aggregates its data along with the data received from the other deployed dev subgraphs, which it then sends back as the HTTP response to the initial HTTP request
rover devwill watch the local subgraph for any changes, and if they are found it will send the subgraph definition over the websocket again, requiring the router dev session to recompose and reload- if another
rover devsession is established with the same graph ref on a different machine, a new dev session id is created for it - if you run another
rover devsession on the same machine with the same graph ref, it will start sending its own subgraph updates on the same websocket connection as the first session - if you start a session on one machine and note the session ID, you can run
rover devon a completely different machine with a--session-id, which will start sending its own subgraph updates on the same websocket connection as the first session
re: implementation details, this could be a router plugin or it could be a sidecar. i imagine the sidecar would be something like rover supergraph dev which would take care of re-composing from the incoming subgraph definitions.
i do not think we should have the subgraph developer session in charge of composition as it will require much larger messages over the wire, and selecting a composition version would be up to the subgraph developer (or the version would also need to be sent over the wire).
co-locating the composer with the router also allows us to create dev "sessions" that can be attached to from multiple different machines.
i've just updated the top-level comment to interface more directly with apollo studio, but i don't think it changes the implementation of the router dev plugin at all.
closing: taking a different approach