Skip to content

Commit

Permalink
Merge branch 'main' into geal/clean-up-dedup-on-cancel
Browse files Browse the repository at this point in the history
  • Loading branch information
Geoffroy Couprie committed Apr 1, 2022
2 parents 9173793 + d57b821 commit c7264a9
Show file tree
Hide file tree
Showing 38 changed files with 499 additions and 92 deletions.
28 changes: 24 additions & 4 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ parameters:
cache_version:
type: string
# increment that one to invalidate all the caches
default: v8-{{ checksum "rust-toolchain.toml" }}
default: v1-{{ checksum "rust-toolchain.toml" }}

commands:
initialize_submodules:
Expand Down Expand Up @@ -249,9 +249,11 @@ commands:
build_all_permutations:
steps:
- build_common_permutations
- rust/build:
with_cache: false
crate: --locked --no-default-features -p apollo-router -p apollo-router-core
- run:
name: cargo check workspace and benchmarks
command: |
set -e -o pipefail
cargo check --locked --all --benches
build_workspace:
parameters:
os:
Expand Down Expand Up @@ -647,6 +649,24 @@ jobs:
- run:
command: >
gh release create $VERSION --notes-file CHANGELOG.md --title $VERSION artifacts/*
- setup_remote_docker:
version: 20.10.11
docker_layer_caching: true
- run:
name: Docker build
command: |
ROUTER_RELEASE=${VERSION:1}
ROUTER_TAG=ghcr.io/apollographql/router
# Build debug image
docker build --build-arg ROUTER_RELEASE=${ROUTER_RELEASE} --build-arg DEBUG_IMAGE=":debug" -f dockerfiles/Dockerfile.router -t ${ROUTER_TAG}:v${ROUTER_RELEASE}-debug .
# Build release image
docker build --build-arg ROUTER_RELEASE=${ROUTER_RELEASE} -f dockerfiles/Dockerfile.router -t ${ROUTER_TAG}:${VERSION} .
# NB: GH token expires 30/3/2023
echo ${GITHUB_DOCKER_TOKEN} | docker login ghcr.io -u garypen --password-stdin
# Push debug image
docker push ${ROUTER_TAG}:${VERSION}-debug
# Push release image
docker push ${ROUTER_TAG}:${VERSION}
workflows:
ci_checks:
Expand Down
45 changes: 38 additions & 7 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,36 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
-->

<!--# [v0.1.0-preview.2] (unreleased) - 2022-mm-dd
# [v0.1.0-preview.2] - 2022-04-01
## ❗ BREAKING ❗

- **CORS default Configuration** ([#40](https://github.com/apollographql/router/issues/40))

The Router will allow only the https://studio.apollographql.com origin by default, instead of any origin.
This behavior can still be tweaked in the [YAML configuration](https://www.apollographql.com/docs/router/configuration/cors)

- **Hot reload flag** ([766](https://github.com/apollographql/router/issues/766))
The `--watch` (or `-w`) flag that enables hot reload was renamed to `--hr` or `--hot-reload`

## 🚀 Features

- **Hot reload via en environment variable** ([766](https://github.com/apollographql/router/issues/766))
You can now use the `ROUTER_HOT_RELOAD=true` environment variable to have the router watch for configuration and schema changes and automatically reload.

- **Container images are now available** ([PR #764](https://github.com/apollographql/router/pull/764))

We now build container images More details at:
https://github.com/apollographql/router/pkgs/container/router

You can use the images with docker, for example, as follows:
e.g.: docker pull ghcr.io/apollographql/router:v0.1.0-preview.1

The images are based on [distroless](https://github.com/GoogleContainerTools/distroless) which is a very constrained image, intended to be secure and small.

We'll provide release and debug images for each release. The debug image has a busybox shell which can be accessed using (for instance) `--entrypoint=sh`.

For more details about these images, see the docs.

- **Skip and Include directives in post processing** ([PR #626](https://github.com/apollographql/router/pull/626))

The Router now understands the [@skip](https://spec.graphql.org/October2021/#sec--skip) and [@include](https://spec.graphql.org/October2021/#sec--include) directives in queries, to add or remove fields depending on variables. It works in post processing, by filtering fields after aggregating the subgraph responses.
Expand All @@ -32,17 +58,22 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm

While schema introspection is useful in development, we might not want to expose the entire schema in production,
so the router can be configured to forbid introspection queries as follows:
```yaml
server:
introspection: false
```
```yaml
server:
introspection: false
```
## 🐛 Fixes
- **Move query dedup to an experimental `traffic_shaping` plugin** ([PR #753](https://github.com/apollographql/router/pull/753))

The experimental `traffic_shaping` plugin will be a central location where we can add things such as rate limiting and retry.

- **Remove `hasNext` from our response objects** ([PR #733](https://github.com/apollographql/router/pull/733))

`hasNext` is a field in the response that may be used in future to support features such as defer and stream. However, we are some way off supporting this and including it now may break clients. It has been removed.

- **Extend Apollo uplink configurability** ([PR #741](https://github.com/apollographql/router/pull/741))

Uplink url and poll interval can now be configured via command line arg and env variable:
```bash
--apollo-schema-config-delivery-endpoint <apollo-schema-config-delivery-endpoint>
Expand All @@ -59,12 +90,12 @@ server:

- **Relax variables selection for subgraph queries** ([PR #755](https://github.com/apollographql/router/pull/755))

federated subgraph queries relying on partial or invalid data from previous subgraph queries could result in response failures or empty subgraph queries. The router is now more flexible when selecting data from previous queries, while still keeping a correct form for the final response
Federated subgraph queries relying on partial or invalid data from previous subgraph queries could result in response failures or empty subgraph queries. The router is now more flexible when selecting data from previous queries, while still keeping a correct form for the final response

## 🛠 Maintenance
## 📚 Documentation

# [v0.1.0-preview.1] - 2022-03-23
<!--# [v0.1.0-preview.1] - 2022-03-23

## 🎉 **The Apollo Router has graduated to its Preview phase!** 🎉
## ❗ BREAKING ❗
Expand Down
22 changes: 11 additions & 11 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ directory.
OPTIONS:
-c, --config <configuration-path> Configuration file location
-s, --supergraph <supergraph-path> Supergraph Schema location
-w, --watch Watches for changes in the supergraph and configuration file
--hr, --hot-reload Watches for changes in the supergraph and configuration file
--schema Prints out a JSON schema of the configuration file
```

Expand Down
2 changes: 1 addition & 1 deletion apollo-router-benchmarks/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "apollo-router-benchmarks"
version = "0.1.0-preview.1"
version = "0.1.0-preview.2"
authors = ["Apollo Graph, Inc. <packages@apollographql.com>"]
edition = "2021"
license = "LicenseRef-ELv2"
Expand Down
2 changes: 1 addition & 1 deletion apollo-router-core/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "apollo-router-core"
version = "0.1.0-preview.1"
version = "0.1.0-preview.2"
authors = ["Apollo Graph, Inc. <packages@apollographql.com>"]
edition = "2021"
license-file = "./LICENSE"
Expand Down
1 change: 1 addition & 0 deletions apollo-router-core/src/layers/deduplication.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use tokio::sync::{
};
use tower::{BoxError, Layer, ServiceExt};

#[derive(Default)]
pub struct QueryDeduplicationLayer;

impl<S> Layer<S> for QueryDeduplicationLayer
Expand Down
1 change: 1 addition & 0 deletions apollo-router-core/src/plugins/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
mod forbid_mutations;
mod headers;
mod traffic_shaping;
119 changes: 119 additions & 0 deletions apollo-router-core/src/plugins/traffic_shaping.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
use std::collections::HashMap;

use schemars::JsonSchema;
use serde::Deserialize;
use tower::util::BoxService;
use tower::{BoxError, ServiceBuilder, ServiceExt};

use crate::deduplication::QueryDeduplicationLayer;
use crate::plugin::Plugin;
use crate::{register_plugin, SubgraphRequest, SubgraphResponse};

#[derive(PartialEq, Debug, Clone, Deserialize, JsonSchema)]
struct Shaping {
dedup: Option<bool>,
}

impl Shaping {
fn merge(&self, fallback: Option<&Shaping>) -> Shaping {
match fallback {
None => self.clone(),
Some(fallback) => Shaping {
dedup: self.dedup.or(fallback.dedup),
},
}
}
}

#[derive(PartialEq, Debug, Clone, Deserialize, JsonSchema)]
struct Config {
#[serde(default)]
all: Option<Shaping>,
#[serde(default)]
subgraphs: HashMap<String, Shaping>,
}

struct TrafficShaping {
config: Config,
}

#[async_trait::async_trait]
impl Plugin for TrafficShaping {
type Config = Config;

fn new(config: Self::Config) -> Result<Self, BoxError> {
Ok(Self { config })
}

fn subgraph_service(
&mut self,
name: &str,
service: BoxService<SubgraphRequest, SubgraphResponse, BoxError>,
) -> BoxService<SubgraphRequest, SubgraphResponse, BoxError> {
// Either we have the subgraph config and we merge it with the all config, or we just have the all config or we have nothing.
let all_config = self.config.all.as_ref();
let subgraph_config = self.config.subgraphs.get(name);
let final_config = Self::merge_config(all_config, subgraph_config);

if let Some(config) = final_config {
ServiceBuilder::new()
.option_layer(config.dedup.unwrap_or_default().then(|| {
//Buffer is required because dedup layer requires a clone service.
ServiceBuilder::new()
.layer(QueryDeduplicationLayer::default())
.buffer(20_000)
}))
.service(service)
.boxed()
} else {
service
}
}
}

impl TrafficShaping {
fn merge_config(
all_config: Option<&Shaping>,
subgraph_config: Option<&Shaping>,
) -> Option<Shaping> {
let merged_subgraph_config = subgraph_config.map(|c| c.merge(all_config));
merged_subgraph_config.or_else(|| all_config.cloned())
}
}

register_plugin!("experimental", "traffic_shaping", TrafficShaping);

#[cfg(test)]
mod test {
use super::*;

#[test]
fn test_merge_config() {
let config = serde_yaml::from_str::<Config>(
r#"
all:
dedup: true
subgraphs:
products:
dedup: false
"#,
)
.unwrap();

assert_eq!(TrafficShaping::merge_config(None, None), None);
assert_eq!(
TrafficShaping::merge_config(config.all.as_ref(), None),
config.all
);
assert_eq!(
TrafficShaping::merge_config(config.all.as_ref(), config.subgraphs.get("products"))
.as_ref(),
config.subgraphs.get("products")
);

assert_eq!(
TrafficShaping::merge_config(None, config.subgraphs.get("products")).as_ref(),
config.subgraphs.get("products")
);
}
}
2 changes: 1 addition & 1 deletion apollo-router/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "apollo-router"
version = "0.1.0-preview.1"
version = "0.1.0-preview.2"
authors = ["Apollo Graph, Inc. <packages@apollographql.com>"]
edition = "2021"
license-file = "./LICENSE"
Expand Down
Loading

0 comments on commit c7264a9

Please sign in to comment.