apollographql / router

A configurable, high-performance routing runtime for Apollo Federation 🚀
https://www.apollographql.com/docs/router/
Other
807 stars 272 forks source link

Send response errors only to coprocessor #5020

Open smyrick opened 6 months ago

smyrick commented 6 months ago

Is your feature request related to a problem? Please describe.**

Today I can configure the Router to send the response, which might have data or errors or extensions, to the coprocessor so that it can perform extra logic. However I can only choose to send the whole response body. If I am returning data back this body may be quite large and can cause performance issues or even errors inside my coprocessor trying to process large responses.

Instead I would like the ability to decide what parts of the GraphQL response I would like sent to a coprocessor.

Config today

coprocessor:
  url: http://127.0.0.1:8081
  supergraph:
    response:
      body: true

Describe the solution you'd like**

I would like the ability to decide what parts of the GraphQL response I would like sent to a coprocessor, so I can reduce the payload size.

It probably makes sense for this to be at the SupergraphResponse phase since that is where the Request is also in a parsed state vs the RouterResponse should be reserved for changing the entire response as it is about to be sent via HTTP back to the client

Note: We should include support for data, errors, and extensions separately

Possible new config:

coprocessor:
  url: http://127.0.0.1:8081
  supergraph:
    response:
      body_data: false
      body_errors: true
      body_extensions: true

Describe alternatives you've considered**

I could use Rhai scripts to process particular parts of the response

Additional context

Actually having a large payload can cause the coprocessor to fail which is a separate issue, so this feature request is one way in which we can solve that

glasser commented 3 months ago

Maybe:

coprocessor:
  url: http://127.0.0.1:8081
  supergraph:
    response:
      body:  # if this is provided as an object, then sub-fields are false by default, eg data
        errors: true
        extensions: true
glasser commented 3 months ago

Note that we are also interested in this for subgraph response.

One question would be to define what body in the coprocessor response means. I believe right now if you send back a body field it will fully overwrite the body. What would the expected semantics of sending back {body: {errors: [...]}} be with the config above: would the idea be that since you didn't ask for data, the lack of mentioning data means you want to leave it alone? Or should it mean to remove it? Is the answer perhaps different between a continue and a break?

smyrick commented 3 months ago

I would assume you would only mutate what was sent to the coprocessor. If you wanted to change the data you should have to send the data, but this also maybe would require more conditional logic? Like maybe I only want to change the data if there was an error.

Actually then maybe the break could be used so you only send errors to the CP but the CP can respond with the full new response on break

glasser commented 3 months ago

Yeah, the semantics are a bit funky too because body in a coproc means something different for continue vs break: for continue it means "overwrite the body of whatever I'm processing (which might be a request or a response)" whereas for break it means "use this as the body for a response to send back now"...