Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: refactor subgraph list #640

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
query ListSubgraphsQuery($graphId: ID!, $variant: String!) {
query SubgraphListQuery($graphId: ID!, $variant: String!) {
frontendUrlRoot
service(id: $graphId) {
implementingServices(graphVariant: $variant) {
Expand Down
6 changes: 6 additions & 0 deletions crates/rover-client/src/query/subgraph/list/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
mod query_runner;

pub(crate) mod types;

pub use query_runner::run;
pub use types::{SubgraphListInput, SubgraphListResponse};
Original file line number Diff line number Diff line change
@@ -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<String>, // optional, and may not be a real url
pub updated_at: Option<DateTime<Local>>,
}

#[derive(Clone, PartialEq, Debug)]
pub struct ListDetails {
pub subgraphs: Vec<SubgraphInfo>,
pub root_url: String,
pub graph_name: String,
}
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<ListDetails, RoverClientError> {
let graph = variables.graph_id.clone();
let response_data = client.post::<ListSubgraphsQuery>(variables)?;
) -> Result<SubgraphListResponse, RoverClientError> {
let graph = input.graph_id.clone();
let response_data = client.post::<SubgraphListQuery>(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<Vec<RawSubgraphInfo>, RoverClientError> {
) -> Result<Vec<QuerySubgraphInfo>, RoverClientError> {
let service_data = response_data.service.ok_or(RoverClientError::NoService {
graph: graph.clone(),
})?;
Expand All @@ -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<SubgraphInfo> {
fn format_subgraphs(subgraphs: &[QuerySubgraphInfo]) -> Vec<SubgraphInfo> {
let mut subgraphs: Vec<SubgraphInfo> = subgraphs
.iter()
.map(|subgraph| SubgraphInfo {
name: subgraph.name.clone(),
url: subgraph.url.clone(),
updated_at: subgraph.updated_at.clone().parse::<DateTime<Local>>().ok(),
updated_at: subgraph.updated_at.clone().parse().ok(),
})
.collect();

Expand Down Expand Up @@ -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!([
Expand All @@ -144,7 +129,7 @@ mod tests {
"updatedAt": "2020-09-16T19:22:06.420Z"
}
]);
let expected_service_list: Vec<RawSubgraphInfo> =
let expected_service_list: Vec<QuerySubgraphInfo> =
serde_json::from_value(expected_json).unwrap();

assert!(output.is_ok());
Expand All @@ -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());
}
Expand All @@ -184,7 +168,7 @@ mod tests {
"updatedAt": "2020-09-16T19:22:06.420Z"
}
]);
let raw_subgraph_list: Vec<RawSubgraphInfo> =
let raw_subgraph_list: Vec<QuerySubgraphInfo> =
serde_json::from_value(raw_info_json).unwrap();
let formatted = format_subgraphs(&raw_subgraph_list);
assert_eq!(formatted[0].name, "accounts".to_string());
Expand Down
38 changes: 38 additions & 0 deletions crates/rover-client/src/query/subgraph/list/types.rs
Original file line number Diff line number Diff line change
@@ -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<SubgraphListInput> 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<SubgraphInfo>,
pub root_url: String,
pub graph_name: String,
}

#[derive(Clone, PartialEq, Debug)]
pub struct SubgraphInfo {
pub name: String,
pub url: Option<String>, // optional, and may not be a real url
pub updated_at: Option<DateTime<Local>>,
}
4 changes: 2 additions & 2 deletions src/command/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -24,7 +24,7 @@ pub enum RoverStdout {
Sdl(String),
CoreSchema(String),
SchemaHash(String),
SubgraphList(ListDetails),
SubgraphList(SubgraphListResponse),
SubgraphCheck(SubgraphCheckResponse),
VariantList(Vec<String>),
Profiles(Vec<String>),
Expand Down
4 changes: 2 additions & 2 deletions src/command/subgraph/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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(),
},
Expand Down