Skip to content

Commit d1100e8

Browse files
committed
graph, graphql: Remove Subscription type from API schema
1 parent b01dd67 commit d1100e8

File tree

7 files changed

+14
-467
lines changed

7 files changed

+14
-467
lines changed

graph/src/data/graphql/ext.rs

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,6 @@ pub trait DocumentExt {
5252

5353
fn get_root_query_type(&self) -> Option<&ObjectType>;
5454

55-
fn get_root_subscription_type(&self) -> Option<&ObjectType>;
56-
5755
fn object_or_interface(&self, name: &str) -> Option<ObjectOrInterface<'_>>;
5856

5957
fn get_named_type(&self, name: &str) -> Option<&TypeDefinition>;
@@ -159,21 +157,6 @@ impl DocumentExt for Document {
159157
.next()
160158
}
161159

162-
fn get_root_subscription_type(&self) -> Option<&ObjectType> {
163-
self.definitions
164-
.iter()
165-
.filter_map(|d| match d {
166-
Definition::TypeDefinition(TypeDefinition::Object(t))
167-
if t.name == "Subscription" =>
168-
{
169-
Some(t)
170-
}
171-
_ => None,
172-
})
173-
.peekable()
174-
.next()
175-
}
176-
177160
fn object_or_interface(&self, name: &str) -> Option<ObjectOrInterface<'_>> {
178161
match self.get_named_type(name) {
179162
Some(TypeDefinition::Object(t)) => Some(t.into()),

graph/src/data/query/error.rs

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ pub enum QueryExecutionError {
2626
OperationNameRequired,
2727
OperationNotFound(String),
2828
NotSupported(String),
29-
NoRootSubscriptionObjectType,
3029
NonNullError(Pos, String),
3130
ListValueError(Pos, String),
3231
NamedTypeError(String),
@@ -42,7 +41,6 @@ pub enum QueryExecutionError {
4241
FilterNotSupportedError(String, String),
4342
UnknownField(Pos, String, String),
4443
EmptyQuery,
45-
MultipleSubscriptionFields,
4644
SubgraphDeploymentIdError(String),
4745
RangeArgumentsError(&'static str, u32, i64),
4846
InvalidFilterError,
@@ -67,7 +65,6 @@ pub enum QueryExecutionError {
6765
Throttled,
6866
UndefinedFragment(String),
6967
Panic(String),
70-
EventStreamError,
7168
FulltextQueryRequiresFilter,
7269
FulltextQueryInvalidSyntax(String),
7370
DeploymentReverted,
@@ -87,7 +84,6 @@ impl QueryExecutionError {
8784
OperationNameRequired
8885
| OperationNotFound(_)
8986
| NotSupported(_)
90-
| NoRootSubscriptionObjectType
9187
| NonNullError(_, _)
9288
| NamedTypeError(_)
9389
| AbstractTypeError(_)
@@ -101,7 +97,6 @@ impl QueryExecutionError {
10197
| ChildFilterNestingNotSupportedError(_, _)
10298
| UnknownField(_, _, _)
10399
| EmptyQuery
104-
| MultipleSubscriptionFields
105100
| SubgraphDeploymentIdError(_)
106101
| InvalidFilterError
107102
| EntityFieldError(_, _)
@@ -127,7 +122,6 @@ impl QueryExecutionError {
127122
| TooComplex(_, _)
128123
| TooDeep(_)
129124
| Panic(_)
130-
| EventStreamError
131125
| TooExpensive
132126
| Throttled
133127
| DeploymentReverted
@@ -166,9 +160,6 @@ impl fmt::Display for QueryExecutionError {
166160
write!(f, "{}", message)
167161
}
168162
NotSupported(s) => write!(f, "Not supported: {}", s),
169-
NoRootSubscriptionObjectType => {
170-
write!(f, "No root Subscription type defined in the schema")
171-
}
172163
NonNullError(_, s) => {
173164
write!(f, "Null value resolved for non-null field `{}`", s)
174165
}
@@ -212,10 +203,6 @@ impl fmt::Display for QueryExecutionError {
212203
write!(f, "Type `{}` has no field `{}`", t, s)
213204
}
214205
EmptyQuery => write!(f, "The query is empty"),
215-
MultipleSubscriptionFields => write!(
216-
f,
217-
"Only a single top-level field is allowed in subscriptions"
218-
),
219206
SubgraphDeploymentIdError(s) => {
220207
write!(f, "Failed to get subgraph ID from type: `{}`", s)
221208
}
@@ -276,7 +263,6 @@ impl fmt::Display for QueryExecutionError {
276263
CyclicalFragment(name) =>write!(f, "query has fragment cycle including `{}`", name),
277264
UndefinedFragment(frag_name) => write!(f, "fragment `{}` is not defined", frag_name),
278265
Panic(msg) => write!(f, "panic processing query: {}", msg),
279-
EventStreamError => write!(f, "error in the subscription event stream"),
280266
FulltextQueryRequiresFilter => write!(f, "fulltext search queries can only use EntityFilter::Equal"),
281267
FulltextQueryInvalidSyntax(msg) => write!(f, "Invalid fulltext search query syntax. Error: {}. Hint: Search terms with spaces need to be enclosed in single quotes", msg),
282268
TooExpensive => write!(f, "query is too expensive"),

graph/src/schema/api.rs

Lines changed: 2 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,8 @@ impl TryFrom<&r::Value> for ErrorPolicy {
9090
///
9191
/// (2) By parsing an appropriate GraphQL schema from text and calling
9292
/// `from_graphql_schema`. In that case, it's the caller's responsibility to
93-
/// make sure that the schema has all the types needed for querying, like
94-
/// `Query` and `Subscription`
93+
/// make sure that the schema has all the types needed for querying, in
94+
/// particular `Query`
9595
///
9696
/// Because of the second point, once constructed, it can not be assumed
9797
/// that an `ApiSchema` is based on an `InputSchema` and it can only be used
@@ -102,7 +102,6 @@ pub struct ApiSchema {
102102

103103
// Root types for the api schema.
104104
pub query_type: Arc<s::ObjectType>,
105-
pub subscription_type: Option<Arc<s::ObjectType>>,
106105
object_types: HashMap<String, Arc<s::ObjectType>>,
107106
}
108107

@@ -121,11 +120,6 @@ impl ApiSchema {
121120
.get_root_query_type()
122121
.context("no root `Query` in the schema")?
123122
.clone();
124-
let subscription_type = schema
125-
.document
126-
.get_root_subscription_type()
127-
.cloned()
128-
.map(Arc::new);
129123

130124
let object_types = HashMap::from_iter(
131125
schema
@@ -138,7 +132,6 @@ impl ApiSchema {
138132
Ok(Self {
139133
schema,
140134
query_type: Arc::new(query_type),
141-
subscription_type,
142135
object_types,
143136
})
144137
}
@@ -360,7 +353,6 @@ pub(in crate::schema) fn api_schema(
360353
add_types_for_interface_types(&mut api, input_schema)?;
361354
add_types_for_aggregation_types(&mut api, input_schema)?;
362355
add_query_type(&mut api.document, input_schema)?;
363-
add_subscription_type(&mut api.document, input_schema)?;
364356
Ok(api.document)
365357
}
366358

@@ -1135,44 +1127,6 @@ fn query_field_for_fulltext(fulltext: &s::Directive) -> Option<s::Field> {
11351127
})
11361128
}
11371129

1138-
/// Adds a root `Subscription` object type to the schema.
1139-
fn add_subscription_type(
1140-
api: &mut s::Document,
1141-
input_schema: &InputSchema,
1142-
) -> Result<(), APISchemaError> {
1143-
let type_name = String::from("Subscription");
1144-
1145-
if api.get_named_type(&type_name).is_some() {
1146-
return Err(APISchemaError::TypeExists(type_name));
1147-
}
1148-
1149-
let mut fields: Vec<s::Field> = input_schema
1150-
.object_types()
1151-
.map(|(name, _)| name)
1152-
.chain(input_schema.interface_types().map(|(name, _)| name))
1153-
.flat_map(|name| query_fields_for_type(name, FilterOps::Object))
1154-
.collect();
1155-
let mut agg_fields = input_schema
1156-
.aggregation_types()
1157-
.map(|(name, _)| name)
1158-
.flat_map(query_fields_for_agg_type)
1159-
.collect::<Vec<s::Field>>();
1160-
fields.append(&mut agg_fields);
1161-
fields.push(meta_field());
1162-
1163-
let typedef = s::TypeDefinition::Object(s::ObjectType {
1164-
position: Pos::default(),
1165-
description: None,
1166-
name: type_name,
1167-
implements_interfaces: vec![],
1168-
directives: vec![],
1169-
fields,
1170-
});
1171-
let def = s::Definition::TypeDefinition(typedef);
1172-
api.definitions.push(def);
1173-
Ok(())
1174-
}
1175-
11761130
fn block_argument() -> s::InputValue {
11771131
s::InputValue {
11781132
position: Pos::default(),

graphql/src/execution/query.rs

Lines changed: 9 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ lazy_static! {
3535
vec![
3636
Box::new(UniqueOperationNames::new()),
3737
Box::new(LoneAnonymousOperation::new()),
38-
Box::new(SingleFieldSubscriptions::new()),
3938
Box::new(KnownTypeNames::new()),
4039
Box::new(FragmentsOnCompositeTypes::new()),
4140
Box::new(VariablesAreInputTypes::new()),
@@ -69,12 +68,6 @@ pub enum ComplexityError {
6968
CyclicalFragment(String),
7069
}
7170

72-
#[derive(Copy, Clone)]
73-
enum Kind {
74-
Query,
75-
Subscription,
76-
}
77-
7871
/// Helper to log the fields in a `SelectionSet` without cloning. Writes
7972
/// a list of field names from the selection set separated by ';'. Using
8073
/// ';' as a separator makes parsing the log a little easier since slog
@@ -130,8 +123,6 @@ pub struct Query {
130123

131124
start: Instant,
132125

133-
kind: Kind,
134-
135126
/// Used only for logging; if logging is configured off, these will
136127
/// have dummy values
137128
pub query_text: Arc<String>,
@@ -226,14 +217,14 @@ impl Query {
226217
let operation = operation.ok_or(QueryExecutionError::OperationNameRequired)?;
227218

228219
let variables = coerce_variables(schema.as_ref(), &operation, query.variables)?;
229-
let (kind, selection_set) = match operation {
230-
q::OperationDefinition::Query(q::Query { selection_set, .. }) => {
231-
(Kind::Query, selection_set)
232-
}
220+
let selection_set = match operation {
221+
q::OperationDefinition::Query(q::Query { selection_set, .. }) => selection_set,
233222
// Queries can be run by just sending a selection set
234-
q::OperationDefinition::SelectionSet(selection_set) => (Kind::Query, selection_set),
235-
q::OperationDefinition::Subscription(q::Subscription { selection_set, .. }) => {
236-
(Kind::Subscription, selection_set)
223+
q::OperationDefinition::SelectionSet(selection_set) => selection_set,
224+
q::OperationDefinition::Subscription(_) => {
225+
return Err(vec![QueryExecutionError::NotSupported(
226+
"Subscriptions are not supported".to_owned(),
227+
)])
237228
}
238229
q::OperationDefinition::Mutation(_) => {
239230
return Err(vec![QueryExecutionError::NotSupported(
@@ -243,10 +234,8 @@ impl Query {
243234
};
244235

245236
let start = Instant::now();
246-
let root_type = match kind {
247-
Kind::Query => schema.query_type.as_ref(),
248-
Kind::Subscription => schema.subscription_type.as_ref().unwrap(),
249-
};
237+
let root_type = schema.query_type.as_ref();
238+
250239
// Use an intermediate struct so we can modify the query before
251240
// enclosing it in an Arc
252241
let raw_query = RawQuery {
@@ -269,7 +258,6 @@ impl Query {
269258
schema,
270259
selection_set: Arc::new(selection_set),
271260
shape_hash: query.shape_hash,
272-
kind,
273261
network,
274262
logger,
275263
start,
@@ -345,23 +333,6 @@ impl Query {
345333
Ok(bcs)
346334
}
347335

348-
/// Return `true` if this is a query, and not a subscription or
349-
/// mutation
350-
pub fn is_query(&self) -> bool {
351-
match self.kind {
352-
Kind::Query => true,
353-
Kind::Subscription => false,
354-
}
355-
}
356-
357-
/// Return `true` if this is a subscription, not a query or a mutation
358-
pub fn is_subscription(&self) -> bool {
359-
match self.kind {
360-
Kind::Subscription => true,
361-
Kind::Query => false,
362-
}
363-
}
364-
365336
/// Log details about the overall execution of the query
366337
pub fn log_execution(&self, block: BlockNumber) {
367338
if ENV_VARS.log_gql_timing() {

graphql/src/introspection/resolver.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -332,10 +332,7 @@ impl IntrospectionResolver {
332332
self.type_objects
333333
.get(&String::from("Query"))
334334
.cloned(),
335-
subscriptionType:
336-
self.type_objects
337-
.get(&String::from("Subscription"))
338-
.cloned(),
335+
subscriptionType: r::Value::Null,
339336
mutationType: r::Value::Null,
340337
types: self.type_objects.values().cloned().collect::<Vec<_>>(),
341338
directives: self.directives.clone(),

graphql/src/query/mod.rs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use graph::{
22
data::query::CacheStatus,
3-
prelude::{BlockPtr, CheapClone, QueryExecutionError, QueryResult},
3+
prelude::{BlockPtr, CheapClone, QueryResult},
44
};
55
use std::sync::Arc;
66
use std::time::Instant;
@@ -54,14 +54,6 @@ where
5454
trace: options.trace,
5555
});
5656

57-
if !query.is_query() {
58-
return (
59-
Arc::new(
60-
QueryExecutionError::NotSupported("Only queries are supported".to_string()).into(),
61-
),
62-
CacheStatus::default(),
63-
);
64-
}
6557
let selection_set = selection_set
6658
.map(Arc::new)
6759
.unwrap_or_else(|| query.selection_set.cheap_clone());

0 commit comments

Comments
 (0)