Docs
Launch GraphOS Studio

Apollo Router customizations

Extend your router with custom functionality


You can create customizations for the to add functionality that isn't available via built-in configuration options. For example, you can make an external call to fetch authentication data for each incoming request.

Customization types

The Apollo Router supports the following customization types:

Because Rhai scripts are easier to deploy, we recommend using them if they support your use case. Use external co-processing if your customization needs to do any of the following (which Rhai scripts don't support):

  • Read or write to disk
  • Make network requests
  • Use libraries from a particular language or framework

The request lifecycle

Customizations intervene at specific points of the request lifecycle, depending on the task you want to perform. Each point is represented by a specific service with its own request and response objects.

request
request
response
response
Your infrastructure
subgraph A
subgraph B
subgraph C
Apollo Router
request
request
request
response
response
response
Router
Service
Supergraph
Service
Execution
Service
Subgraph
Service
Client

Each service can have a set of plugins. For requests, the router executes plugins before the service.

Service
request
request
request
request
Core
service
Plugin 2
Plugin 1
Client
Next service

For responses, the router executes the plugins after the service.

Service
response
response
response
response
Plugin 1
Plugin 2
Core
service
Client
Next service

Each request and response object contains a Context object, which is carried throughout the entire process. Each request's Context object is unique. You can use it to store plugin-specific information between the request and response or to communicate between different hook points. (A plugin can be called at multiple steps of the request lifecycle.)

The following flowcharts diagram the entire request lifecycle. The first details the path of a request from a client, through the parts of the Apollo Router, all the way to your . The second details the path of a response from your subgraphs back to the client.

Request path

Apollo Router
Subgraph Services
1. HTTP request
2. RouterRequest
3. SupergraphRequest
4. Query
5. Query plan
6. ExecutionRequest
7a. SubgraphRequest
7b. SubgraphRequest
8a. HTTP request
8b. HTTP request
HTTP server
Router Service
Router plugins
Execution Service
Execution plugins
Subgraph Service A
Subgraph plugins
Subgraph Service B
Subgraph plugins
Supergraph Service
Supergraph plugins
Query Planner
Client
Subgraph A
Subgraph B

  1. The router receives a client request at an HTTP server.
  2. The HTTP server transforms the HTTP request into a RouterRequest containing HTTP headers and the request body as a stream of byte arrays.
  3. The router service receives the RouterRequest. It handles (), parses the request from JSON, and calls the service with the resulting SupergraphRequest.
  4. The supergraph service calls the with the GraphQL query from the SupergraphRequest.
  5. The query planner returns a query plan for most efficiently executing the query.
  6. The supergraph service calls the execution service with an ExecutionRequest, made up of SupergraphRequest and the .
  7. For each fetch node of the query plan, the execution service creates a SubgraphRequest and then calls the respective service.
  8. Each subgraph has its own subgraph service, and each service can have its own subgraph plugin configuration. The subgraph service transforms the SubgraphRequest into an HTTP request to its subgraph. The SubgraphRequest contains:
    • the (read-only) SupergraphRequest
    • HTTP headers
    • the subgraph request's type (, , or )
    • a GraphQL request object as the request body

Once your subgraphs provide a response, the response follows the path outlined below.

Response path

Subgraph Services
14. HTTP response
9a. HTTP response
9b. HTTP response
10a. SubgraphResponse
10b. SubgraphResponse
11. ExecutionResponse
12. SupergraphResponse
13. RouterResponse
HTTP server
Router Service
Router plugins
Execution Service
Execution plugins
Subgraph Service A
Subgraph plugins
Subgraph Service B
Subgraph plugins
Supergraph Service
Supergraph plugins
QueryPlanner
Client
Subgraph A
Subgraph B

  1. Each subgraph provides an HTTP response to the subgraph services.
  2. Each subgraph service creates a SubgraphResponse containing the HTTP headers and a GraphQL response.
  3. Once the execution service has received all subgraph responses, it formats the GraphQL responses—removing unneeded data and propagating nulls—before sending it back to the supergraph plugin as the ExecutionResponse.
  4. The SupergraphResponse has the same content as the ExecutionResponse. It contains headers and a stream of GraphQL responses. That stream only contains one element for most queries—it can contain more if the query uses the @defer or .
  5. The router service receives the SupergraphResponse and serializes the GraphQL responses to JSON.
  6. The HTTP server sends the JSON in an HTTP response to the client.

Request and response nuances

For simplicity's sake, the preceding diagrams show the request and response sides separately and sequentially. In reality, some requests and responses may happen simultaneously and repeatedly.

For example, SubgraphRequests can happen both in parallel and in sequence: one subgraph's response may be necessary for another's SubgraphRequest. (The query planner decides which requests can happen in parallel vs. which need to happen in sequence.)

Requests run in parallel

Subgraph Services
1A. SubgraphRequest
1B. SubgraphRequest
4A. SubgraphResponse
4B. SubgraphResponse
2A. HTTP request
2B. HTTP request
3A. HTTP response
3B. HTTP response
Execution Service
Execution plugins
Subgraph Service A
Subgraph plugins
Subgraph Service B
Subgraph plugins
Subgraph A
Subgraph B

Requests run sequentially

Subgraph Services
1. SubgraphRequest
4. SubgraphResponse
5. SubgraphRequest
8. SubgraphResponse
2. HTTP request
6. HTTP request
3. HTTP response
7. HTTP response
Execution Service
Execution plugins
Subgraph Service A
Subgraph plugins
Subgraph Service B
Subgraph plugins
Subgraph A
Subgraph B

Additionally, some requests and responses may happen multiple times for the same operation. With subscriptions, for example, a subgraph sends a new SubgraphResponse whenever data is updated. Each response object travels through all the services in the response path and interacts with any customizations you've created.

Request and Response buffering

The router expects to execute on a stream of data. In order to work correctly and provide high performance, the following expectations must be met:

  • Request Path: No buffering before the end of the router_service processing step
  • Response Path: No buffering

In general, it's best to avoid buffering where possible. If necessary, it is ok to do so on the request path once the router_service step is complete.

This guidance applies if you are:

  • Modifying the router
  • Creating a native Rust plugin
  • Creating a custom binary

Customization creation

To learn how to hook in to the various lifecycle stages, including examples customizations, refer to the Rhai scripts and external coprocessing docs.

Previous
Health checks
Next
Rhai scripts
Edit on GitHubEditForumsDiscord

© 2024 Apollo Graph Inc.

Privacy Policy

Company