From 02a8e149c3e827cf6fbc4458cfa377d64af50bdf Mon Sep 17 00:00:00 2001 From: Avery Harnish Date: Mon, 28 Jun 2021 15:07:00 -0500 Subject: [PATCH] chore: refactor subgraph list (#640) --- .../{list.graphql => list/list_query.graphql} | 2 +- .../src/query/subgraph/list/mod.rs | 6 ++ .../{list.rs => list/query_runner.rs} | 64 +++++++------------ .../src/query/subgraph/list/types.rs | 38 +++++++++++ src/command/output.rs | 4 +- src/command/subgraph/list.rs | 4 +- 6 files changed, 73 insertions(+), 45 deletions(-) rename crates/rover-client/src/query/subgraph/{list.graphql => list/list_query.graphql} (80%) create mode 100644 crates/rover-client/src/query/subgraph/list/mod.rs rename crates/rover-client/src/query/subgraph/{list.rs => list/query_runner.rs} (72%) create mode 100644 crates/rover-client/src/query/subgraph/list/types.rs diff --git a/crates/rover-client/src/query/subgraph/list.graphql b/crates/rover-client/src/query/subgraph/list/list_query.graphql similarity index 80% rename from crates/rover-client/src/query/subgraph/list.graphql rename to crates/rover-client/src/query/subgraph/list/list_query.graphql index d733b65aa..69ec2f182 100644 --- a/crates/rover-client/src/query/subgraph/list.graphql +++ b/crates/rover-client/src/query/subgraph/list/list_query.graphql @@ -1,4 +1,4 @@ -query ListSubgraphsQuery($graphId: ID!, $variant: String!) { +query SubgraphListQuery($graphId: ID!, $variant: String!) { frontendUrlRoot service(id: $graphId) { implementingServices(graphVariant: $variant) { diff --git a/crates/rover-client/src/query/subgraph/list/mod.rs b/crates/rover-client/src/query/subgraph/list/mod.rs new file mode 100644 index 000000000..07495e228 --- /dev/null +++ b/crates/rover-client/src/query/subgraph/list/mod.rs @@ -0,0 +1,6 @@ +mod query_runner; + +pub(crate) mod types; + +pub use query_runner::run; +pub use types::{SubgraphListInput, SubgraphListResponse}; diff --git a/crates/rover-client/src/query/subgraph/list.rs b/crates/rover-client/src/query/subgraph/list/query_runner.rs similarity index 72% rename from crates/rover-client/src/query/subgraph/list.rs rename to crates/rover-client/src/query/subgraph/list/query_runner.rs index a7752d5f7..368744417 100644 --- a/crates/rover-client/src/query/subgraph/list.rs +++ b/crates/rover-client/src/query/subgraph/list/query_runner.rs @@ -1,59 +1,44 @@ use crate::blocking::StudioClient; +use crate::query::subgraph::list::types::*; use crate::RoverClientError; -use chrono::prelude::*; + use graphql_client::*; type Timestamp = String; - #[derive(GraphQLQuery)] // The paths are relative to the directory where your `Cargo.toml` is located. // Both json and the GraphQL schema language are supported as sources for the schema #[graphql( - query_path = "src/query/subgraph/list.graphql", + query_path = "src/query/subgraph/list/list_query.graphql", schema_path = ".schema/schema.graphql", response_derives = "PartialEq, Debug, Serialize, Deserialize", deprecated = "warn" )] /// This struct is used to generate the module containing `Variables` and /// `ResponseData` structs. -/// Snake case of this name is the mod name. i.e. list_subgraphs_query -pub struct ListSubgraphsQuery; - -#[derive(Clone, PartialEq, Debug)] -pub struct SubgraphInfo { - pub name: String, - pub url: Option, // optional, and may not be a real url - pub updated_at: Option>, -} - -#[derive(Clone, PartialEq, Debug)] -pub struct ListDetails { - pub subgraphs: Vec, - pub root_url: String, - pub graph_name: String, -} +/// Snake case of this name is the mod name. i.e. subgraph_list_query +pub struct SubgraphListQuery; /// Fetches list of subgraphs for a given graph, returns name & url of each pub fn run( - variables: list_subgraphs_query::Variables, + input: SubgraphListInput, client: &StudioClient, -) -> Result { - let graph = variables.graph_id.clone(); - let response_data = client.post::(variables)?; +) -> Result { + let graph = input.graph_id.clone(); + let response_data = client.post::(input.into())?; let root_url = response_data.frontend_url_root.clone(); let subgraphs = get_subgraphs_from_response_data(response_data, graph.clone())?; - Ok(ListDetails { + Ok(SubgraphListResponse { subgraphs: format_subgraphs(&subgraphs), root_url, graph_name: graph, }) } -type RawSubgraphInfo = list_subgraphs_query::ListSubgraphsQueryServiceImplementingServicesOnFederatedImplementingServicesServices; fn get_subgraphs_from_response_data( - response_data: list_subgraphs_query::ResponseData, + response_data: QueryResponseData, graph: String, -) -> Result, RoverClientError> { +) -> Result, RoverClientError> { let service_data = response_data.service.ok_or(RoverClientError::NoService { graph: graph.clone(), })?; @@ -72,24 +57,25 @@ fn get_subgraphs_from_response_data( // implementing_services.services match services { - list_subgraphs_query::ListSubgraphsQueryServiceImplementingServices::FederatedImplementingServices (services) => { - Ok(services.services) - }, - list_subgraphs_query::ListSubgraphsQueryServiceImplementingServices::NonFederatedImplementingService => { - Err(RoverClientError::ExpectedFederatedGraph { graph, can_operation_convert: false }) + QueryGraphType::FederatedImplementingServices(services) => Ok(services.services), + QueryGraphType::NonFederatedImplementingService => { + Err(RoverClientError::ExpectedFederatedGraph { + graph, + can_operation_convert: false, + }) } } } /// puts the subgraphs into a vec of SubgraphInfo, sorted by updated_at /// timestamp. Newer updated services will show at top of list -fn format_subgraphs(subgraphs: &[RawSubgraphInfo]) -> Vec { +fn format_subgraphs(subgraphs: &[QuerySubgraphInfo]) -> Vec { let mut subgraphs: Vec = subgraphs .iter() .map(|subgraph| SubgraphInfo { name: subgraph.name.clone(), url: subgraph.url.clone(), - updated_at: subgraph.updated_at.clone().parse::>().ok(), + updated_at: subgraph.updated_at.clone().parse().ok(), }) .collect(); @@ -128,8 +114,7 @@ mod tests { } } }); - let data: list_subgraphs_query::ResponseData = - serde_json::from_value(json_response).unwrap(); + let data: QueryResponseData = serde_json::from_value(json_response).unwrap(); let output = get_subgraphs_from_response_data(data, "mygraph".to_string()); let expected_json = json!([ @@ -144,7 +129,7 @@ mod tests { "updatedAt": "2020-09-16T19:22:06.420Z" } ]); - let expected_service_list: Vec = + let expected_service_list: Vec = serde_json::from_value(expected_json).unwrap(); assert!(output.is_ok()); @@ -159,8 +144,7 @@ mod tests { "implementingServices": null } }); - let data: list_subgraphs_query::ResponseData = - serde_json::from_value(json_response).unwrap(); + let data: QueryResponseData = serde_json::from_value(json_response).unwrap(); let output = get_subgraphs_from_response_data(data, "mygraph".to_string()); assert!(output.is_err()); } @@ -184,7 +168,7 @@ mod tests { "updatedAt": "2020-09-16T19:22:06.420Z" } ]); - let raw_subgraph_list: Vec = + let raw_subgraph_list: Vec = serde_json::from_value(raw_info_json).unwrap(); let formatted = format_subgraphs(&raw_subgraph_list); assert_eq!(formatted[0].name, "accounts".to_string()); diff --git a/crates/rover-client/src/query/subgraph/list/types.rs b/crates/rover-client/src/query/subgraph/list/types.rs new file mode 100644 index 000000000..ef69c1cb7 --- /dev/null +++ b/crates/rover-client/src/query/subgraph/list/types.rs @@ -0,0 +1,38 @@ +use crate::query::subgraph::list::query_runner::subgraph_list_query; + +pub(crate) type QuerySubgraphInfo = subgraph_list_query::SubgraphListQueryServiceImplementingServicesOnFederatedImplementingServicesServices; +pub(crate) type QueryResponseData = subgraph_list_query::ResponseData; +pub(crate) type QueryGraphType = subgraph_list_query::SubgraphListQueryServiceImplementingServices; + +type QueryVariables = subgraph_list_query::Variables; + +use chrono::{DateTime, Local}; + +#[derive(Clone, PartialEq, Debug)] +pub struct SubgraphListInput { + pub graph_id: String, + pub variant: String, +} + +impl From for QueryVariables { + fn from(input: SubgraphListInput) -> Self { + Self { + graph_id: input.graph_id, + variant: input.variant, + } + } +} + +#[derive(Clone, PartialEq, Debug)] +pub struct SubgraphListResponse { + pub subgraphs: Vec, + pub root_url: String, + pub graph_name: String, +} + +#[derive(Clone, PartialEq, Debug)] +pub struct SubgraphInfo { + pub name: String, + pub url: Option, // optional, and may not be a real url + pub updated_at: Option>, +} diff --git a/src/command/output.rs b/src/command/output.rs index c1c8fe3e9..c2870532f 100644 --- a/src/command/output.rs +++ b/src/command/output.rs @@ -6,7 +6,7 @@ use crate::utils::table::{self, cell, row}; use ansi_term::{Colour::Yellow, Style}; use atty::Stream; use crossterm::style::Attribute::Underlined; -use rover_client::query::subgraph::{check::SubgraphCheckResponse, list::ListDetails}; +use rover_client::query::subgraph::{check::SubgraphCheckResponse, list::SubgraphListResponse}; use termimad::MadSkin; /// RoverStdout defines all of the different types of data that are printed @@ -24,7 +24,7 @@ pub enum RoverStdout { Sdl(String), CoreSchema(String), SchemaHash(String), - SubgraphList(ListDetails), + SubgraphList(SubgraphListResponse), SubgraphCheck(SubgraphCheckResponse), VariantList(Vec), Profiles(Vec), diff --git a/src/command/subgraph/list.rs b/src/command/subgraph/list.rs index 27843938d..28c122a48 100644 --- a/src/command/subgraph/list.rs +++ b/src/command/subgraph/list.rs @@ -2,7 +2,7 @@ use ansi_term::Colour::Cyan; use serde::Serialize; use structopt::StructOpt; -use rover_client::query::subgraph::list; +use rover_client::query::subgraph::list::{self, SubgraphListInput}; use crate::command::RoverStdout; use crate::utils::client::StudioClientConfig; @@ -34,7 +34,7 @@ impl List { ); let list_details = list::run( - list::list_subgraphs_query::Variables { + SubgraphListInput { graph_id: self.graph.name.clone(), variant: self.graph.variant.clone(), },