Skip to content

Commit 4d74880

Browse files
authored
Add the ability to use $args and $this in headers (#6193)
1 parent 82e262b commit 4d74880

File tree

4 files changed

+71
-4
lines changed

4 files changed

+71
-4
lines changed

apollo-federation/src/sources/connect/header.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,12 @@ fn identifier(input: &str) -> IResult<&str, &str> {
113113
}
114114

115115
fn namespace(input: &str) -> IResult<&str, &str> {
116-
recognize(alt((tag("$config"), tag("$context"))))(input)
116+
recognize(alt((
117+
tag("$args"),
118+
tag("$config"),
119+
tag("$context"),
120+
tag("$this"),
121+
)))(input)
117122
}
118123

119124
fn path(input: &str) -> IResult<&str, &str> {

apollo-router/src/plugins/connectors/testdata/steelthread.graphql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ type Query
7373
{
7474
users: [User] @join__field(graph: CONNECTORS) @join__directive(graphs: [CONNECTORS], name: "connect", args: {source: "json", http: {GET: "/users", headers: [{name: "x-new-name", from: "x-rename-connect"}, {name: "x-insert-multi-value", value: "first,second"}, {name: "x-config-variable-connect", value: "before {$config.connect.val} after"}, {name: "x-context-value-connect", value: "before {$context.val} after"}]}, selection: "id name"})
7575
me: User @join__field(graph: CONNECTORS) @join__directive(graphs: [CONNECTORS], name: "connect", args: {source: "json", http: {GET: "/users/{$config.id}"}, selection: "id\nname\nusername"})
76-
user(id: ID!): User @join__field(graph: CONNECTORS) @join__directive(graphs: [CONNECTORS], name: "connect", args: {source: "json", http: {GET: "/users/{$args.id}"}, selection: "id\nname\nusername", entity: true})
76+
user(id: ID!): User @join__field(graph: CONNECTORS) @join__directive(graphs: [CONNECTORS], name: "connect", args: {source: "json", http: {GET: "/users/{$args.id}", headers: [{name: "x-from-args", value: "before {$args.id} after"}]}, selection: "id\nname\nusername", entity: true})
7777
posts: [Post] @join__field(graph: CONNECTORS) @join__directive(graphs: [CONNECTORS], name: "connect", args: {source: "json", http: {GET: "/posts"}, selection: "id title user: { id: userId }"})
7878
}
7979

@@ -84,6 +84,7 @@ type User
8484
id: ID!
8585
name: String @join__field(graph: CONNECTORS)
8686
username: String @join__field(graph: CONNECTORS)
87+
nickname: String @join__field(graph: CONNECTORS) @join__directive(graphs: [CONNECTORS], name: "connect", args: {source: "json", http: {GET: "/users/{$this.id}/nicknames", headers: [{name: "x-from-this", value: "before {$this.id} after"}]}, selection: "nickname: $.first"})
8788
c: String @join__field(graph: CONNECTORS, external: true) @join__field(graph: GRAPHQL)
8889
d: String @join__field(graph: CONNECTORS, requires: "c") @join__directive(graphs: [CONNECTORS], name: "connect", args: {source: "json", http: {GET: "/users/{$this.c}"}, selection: "$.phone"})
8990
}

apollo-router/src/plugins/connectors/testdata/steelthread.yaml

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# rover supergraph compose --config apollo-router/src/plugins/connectors/testdata/steelthread.yaml > apollo-router/src/plugins/connectors/testdata/steelthread.graphql
2-
federation_version: =2.10.0-alpha.0
2+
federation_version: =2.10.0-preview.0
33
subgraphs:
44
connectors:
55
routing_url: none
@@ -57,7 +57,12 @@ subgraphs:
5757
user(id: ID!): User
5858
@connect(
5959
source: "json"
60-
http: { GET: "/users/{$$args.id}" }
60+
http: {
61+
GET: "/users/{$$args.id}"
62+
headers: [
63+
{name: "x-from-args" value: "before {$$args.id} after"}
64+
]
65+
}
6166
selection: """
6267
id
6368
name
@@ -78,6 +83,17 @@ subgraphs:
7883
id: ID!
7984
name: String
8085
username: String
86+
nickname: String
87+
@connect(
88+
source: "json"
89+
http: {
90+
GET: "/users/{$$this.id}/nicknames"
91+
headers: [
92+
{name: "x-from-this" value: "before {$$this.id} after"}
93+
]
94+
}
95+
selection: "$.first"
96+
)
8197
c: String @external
8298
d: String
8399
@requires(fields: "c")

apollo-router/src/plugins/connectors/tests.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,12 @@ pub(crate) mod mock_api {
8484
)
8585
}
8686

87+
pub(crate) fn user_2_nicknames() -> Mock {
88+
Mock::given(method("GET"))
89+
.and(path("/users/2/nicknames"))
90+
.respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!(["cat"])))
91+
}
92+
8793
pub(crate) fn users_error() -> Mock {
8894
Mock::given(method("GET")).and(path("/users")).respond_with(
8995
ResponseTemplate::new(404).set_body_json(serde_json::json!([
@@ -668,6 +674,45 @@ async fn test_headers() {
668674
);
669675
}
670676

677+
#[tokio::test]
678+
async fn test_args_and_this_in_header() {
679+
let mock_server = MockServer::start().await;
680+
mock_api::user_2().mount(&mock_server).await;
681+
mock_api::user_2_nicknames().mount(&mock_server).await;
682+
683+
execute(
684+
STEEL_THREAD_SCHEMA,
685+
&mock_server.uri(),
686+
"query { user(id: 2){ id nickname } }",
687+
Default::default(),
688+
None,
689+
|_| {},
690+
)
691+
.await;
692+
693+
req_asserts::matches(
694+
&mock_server.received_requests().await.unwrap(),
695+
vec![
696+
Matcher::new()
697+
.method("GET")
698+
.header(
699+
HeaderName::from_str("x-from-args").unwrap(),
700+
HeaderValue::from_str("before 2 after").unwrap(),
701+
)
702+
.path("/users/2")
703+
.build(),
704+
Matcher::new()
705+
.method("GET")
706+
.header(
707+
HeaderName::from_str("x-from-this").unwrap(),
708+
HeaderValue::from_str("before 2 after").unwrap(),
709+
)
710+
.path("/users/2/nicknames")
711+
.build(),
712+
],
713+
);
714+
}
715+
671716
mock! {
672717
Subscriber {}
673718
impl tracing_core::Subscriber for Subscriber {

0 commit comments

Comments
 (0)