forked from apollographql/router
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
uses cache-control headers from subgraphs to determine an overall cache-control policy partially addresses apollographql#326
- Loading branch information
1 parent
c851bc4
commit 21e94d9
Showing
14 changed files
with
306 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
[package] | ||
name = "cache-control" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
[dependencies] | ||
anyhow = "1" | ||
apollo-router = { path = "../../../apollo-router" } | ||
http = "0.2" | ||
serde_json = "1" | ||
tokio = { version = "1", features = ["full"] } | ||
tower = { version = "0.4", features = ["full"] } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# Rhai script | ||
|
||
Demonstrates header and context manipulation via Rhai script. | ||
|
||
Usage: | ||
|
||
```bash | ||
cargo run -- -s ../../graphql/supergraph.graphql -c ./router.yaml | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
rhai: | ||
scripts: src | ||
main: cache_control.rhai |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
fn subgraph_service(service, subgraph) { | ||
// collect the max-age and scope values from cache-control headers and store | ||
// on the context for use in supergraph_service | ||
service.map_response(|response| { | ||
let cache_control = response.headers.values("cache-control").get(0); | ||
|
||
// if a subgraph response is uncacheable, the whole response is uncacheable | ||
if cache_control == () { | ||
response.context.cache_control_uncacheable = true; | ||
return; | ||
} | ||
|
||
let max_age = get_max_age(cache_control); | ||
|
||
// use the smallest max age | ||
response.context.upsert("cache_control_max_age", |current| { | ||
if current == () { | ||
max_age | ||
} else if max_age < current { | ||
max_age | ||
} else { | ||
current | ||
} | ||
}); | ||
|
||
let scope = if cache_control.contains("public") { | ||
"public" | ||
} else { | ||
"private" | ||
}; | ||
|
||
// if the scope is ever private, it cannot become public | ||
response.context.upsert("cache_control_scope", |current| { | ||
if current == "private" || scope == "private" { | ||
"private" | ||
} else { | ||
scope | ||
} | ||
}); | ||
}); | ||
} | ||
|
||
fn supergraph_service(service) { | ||
// attach the cache-control header if enough data is available | ||
service.map_response(|response| { | ||
let uncacheable = response.context.cache_control_uncacheable; | ||
let max_age = response.context.cache_control_max_age; | ||
let scope = response.context.cache_control_scope; | ||
|
||
if uncacheable != true && max_age != () && scope != () { | ||
response.headers["cache-control"] = `max-age=${max_age}, ${scope}`; | ||
} | ||
}); | ||
} | ||
|
||
// find the the max-age= part and parse the value into an integer | ||
fn get_max_age(str) { | ||
let max_age = 0; | ||
|
||
for part in str.split(",") { | ||
part.remove(" "); | ||
|
||
if part.starts_with("max-age=") { | ||
let num = part.split("=").get(1); | ||
|
||
if num == () || num == "" { | ||
break; | ||
} | ||
|
||
try { | ||
max_age = num.parse_int(); | ||
} catch (err) { | ||
log_error(`error parsing max-age from "${str}": ${err}`); | ||
} | ||
break; | ||
} | ||
} | ||
|
||
max_age | ||
} |
Oops, something went wrong.