@override limitations on Apollo Federation 2.7

hi all! I’m currently working on a Apollo federated supergraph with many subgraphs.

I need to build a subgraph that @overrides a bunch of a legacy subgraph queries and mutations.

I’m looking for some additional control on top of this @override directive, where I can pass in a flag for a single client test via custom header or an input. Can anyone help out in this regard?

Hello :waving_hand:

You should be able to achieve this with progressive @overrides and a custom Rhai script / coprocessor. In your custom script you would then evaluate the header and calculate the appropriate value for the override label (true/false).

Thanks,
Derek

1 Like

thank you so much for the quick reply! this looks exactly like what I need and I have a prototype ready for testing soon. pinging back here if it works out OK!

cheers

@dkuc I arrived at this solution but I’m not 100% on my rhai chops quite yet.
Basically, I’d like it so that whenever x-use-override header set to true is present, the @override directive is triggered. Otherwise I want @override to be completely ignored and resolve in the original subgraph.

fn configure_overrides(service) {
    service.map_request(|request| {
        let unresolved_labels = request.context["apollo_override::unresolved_labels"];
        if unresolved_labels != () {
            let labels_to_override = {};
            if request.headers.contains("x-use-override {
                let header_value = request.headers["x-use-override"];
                if header_value == "true" {
                    for label in unresolved_labels {
                        labels_to_override[label] = true;
                    }
                    log_info(`enabling overrides for labels: ${unresolved_labels}`);
                }
            }
            request.context["apollo_override::labels_to_override"] = labels_to_override;
        }
    });
}

there’s definitely an issue around map. here’s what’s popping up in our observability:

map_request callback failed: ErrorDetails {
status: 500,
message: Some(
"rhai execution error: 'Function not found: anon$f75adada35b9b3dc'",
),
position: None,
body: None,
}

Is there a sane way to test this locally? I’ve experimented with a solution involving mocking these request objects but I’m not too sure yet. I appreciate pointing out any red flags with this code in the meantime.

You are missing end quote here. Unsure where the original error comes from though.

Take a look at rhai-test for an experimental CLI tool that might help you with testing out your script.

1 Like

Whoops, sorry. I’ve edited the script as I pasted in a CMD+Z’d version. main thing I’m not sure of is the true block - would setting labels_to_override[label] to true here cut it?

Based on the router customization Rhai reference docs, I see these two as potential hooks for this:

  • apollo::progressive_override::labels_to_override: used in progressive override, list of labels for which we need an override
  • apollo::progressive_override::unresolved_labels: used in progressive override, contains the list of unresolved labels

Here’s the full script as is that replicated that error. I want to bypass @override entirely whenever that header is set to false. But upon further examination I think this approach is liable to fail. Is it possible with rhai scripting alone or do I need to look into co-processor examples?

fn configure_overrides(service) {
    service.map_request(|request| {
        let unresolved_labels = request.context["apollo_override::unresolved_labels"];
        if unresolved_labels != () {
            let labels_to_override = #{};
            if request.headers.contains("x-use-override") {
                let header_value = request.headers["x-use-override"];
                if header_value == "true" {
                    for label in unresolved_labels {
                        labels_to_override[label] = true;
                    }
                    log_info(`enabling overrides for labels: ${unresolved_labels}`);
                }
            }
            request.context["apollo_override::labels_to_override"] = labels_to_override;
        }
    });
}

You definitely should be able to do it through rhai script. Based on the docs and the code, labels_to_override should be a vec of strings and it should work (i.e. if label is set then we’ll do override, otherwise we’ll fallback to default no override).