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

feat: adds rover graph delete #861

Merged
merged 6 commits into from
Oct 25, 2021
Merged
Show file tree
Hide file tree
Changes from 5 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
@@ -0,0 +1,10 @@
mutation GraphDeleteMutation(
$graph_id: ID!,
$variant: String!
) {
service(id: $graph_id) {
deleteSchemaTag(tag: $variant) {
deleted
}
}
}
5 changes: 5 additions & 0 deletions crates/rover-client/src/operations/graph/delete/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
mod runner;
mod types;

pub use runner::run;
pub use types::GraphDeleteInput;
52 changes: 52 additions & 0 deletions crates/rover-client/src/operations/graph/delete/runner.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use crate::blocking::StudioClient;
use crate::operations::graph::{
delete::GraphDeleteInput,
variant::{self, VariantListInput},
};
use crate::RoverClientError;

use graphql_client::*;

#[derive(GraphQLQuery)]
#[graphql(
query_path = "src/operations/graph/delete/delete_mutation.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. graph_delete_mutation
pub(crate) struct GraphDeleteMutation;

/// The main function to be used from this module.
/// This function deletes a single graph variant from the graph registry
pub fn run(input: GraphDeleteInput, client: &StudioClient) -> Result<(), RoverClientError> {
let graph_ref = input.graph_ref.clone();
let response_data = client
.post::<GraphDeleteMutation>(input.into())
.map_err(|e| {
if e.to_string().contains("Variant not found") {
if let Err(no_variant_err) = variant::run(
VariantListInput {
graph_ref: graph_ref.clone(),
},
client,
) {
return no_variant_err;
}
}
e
})?;
let service_data = response_data
.service
.ok_or(RoverClientError::GraphNotFound { graph_ref })?;

if service_data.delete_schema_tag.deleted {
Ok(())
} else {
Err(RoverClientError::AdhocError {
msg: "An unknown error occurred while deleting your graph.".to_string(),
})
}
}
17 changes: 17 additions & 0 deletions crates/rover-client/src/operations/graph/delete/types.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use crate::operations::graph::delete::runner::graph_delete_mutation;
use crate::shared::GraphRef;

#[derive(Debug, Clone, PartialEq)]
pub struct GraphDeleteInput {
pub graph_ref: GraphRef,
}

type MutationVariables = graph_delete_mutation::Variables;
impl From<GraphDeleteInput> for MutationVariables {
fn from(input: GraphDeleteInput) -> Self {
Self {
graph_id: input.graph_ref.name,
variant: input.graph_ref.variant,
}
}
}
6 changes: 6 additions & 0 deletions crates/rover-client/src/operations/graph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,9 @@ pub mod check;

/// "graph introspect" command execution
pub mod introspect;

/// "graph delete" command execution
pub mod delete;

/// internal module for getting info about variants
pub(crate) mod variant;
5 changes: 5 additions & 0 deletions crates/rover-client/src/operations/graph/variant/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
mod runner;
mod types;

pub(crate) use runner::run;
pub(crate) use types::VariantListInput;
45 changes: 45 additions & 0 deletions crates/rover-client/src/operations/graph/variant/runner.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use crate::blocking::StudioClient;
use crate::operations::graph::variant::VariantListInput;
use crate::RoverClientError;

use graphql_client::*;

#[derive(GraphQLQuery)]
#[graphql(
query_path = "src/operations/graph/variant/variant_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. variant_list_query
pub(crate) struct VariantListQuery;

/// The main function to be used from this module.
/// This function lists all the variants for a given graph ref
pub fn run(input: VariantListInput, client: &StudioClient) -> Result<(), RoverClientError> {
let graph_ref = input.graph_ref.clone();
let response_data = client.post::<VariantListQuery>(input.into())?;
let service_data = response_data
.service
.ok_or(RoverClientError::GraphNotFound {
graph_ref: graph_ref.clone(),
})?;

let mut valid_variants = Vec::new();

for variant in service_data.variants {
valid_variants.push(variant.name)
}

if !valid_variants.contains(&graph_ref.variant) {
Err(RoverClientError::NoSchemaForVariant {
graph_ref,
valid_variants,
frontend_url_root: response_data.frontend_url_root,
})
} else {
Ok(())
}
}
16 changes: 16 additions & 0 deletions crates/rover-client/src/operations/graph/variant/types.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use crate::operations::graph::variant::runner::variant_list_query;
use crate::shared::GraphRef;

#[derive(Debug, Clone, PartialEq)]
pub struct VariantListInput {
pub graph_ref: GraphRef,
}

type MutationVariables = variant_list_query::Variables;
impl From<VariantListInput> for MutationVariables {
fn from(input: VariantListInput) -> Self {
Self {
graph_id: input.graph_ref.name,
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
query VariantListQuery($graph_id: ID!) {
frontendUrlRoot,
service(id: $graph_id) {
variants {
name
}
}
}
42 changes: 33 additions & 9 deletions crates/rover-client/src/operations/subgraph/publish/runner.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
use super::types::*;
use crate::blocking::StudioClient;
use crate::operations::config::is_federated::{self, IsFederatedInput};
use crate::operations::graph::variant::VariantListInput;
use crate::operations::{
config::is_federated::{self, IsFederatedInput},
graph::variant,
};
use crate::shared::{BuildError, BuildErrors, GraphRef};
use crate::RoverClientError;
use graphql_client::*;
Expand Down Expand Up @@ -29,18 +33,38 @@ pub fn run(
// Error here if no --convert flag is passed _and_ the current context
// is non-federated. Add a suggestion to require a --convert flag.
if !input.convert_to_federated_graph {
let is_federated = is_federated::run(
IsFederatedInput {
// first, check if the variant exists _at all_
// if it doesn't exist, there is no graph schema to "convert"
// so don't require --convert in this case, just publish the subgraph
let variant_exists = variant::run(
VariantListInput {
graph_ref: graph_ref.clone(),
},
client,
)?;
)
.is_ok();

if !is_federated {
return Err(RoverClientError::ExpectedFederatedGraph {
graph_ref,
can_operation_convert: true,
});
if variant_exists {
// check if subgraphs have ever been published to this graph ref
let is_federated = is_federated::run(
IsFederatedInput {
graph_ref: graph_ref.clone(),
},
client,
)?;

if !is_federated {
return Err(RoverClientError::ExpectedFederatedGraph {
graph_ref,
can_operation_convert: true,
});
}
} else {
tracing::debug!(
"Publishing new subgraph {} to {}",
&input.subgraph,
&input.graph_ref
);
}
}
let data = client.post::<SubgraphPublishMutation>(variables)?;
Expand Down
33 changes: 2 additions & 31 deletions docs/package-lock.json

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

17 changes: 17 additions & 0 deletions docs/source/graphs.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ The argument `my-graph@my-variant` in the example above specifies the ID of the

> You can omit `@` and the variant name. If you do, Rover publishes the schema to the default variant, named `current`.

If the graph exists in the graph registry, but the variant does not, a new variant will be created on publish.

### Providing the schema

You provide your schema to Rover commands via the `--schema` option. The value is usually the path to a local `.graphql` or `.gql` file in [SDL format](https://www.apollographql.com/docs/resources/graphql-glossary/#schema-definition-language-sdl).
Expand Down Expand Up @@ -112,3 +114,18 @@ rover graph introspect http://localhost:4000 | rover graph check my-graph --sche
As shown, arguments and options are similar to [`graph publish`](#publishing-a-schema-to-apollo-studio).

To configure the behavior of schema checks (such as the time range of past operations to check against), see the [documentation for schema checks](https://www.apollographql.com/docs/studio/check-configurations/#using-apollo-studio-recommended).

## Deleting a variant

> This requires first [authenticating Rover with Apollo Studio](./configuring/#authenticating-with-apollo-studio).

You can delete a single variant of a graph by running `rover graph delete`:

```bash
# ⚠️ This action is irreversible!
rover graph delete my-graph@variant-to-delete
```

This command prompts you for confirmation because the action is irreversible. You can bypass confirmation by passing the `--confirm` flag.

If you delete a federated variant with this command, it _also_ deletes all of that variant's subgraphs. To delete a single subgraph while preserving the variant, see [Deleting a subgraph](./subgraphs/#deleting-a-subgraph).
44 changes: 40 additions & 4 deletions docs/source/subgraphs.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,15 +125,17 @@ Use the `subgraph publish` command, like so:

```bash
rover subgraph publish my-supergraph@my-variant \
--schema ./accounts/schema.graphql\
--name accounts\
--routing-url https://my-running-subgraph.com/api
--schema "./accounts/schema.graphql" \
--name accounts \
--routing-url "https://my-running-subgraph.com/api"
```

The argument `my-graph@my-variant` in the example above is a [graph ref](./conventions/#graph-refs) that specifies the ID of the Studio graph you're publishing to, along with which [variant](https://www.apollographql.com/docs/studio/org/graphs/#managing-variants) you're publishing to.
The argument `my-supergraph@my-variant` in the example above is a [graph ref](./conventions/#graph-refs) that specifies the ID of the Studio graph you're publishing to, along with which [variant](https://www.apollographql.com/docs/studio/org/graphs/#managing-variants) you're publishing to.

> You can omit `@` and the variant name. If you do, Rover publishes the schema to the default variant, named `current`.

If the graph exists in the graph registry but the variant does _not_, a new variant is created on publish.

Options include:

<table class="field-table">
Expand Down Expand Up @@ -188,6 +190,23 @@ The URL that your gateway uses to communicate with the subgraph in a [managed fe

**Optional** after your first publish. Provide only if you need to change the subgraph's routing URL.

</td>
</tr>
<tr class="required">
<td>

###### `--convert`

</td>

<td>

If a monolithic schema for this variant already exists in the graph registry instead of multiple subgraph schemas, you will need to run `rover subgraph publish` with the `--convert` flag in order to convert this variant to be a federated graph with one or more subgraphs. This will _permanently_ delete the existing schema from this variant and replace it with a single subgraph. You will likely need to run multiple `subgraph publish` multiple times in order to successfully compose a supergraph.

**Required** if you are converting an existing monolithic graph variant to a federated graph variant with one or more subgraphs.

**Optional** if the graph variant already has one or more subgraphs.

</td>
</tr>
</tbody>
Expand Down Expand Up @@ -215,3 +234,20 @@ rover subgraph introspect http://localhost:4000 \
As shown, arguments and options are similar to [`subgraph publish`](#publishing-a-subgraph-schema-to-apollo-studio).

To configure the behavior of schema checks (such as the time range of past operations to check against), see the [documentation for schema checks](https://www.apollographql.com/docs/studio/check-configurations/#using-apollo-studio-recommended).

## Deleting a subgraph

> This requires first [authenticating Rover with Apollo Studio](./configuring/#authenticating-with-apollo-studio).

You can delete a single subgraph from a federated graph by running `rover subgraph delete`:

```bash
# ⚠️ This action is irreversible!
rover subgraph delete my-graph@my-variant --name subgraph-to-delete
```

This command prompts you for confirmation because the action is irreversible. You can bypass confirmation by passing the `--confirm` flag.
EverlastingBugstopper marked this conversation as resolved.
Show resolved Hide resolved

This command fails with an error if any _other_ subgraph references types that originate in this subgraph.

To delete an entire federated graph instead of a single subgraph, see [Deleting a variant](./graphs/#deleting-a-variant).
Loading