Skip to content

Commit

Permalink
Pass requisite data into graph proxy query resolvers
Browse files Browse the repository at this point in the history
  • Loading branch information
garryod committed Aug 27, 2024
1 parent a8c3554 commit ea8d9a6
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 12 deletions.
69 changes: 69 additions & 0 deletions graph-proxy/Cargo.lock

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

2 changes: 2 additions & 0 deletions graph-proxy/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ argo-workflows-openapi = { path = "./argo-workflows-openapi" }
async-graphql = { version = "7.0.7" }
async-graphql-axum = { version = "7.0.7" }
axum = { version = "0.7.5" }
axum-extra = { version = "0.9.3", features = ["typed-header"] }
clap = { version = "4.5.16", features = ["derive", "env"] }
derive_more = { version = "1.0.0", features = ["deref"] }
dotenvy = { version = "0.15.7" }
opentelemetry = { version = "0.22.0" }
opentelemetry-otlp = { version = "0.15.0", features = ["metrics"] }
Expand Down
21 changes: 21 additions & 0 deletions graph-proxy/src/graphql.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
use async_graphql::{EmptyMutation, EmptySubscription, MergedObject, Schema, SchemaBuilder};
use async_graphql_axum::{GraphQLRequest, GraphQLResponse};
use axum::extract::State;
use axum_extra::{
headers::{authorization::Bearer, Authorization},
TypedHeader,
};

/// The root schema of the service
pub type RootSchema = Schema<Query, EmptyMutation, EmptySubscription>;

/// A schema builder for the service
pub fn root_schema_builder() -> SchemaBuilder<Query, EmptyMutation, EmptySubscription> {
Expand All @@ -8,3 +17,15 @@ pub fn root_schema_builder() -> SchemaBuilder<Query, EmptyMutation, EmptySubscri
/// The root query of the service
#[derive(Debug, Clone, Default, MergedObject)]
pub struct Query;

/// Handles HTTP requests as GraphQL according to the provided [`Schema`]
pub async fn graphql_handler(
State(schema): State<RootSchema>,
TypedHeader(auth_token): TypedHeader<Authorization<Bearer>>,
request: GraphQLRequest,
) -> GraphQLResponse {
schema
.execute(request.into_inner().data(auth_token))
.await
.into()
}
28 changes: 16 additions & 12 deletions graph-proxy/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@ mod graphql;
/// OpenTelemetry setup and configuration
mod telemetry;

use async_graphql::{http::GraphiQLSource, ObjectType, SDLExportOptions, Schema, SubscriptionType};
use async_graphql_axum::GraphQL;
use async_graphql::{http::GraphiQLSource, SDLExportOptions};
use axum::{response::Html, routing::get, Router};
use clap::Parser;
use graphql::root_schema_builder;
use graphql::{graphql_handler, root_schema_builder, RootSchema};
use std::{
fs::File,
io::Write,
Expand All @@ -26,6 +25,7 @@ use url::Url;

/// A proxy providing Argo Workflows data
#[derive(Debug, Parser)]
#[allow(clippy::large_enum_variant)]
enum Cli {
/// Starts a webserver serving the GraphQL API
Serve(ServeArgs),
Expand All @@ -36,6 +36,9 @@ enum Cli {
/// Arguments for serving the GraphQL API
#[derive(Debug, Parser)]
struct ServeArgs {
/// The base URL of the Argo Server from which data is to be retrieved
#[arg(short, long, env = "ARGO_SERVER_URL")]
argo_server_url: Url,
/// The host IP to bind the service to
#[arg(short, long, env="HOST", default_value_t=IpAddr::V4(Ipv4Addr::UNSPECIFIED))]
host: IpAddr,
Expand All @@ -61,6 +64,10 @@ struct SchemaArgs {
path: Option<PathBuf>,
}

/// The URL of an Argo Server
#[derive(Debug, Clone, derive_more::Deref)]
pub struct ArgoServerUrl(Url);

#[tokio::main]
async fn main() {
dotenvy::dotenv().ok();
Expand All @@ -74,7 +81,9 @@ async fn main() {
args.telemetry_level,
)
.unwrap();
let schema = root_schema_builder().finish();
let schema = root_schema_builder()
.data(ArgoServerUrl(args.argo_server_url))
.finish();
let router = setup_router(schema);
serve(router, args.host, args.port).await.unwrap();
}
Expand All @@ -92,13 +101,7 @@ async fn main() {
}

/// Creates an [`axum::Router`] serving GraphiQL and sychronous GraphQL
fn setup_router(
schema: Schema<
impl ObjectType + 'static,
impl ObjectType + 'static,
impl SubscriptionType + 'static,
>,
) -> Router {
fn setup_router(schema: RootSchema) -> Router {
#[allow(clippy::missing_docs_in_private_items)]
const GRAPHQL_ENDPOINT: &str = "/";

Expand All @@ -107,7 +110,8 @@ fn setup_router(
get(Html(
GraphiQLSource::build().endpoint(GRAPHQL_ENDPOINT).finish(),
))
.post_service(GraphQL::new(schema)),
.post(graphql_handler)
.with_state(schema),
)
}

Expand Down

0 comments on commit ea8d9a6

Please sign in to comment.