mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-14 17:02:49 +03:00
Add the SubgraphIdentifier
type (#613)
## Description Parallel to #611, in service of removing supergraph config, we'd like to map all current supergraph config into a generated subgraph. To ensure that we don't end up with an unfortunate naming collision, I've decided to refine the definition of a subgraph identifier to exclude any string starting with `__internal`, which we can then have as our "internal namespace". This change introduces the new type, and updates the "unknown_namespace" subgraph to come under this umbrella. This change should be a no-op to any user who hasn't used a subgraph name prefixed with `__internal`. <!-- Questions to consider answering: 1. What user-facing changes are being made? 2. What are issues related to this PR? (Consider adding `(close #<issue-no>)` to the PR title) 3. What is the conceptual design behind this PR? 4. How can this PR be tested/verified? 5. Does the PR have limitations? 6. Does the PR introduce breaking changes? --> ## Changelog User-defined subgraphs may no longer be given names that start with `__internal`, as this will be reserved for internally generated subgraphs. - Add a changelog entry (in the "Changelog entry" section below) if the changes in this PR have any user-facing impact. See [changelog guide](https://github.com/hasura/graphql-engine-mono/wiki/Changelog-Guide). - If no changelog is required ignore/remove this section and add a `no-changelog-required` label to the PR. ### Product _(Select all products this will be available in)_ - [x] community-edition - [x] cloud <!-- product : end : DO NOT REMOVE --> ### Type <!-- See changelog structure: https://github.com/hasura/graphql-engine-mono/wiki/Changelog-Guide#structure-of-our-changelog --> _(Select only one. In case of multiple, choose the most appropriate)_ - [ ] highlight - [ ] enhancement - [ ] bugfix - [x] behaviour-change - [ ] performance-enhancement - [ ] security-fix <!-- type : end : DO NOT REMOVE --> ### Changelog entry <!-- - Add a user understandable changelog entry - Include all details needed to understand the change. Try including links to docs or issues if relevant - For Highlights start with a H4 heading (#### <entry title>) - Get the changelog entry reviewed by your team --> User-defined subgraphs may no longer have names that start with `__internal`. <!-- changelog-entry : end : DO NOT REMOVE --> <!-- changelog : end : DO NOT REMOVE --> V3_GIT_ORIGIN_REV_ID: a6df1bba7b1f2cda4593654c15d168f25b7134b2
This commit is contained in:
parent
0b16216bad
commit
e4c5d7a752
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"version": "v2",
|
||||||
|
"subgraphs": [
|
||||||
|
{
|
||||||
|
"name": "__default",
|
||||||
|
"objects": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
__ is a reserved prefix for subgraph names at path $.subgraphs[0].name
|
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"version": "v2",
|
||||||
|
"subgraphs": [
|
||||||
|
{
|
||||||
|
"name": "default",
|
||||||
|
"objects": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -3645,7 +3645,7 @@
|
|||||||
"properties": {
|
"properties": {
|
||||||
"name": {
|
"name": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"pattern": "^[_a-zA-Z][_a-zA-Z0-9]*$"
|
"pattern": "^(?!__)[_a-zA-Z][_a-zA-Z0-9]*$"
|
||||||
},
|
},
|
||||||
"objects": {
|
"objects": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
|
@ -140,7 +140,7 @@ impl MetadataAccessor {
|
|||||||
match metadata {
|
match metadata {
|
||||||
Metadata::WithoutNamespaces(metadata) => {
|
Metadata::WithoutNamespaces(metadata) => {
|
||||||
let mut accessor: MetadataAccessor = MetadataAccessor::new_empty(None);
|
let mut accessor: MetadataAccessor = MetadataAccessor::new_empty(None);
|
||||||
load_metadata_objects(metadata, "unknown_namespace", &mut accessor);
|
load_metadata_objects(metadata, "__unknown_namespace", &mut accessor);
|
||||||
accessor
|
accessor
|
||||||
}
|
}
|
||||||
Metadata::Versioned(MetadataWithVersion::V1(metadata)) => {
|
Metadata::Versioned(MetadataWithVersion::V1(metadata)) => {
|
||||||
|
@ -101,3 +101,80 @@ impl<'de> Deserialize<'de> for Identifier {
|
|||||||
OpenDd::deserialize(serde_json::Value::deserialize(deserializer)?).map_err(D::Error::custom)
|
OpenDd::deserialize(serde_json::Value::deserialize(deserializer)?).map_err(D::Error::custom)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Macro to produce a validated subgraph identifier using a string literal that crashes if the
|
||||||
|
// literal is invalid. Does not work for non-literal strings to avoid use on user supplied input.
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! subgraph_identifier {
|
||||||
|
($name:literal) => {
|
||||||
|
open_dds::identifier::SubgraphIdentifier::new($name.to_string()).unwrap()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Type capturing a subgraph identifier used within the metadata. The wrapped String
|
||||||
|
/// is guaranteed to be a valid identifier, i.e.
|
||||||
|
/// - does not start with __
|
||||||
|
/// - starts with an alphabet or underscore
|
||||||
|
/// - all characters are either alphanumeric or underscore
|
||||||
|
#[derive(Serialize, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, derive_more::Display)]
|
||||||
|
pub struct SubgraphIdentifier(pub String);
|
||||||
|
|
||||||
|
impl SubgraphIdentifier {
|
||||||
|
pub fn new(string: String) -> Result<SubgraphIdentifier, &'static str> {
|
||||||
|
let Identifier(string) = Identifier::new(string)?;
|
||||||
|
|
||||||
|
if string.starts_with("__") {
|
||||||
|
return Err("__ is a reserved prefix for subgraph names");
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(SubgraphIdentifier(string))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_str(&self) -> &str {
|
||||||
|
self.0.as_str()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for SubgraphIdentifier {
|
||||||
|
type Target = String;
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OpenDd for SubgraphIdentifier {
|
||||||
|
fn deserialize(json: serde_json::Value) -> Result<Self, OpenDdDeserializeError> {
|
||||||
|
let string: String =
|
||||||
|
serde_json::from_value(json).map_err(|error| OpenDdDeserializeError {
|
||||||
|
error,
|
||||||
|
path: Default::default(),
|
||||||
|
})?;
|
||||||
|
SubgraphIdentifier::new(string).map_err(|e| OpenDdDeserializeError {
|
||||||
|
error: serde_json::Error::custom(e),
|
||||||
|
path: Default::default(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn json_schema(_gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
|
||||||
|
SchemaObjectVariant(SchemaObject {
|
||||||
|
instance_type: Some(schemars::schema::SingleOrVec::Single(Box::new(
|
||||||
|
schemars::schema::InstanceType::String,
|
||||||
|
))),
|
||||||
|
string: Some(Box::new(StringValidation {
|
||||||
|
pattern: Some("^(?!__)[_a-zA-Z][_a-zA-Z0-9]*$".to_string()),
|
||||||
|
..Default::default()
|
||||||
|
})),
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _schema_name() -> String {
|
||||||
|
"SubgraphIdentifier".to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _schema_is_referenceable() -> bool {
|
||||||
|
// This is a tiny leaf schema so just make it non-referenceable to avoid a layer of
|
||||||
|
// indirection in the overall JSONSchema.
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -258,7 +258,7 @@ impl Supergraph {
|
|||||||
#[derive(Serialize, Clone, Debug, PartialEq, opendds_derive::OpenDd)]
|
#[derive(Serialize, Clone, Debug, PartialEq, opendds_derive::OpenDd)]
|
||||||
#[opendd(json_schema(rename = "OpenDdSubgraph"))]
|
#[opendd(json_schema(rename = "OpenDdSubgraph"))]
|
||||||
pub struct Subgraph {
|
pub struct Subgraph {
|
||||||
pub name: identifier::Identifier,
|
pub name: identifier::SubgraphIdentifier,
|
||||||
pub objects: Vec<OpenDdSubgraphObject>,
|
pub objects: Vec<OpenDdSubgraphObject>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user