Conversation
50fe5fb to
17f5d84
Compare
| let document = graphql_parser::parse_schema(ROOT_SCHEMA).expect("Failed to parse root schema"); | ||
| let document = graphql_parser::parse_schema(ROOT_SCHEMA).unwrap(); |
There was a problem hiding this comment.
Why drop the error message here (and in the following tests)?
| pub enum SubgraphManifestValidationWarning { | ||
| #[fail(display = "schema validation produced warnings: {:?}", _0)] | ||
| SchemaValidationWarning(SchemaImportError), | ||
| SchemaImportError(SchemaImportError), |
There was a problem hiding this comment.
We could just call this variant SchemaImport because it's already in the ...Warning enum.
| // TODO: Does anything guarantee that the introspection and subgraph query fields | ||
| // do not overlap? |
There was a problem hiding this comment.
That would have to be checked during validation. What it needs to ensure is that no imported types (or type aliases) collide with local types / interfaces / enums. If that is the case then there will be no conflicts in the merged schema / query fields and introspection.
| // If the schema is not available, then add a placeholder type to the root schema. | ||
| // | ||
| // If the schema is available, copy the type over. | ||
| // Check each field in the copied type and for non scalar fields, produce an (ImportedType, SchemaRefernce) |
There was a problem hiding this comment.
Typo: SchemaRefernce -> SchemaReference
| .find(|definition| { | ||
| if let Definition::TypeDefinition(TypeDefinition::Object(obj)) = definition | ||
| { | ||
| obj.name.eq(&original_name) | ||
| } else { | ||
| false | ||
| } | ||
| }) | ||
| .map(|definition| match definition { | ||
| Definition::TypeDefinition(TypeDefinition::Object(obj)) => obj, | ||
| _ => unreachable!(), | ||
| }) |
There was a problem hiding this comment.
Hint hint: find_map will allow you to collapse these two combinators into one and only match the type definition kind once: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.find_map
| let merged = merged_schema(&root_schema, schemas); | ||
|
|
||
| // Verify the output schema is correctl | ||
| match merged |
There was a problem hiding this comment.
You could make your life a whole lot easier if you just dump the merged GraphQL schema and compare it to an expected string. That'll also make it easier to understand the test. See https://docs.rs/graphql-parser/0.2.3/graphql_parser/#example-parse-and-format-schema for more info. It looks like given a GraphQL schema AST, dumping the schema is as simple as doing format!("{}", schema).
| match merged.document.get_object_type_definitions().iter().next() { | ||
| None => panic!("Failed to import placeholder for type `A`"), | ||
| Some(type_a) => { | ||
| // Has an id field | ||
| match type_a.fields.iter().find(|field| field.name.eq("id")) { | ||
| Some(_) => (), | ||
| _ => panic!("Placeholder for imported type does not have the correct fields"), | ||
| }; | ||
|
|
||
| // Has a placeholder directive | ||
| match type_a | ||
| .directives | ||
| .iter() | ||
| .find(|directive| directive.name.eq("placeholder")) | ||
| { | ||
| Some(_) => (), | ||
| _ => { | ||
| panic!("Imported type `A` does not have a `@placeholder` directive"); | ||
| } | ||
| } | ||
| } | ||
| }; |
There was a problem hiding this comment.
Same here (compare schema strings)
There was a problem hiding this comment.
Same in all other tests in this file. 😉
| // Cache entry is stale and an unstable import has changed or is now available | ||
| // TODO: Is it okay to ignore unstable imports which are no longer available? | ||
| // TODO: Make this threshold an envvar? | ||
| let requires_refresh = entry.last_refresh.elapsed().as_secs() >= 120 | ||
| && entry | ||
| .unstable_imports | ||
| .iter() | ||
| .any(|(schema_reference, subgraph_id_opt)| { | ||
| self.resolve_schema_reference(schema_reference) | ||
| .map(|schema| match subgraph_id_opt { | ||
| Some(subgraph_id) => schema.id.eq(subgraph_id), | ||
| None => true, | ||
| }) | ||
| .unwrap_or(false) | ||
| }); |
There was a problem hiding this comment.
Don't we also have to check the previously available schemas that were imported? Some of them might be gone now.
| if let Some(entry) = self.schema_cache.lock().unwrap().get(&subgraph_id) { | ||
| // Cache entry is stale and an unstable import has changed or is now available | ||
| // TODO: Is it okay to ignore unstable imports which are no longer available? | ||
| // TODO: Make this threshold an envvar? |
There was a problem hiding this comment.
Yes, an env var sounds good.
| .filter_map(|(schema_reference, schema)| match schema_reference { | ||
| SchemaReference::ByName(_) => { | ||
| Some((schema_reference.clone(), Some(schema.id.clone()))) | ||
| } | ||
| _ => None, | ||
| }) |
There was a problem hiding this comment.
Aren't references by ID also unstable, as they may or may not be available all the time?
4e04f73 to
f389c99
Compare
Implements graphprotocol/rfcs#6