Skip to content

Commit

Permalink
Merge branch 'main' into add-build-tag
Browse files Browse the repository at this point in the history
  • Loading branch information
alankritdabral authored Mar 14, 2024
2 parents 9334211 + f5e0fa4 commit d224a14
Show file tree
Hide file tree
Showing 34 changed files with 866 additions and 85 deletions.
416 changes: 380 additions & 36 deletions Cargo.lock

Large diffs are not rendered by default.

8 changes: 7 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ moka = { version = "0.12.5", default-features = false, features = [
"future",
], optional = true }
hyper-rustls = { version = "0.25.0", optional = true }
rustls = { version = "0.23.1", optional = true, features = ["std"], default-features = false }
rustls = { version = "0.23.2", optional = true, features = ["std"], default-features = false }
rustls-pki-types = "1.3.1"
inquire = { version = "0.7.1", optional = true }
opentelemetry-otlp = { version = "0.15.0", features = [
Expand Down Expand Up @@ -123,6 +123,12 @@ opentelemetry-appender-tracing = { version = "0.3.0" }
opentelemetry-prometheus = "0.15.0"
phonenumber = "0.3.3"
chrono = "0.4.35"
async-graphql-extension-apollo-tracing = { git = "https://github.com/tailcallhq/async_graphql_apollo_studio_extension/" }

[patch.crates-io]
# TODO: update this once https://github.com/haixuanTao/opentelemetry-system-metrics/pull/2 gets merged
async-graphql-value = {git ="https://github.com/tusharmath/async-graphql.git", branch = "add-setter"}
async-graphql = {git ="https://github.com/tusharmath/async-graphql.git", branch = "add-setter"}

[dev-dependencies]
criterion = "0.5.1"
Expand Down
1 change: 1 addition & 0 deletions autogen/src/gen_gql_schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ static OBJECT_WHITELIST: &[&str] = &[
"OtlpExporter",
"PrometheusFormat",
"PrometheusExporter",
"Apollo",
];

#[derive(Clone, Copy)]
Expand Down
1 change: 1 addition & 0 deletions aws-lambda/src/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,6 @@ pub fn init_runtime() -> TargetRuntime {
file: init_file(),
env: init_env(),
cache: init_cache(),
extensions: Arc::new(vec![]),
}
}
1 change: 1 addition & 0 deletions benches/data_loader_bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ fn benchmark_data_loader(c: &mut Criterion) {
env: Arc::new(Env {}),
file: Arc::new(File {}),
cache: Arc::new(Cache {}),
extensions: Arc::new(vec![]),
};
let loader = HttpDataLoader::new(rt, None, false);
let loader = loader.to_data_loader(Batch::default().delay(1));
Expand Down
1 change: 1 addition & 0 deletions benches/impl_path_string_for_evaluation_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ fn request_context() -> RequestContext {
env: Arc::new(Env {}),
file: Arc::new(File {}),
cache: Arc::new(InMemoryCache::new()),
extensions: Arc::new(vec![]),
};
RequestContext {
req_headers: HeaderMap::new(),
Expand Down
1 change: 1 addition & 0 deletions cloudflare/src/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,6 @@ pub fn init(env: Rc<worker::Env>) -> anyhow::Result<TargetRuntime> {
env: init_env(env.clone()),
file: init_file(env.clone(), bucket_id)?,
cache: init_cache(env),
extensions: Arc::new(vec![]),
})
}
17 changes: 17 additions & 0 deletions examples/apollo-tracing.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
schema
@server(port: 8000, graphiql: true, hostname: "0.0.0.0")
@upstream(baseURL: "http://jsonplaceholder.typicode.com")
@telemetry(export: {apollo: {apiKey: "{{env.APOLLO_KEY}}", graphRef: "{{env.APOLLO_GRAPH_REF}}"}}) {
query: Query
}

type Query @cache(maxAge: 30000) {
posts: [Post] @http(path: "/posts")
}

type Post {
id: Int!
userId: Int!
title: String!
body: String!
}
23 changes: 23 additions & 0 deletions generated/.tailcallrc.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,28 @@ directive @upstream(
userAgent: String
) on SCHEMA

input Apollo {
"""
Setting `apiKey` for Apollo.
"""
apiKey: String!
"""
Setting `graphRef` for Apollo in the format <graphId>@<variant>.
"""
graphRef: String!
"""
Setting `platform` for Apollo.
"""
platform: String!
"""
Setting `userVersion` for Apollo.
"""
userVersion: String!
"""
Setting `version` for Apollo.
"""
version: String!
}
input Batch {
delay: Int!
headers: [String!]
Expand Down Expand Up @@ -733,6 +755,7 @@ input TelemetryExporter {
stdout: StdoutExporter
otlp: OtlpExporter
prometheus: PrometheusExporter
apollo: Apollo
}
input Schema {
Obj: JSON
Expand Down
44 changes: 44 additions & 0 deletions generated/.tailcallrc.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,38 @@
}
}
},
"Apollo": {
"type": "object",
"required": [
"apiKey",
"graphRef"
],
"properties": {
"apiKey": {
"description": "Setting `apiKey` for Apollo.",
"type": "string"
},
"graphRef": {
"description": "Setting `graphRef` for Apollo in the format <graphId>@<variant>.",
"type": "string"
},
"platform": {
"description": "Setting `platform` for Apollo.",
"default": "platform",
"type": "string"
},
"userVersion": {
"description": "Setting `userVersion` for Apollo.",
"default": "1.0",
"type": "string"
},
"version": {
"description": "Setting `version` for Apollo.",
"default": "1.0",
"type": "string"
}
}
},
"Arg": {
"type": "object",
"required": [
Expand Down Expand Up @@ -1730,6 +1762,18 @@
}
},
"additionalProperties": false
},
{
"type": "object",
"required": [
"apollo"
],
"properties": {
"apollo": {
"$ref": "#/definitions/Apollo"
}
},
"additionalProperties": false
}
]
},
Expand Down
5 changes: 3 additions & 2 deletions src/app_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use async_graphql::dynamic::{self, DynamicRequest};
use async_graphql::Response;

use crate::blueprint::Type::ListType;
use crate::blueprint::{Blueprint, Definition};
use crate::blueprint::{Blueprint, Definition, SchemaModifiers};
use crate::data_loader::DataLoader;
use crate::graphql::GraphqlDataLoader;
use crate::grpc;
Expand Down Expand Up @@ -104,7 +104,8 @@ impl AppContext {
}
}

let schema = blueprint.to_schema();
let schema = blueprint
.to_schema_with(SchemaModifiers::default().extensions(runtime.extensions.clone()));

AppContext {
schema,
Expand Down
15 changes: 12 additions & 3 deletions src/blueprint/blueprint.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::collections::{BTreeSet, HashMap};
use std::sync::Arc;

use async_graphql::dynamic::{Schema, SchemaBuilder};
use async_graphql::extensions::ApolloTracing;
Expand All @@ -11,6 +12,7 @@ use super::telemetry::Telemetry;
use super::GlobalTimeout;
use crate::blueprint::{Server, Upstream};
use crate::lambda::Expression;
use crate::schema_extension::SchemaExtension;

/// Blueprint is an intermediary representation that allows us to generate
/// graphQL APIs. It can only be generated from a valid Config.
Expand Down Expand Up @@ -172,15 +174,18 @@ pub struct UnionTypeDefinition {

///
/// Controls the kind of blueprint that is generated.
#[derive(Copy, Clone, Debug, Default)]
#[derive(Clone, Default, Setters)]
pub struct SchemaModifiers {
/// If true, the generated schema will not have any resolvers.
pub no_resolver: bool,
/// List of extensions to add to the schema.
pub extensions: Arc<Vec<SchemaExtension>>,
}

impl SchemaModifiers {
pub fn no_resolver() -> Self {
Self { no_resolver: true }
pub fn with_no_resolver(mut self) -> Self {
self.no_resolver = true;
self
}
}

Expand Down Expand Up @@ -244,6 +249,10 @@ impl Blueprint {
schema = schema.disable_introspection();
}

for extension in schema_modifiers.extensions.iter().cloned() {
schema = schema.extension(extension);
}

// We should safely assume the blueprint is correct and,
// generation of schema cannot fail.
schema.finish().unwrap()
Expand Down
2 changes: 1 addition & 1 deletion src/blueprint/operation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ pub async fn validate_operations(
blueprint: &Blueprint,
operations: Vec<OperationQuery>,
) -> Valid<(), String> {
let schema = blueprint.to_schema_with(SchemaModifiers::no_resolver());
let schema = blueprint.to_schema_with(SchemaModifiers::default().with_no_resolver());
Valid::from_iter(
futures_util::future::join_all(operations.iter().map(|op| op.validate(&schema)))
.await
Expand Down
68 changes: 47 additions & 21 deletions src/blueprint/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,27 +113,32 @@ impl TryFrom<crate::config::ConfigModule> for Server {
(config_server).get_response_headers(),
))
.fuse(to_script(&config_module))
.map(|(hostname, http, response_headers, script)| Server {
enable_apollo_tracing: (config_server).enable_apollo_tracing(),
enable_cache_control_header: (config_server).enable_cache_control(),
enable_set_cookie_header: (config_server).enable_set_cookies(),
enable_graphiql: (config_server).enable_graphiql(),
enable_introspection: (config_server).enable_introspection(),
enable_query_validation: (config_server).enable_query_validation(),
enable_response_validation: (config_server).enable_http_validation(),
enable_batch_requests: (config_server).enable_batch_requests(),
enable_showcase: (config_server).enable_showcase(),
experimental_headers: (config_server).get_experimental_headers(),
global_response_timeout: (config_server).get_global_response_timeout(),
http,
worker: (config_server).get_workers(),
port: (config_server).get_port(),
hostname,
vars: (config_server).get_vars(),
pipeline_flush: (config_server).get_pipeline_flush(),
response_headers,
script,
})
.fuse(handle_experimental_headers(
(config_server).get_experimental_headers(),
))
.map(
|(hostname, http, response_headers, script, experimental_headers)| Server {
enable_apollo_tracing: (config_server).enable_apollo_tracing(),
enable_cache_control_header: (config_server).enable_cache_control(),
enable_set_cookie_header: (config_server).enable_set_cookies(),
enable_graphiql: (config_server).enable_graphiql(),
enable_introspection: (config_server).enable_introspection(),
enable_query_validation: (config_server).enable_query_validation(),
enable_response_validation: (config_server).enable_http_validation(),
enable_batch_requests: (config_server).enable_batch_requests(),
enable_showcase: (config_server).enable_showcase(),
experimental_headers,
global_response_timeout: (config_server).get_global_response_timeout(),
http,
worker: (config_server).get_workers(),
port: (config_server).get_port(),
hostname,
vars: (config_server).get_vars(),
pipeline_flush: (config_server).get_pipeline_flush(),
response_headers,
script,
},
)
.to_result()
}
}
Expand Down Expand Up @@ -187,6 +192,27 @@ fn handle_response_headers(resp_headers: Vec<(String, String)>) -> Valid<HeaderM
.trace("schema")
}

fn handle_experimental_headers(headers: BTreeSet<String>) -> Valid<BTreeSet<String>, String> {
Valid::from_iter(headers.iter(), |h| {
if !h.to_lowercase().starts_with("x-") {
Valid::fail(
format!(
"Experimental headers must start with 'x-' or 'X-'. Got: '{}'",
h
)
.to_string(),
)
} else {
Valid::succeed(h.clone())
}
})
.map_to(headers)
.trace("experimental")
.trace("headers")
.trace("@server")
.trace("schema")
}

#[cfg(test)]
mod tests {
use crate::config::ConfigModule;
Expand Down
Loading

0 comments on commit d224a14

Please sign in to comment.