Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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
18 changes: 18 additions & 0 deletions .changeset/extra-query-avoid.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
hive-router-query-planner: patch
router: patch
node-addon: patch
---

# Avoid extra `query` prefix for anonymous queries

When there is no variable definitions and no operation name, GraphQL queries can be sent without the `query` prefix. For example, instead of sending:

```diff
- query {
+ {
user(id: "1") {
name
}
}
```
1 change: 1 addition & 0 deletions .gemini/styleguide.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,5 +86,6 @@ async fn handle(user: &User, req: &Request) -> Result<Response> {
We are using `knope` with changesets for declaring changes. If you detect a new file in a PR under `.changeset/` directory, please confirm the following rules:

- Every new `changesets` file that touches `query-planner` must have a `router` changeset - either in the same changeset or a separate changeset.
- Every new `changesets` file that touches `query-planner` must have a `node-addon` changeset - either in the same changeset or a separate changeset.
- Every new `changesets` file that touches `executor` must have a `query-planner` changeset - either in the same changeset or a separate changeset.
- If a PR touches `config` crate and adds/changes to the `HiveRouterConfig` struct, it must have a `router` changeset that contains a YAML example on how the configuration needs to be used.
154 changes: 77 additions & 77 deletions lib/query-planner/src/ast/normalization/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,16 +135,16 @@ mod tests {
.unwrap()
.to_string()
),
@r#"
query {
a: __typename
words
__typename
__schema {
__typename
}
}
"#
@r"
{
a: __typename
words
__typename
__schema {
__typename
}
}
"
);
}

Expand Down Expand Up @@ -179,11 +179,11 @@ mod tests {
.to_string()
),
@r#"
query {
words(sep: ",")
foo: words(len: 10, sep: ".")
}
"#
{
words(sep: ",")
foo: words(len: 10, sep: ".")
}
"#
);
}

Expand Down Expand Up @@ -261,14 +261,14 @@ mod tests {
.unwrap()
.to_string()
),
@r#"
query {
words
c: words(len: 1)
b: words
a: words
}
"#
@r"
{
words
c: words(len: 1)
b: words
a: words
}
"
);
}

Expand Down Expand Up @@ -386,7 +386,7 @@ mod tests {
.to_string()
),
@r"
query {
{
products {
... on Toaster {
t1
Expand Down Expand Up @@ -529,12 +529,12 @@ mod tests {

insta::assert_snapshot!(
pretty_query(r.to_string()),
@r###"
query {
@r#"
{
one: words(len: 10, sep: ".")
two: words(len: 10, sep: ".")
}
"###
"#
);
}

Expand Down Expand Up @@ -697,7 +697,7 @@ mod tests {
.to_string()
),
@r"
query {
{
userFromA {
profile {
displayName
Expand Down Expand Up @@ -792,7 +792,7 @@ mod tests {
.to_string()
),
@r"
query {
{
products {
id
... on Book {
Expand Down Expand Up @@ -841,13 +841,13 @@ mod tests {
.to_string()
),
@r"
query {
anotherUsers {
id
name
username
}
}
{
anotherUsers {
id
name
username
}
}
",
);
}
Expand Down Expand Up @@ -885,19 +885,19 @@ mod tests {
.to_string()
),
@r"
query {
userFromA {
profile {
... on AdminAccount {
accountType
}
... on GuestAccount {
accountType
{
userFromA {
profile {
... on AdminAccount {
accountType
}
... on GuestAccount {
accountType
}
}
}
}
}
",
",
);
}

Expand Down Expand Up @@ -940,20 +940,20 @@ mod tests {
.to_string()
),
@r"
query {
userFromA {
profile {
... on AdminAccount {
accountType
}
... on GuestAccount {
accountType
guestToken
{
userFromA {
profile {
... on AdminAccount {
accountType
}
... on GuestAccount {
accountType
guestToken
}
}
}
}
}
",
",
);
}

Expand Down Expand Up @@ -1185,7 +1185,7 @@ mod tests {
.to_string()
),
@r"
query {
{
results {
__typename
... on MultipleColor {
Expand Down Expand Up @@ -1265,27 +1265,27 @@ mod tests {
.to_string()
),
@r"
query {
results {
__typename
... on MultipleColor {
id
name
colorOptions {
id
color
}
}
... on SingleColor {
id
name
colorOption {
id
color
}
}
{
results {
__typename
... on MultipleColor {
id
name
colorOptions {
id
color
}
}
... on SingleColor {
id
name
colorOption {
id
color
}
}
}
}
"
);
}
Expand Down
10 changes: 10 additions & 0 deletions lib/query-planner/src/ast/operation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,16 @@ impl PrettyDisplay for SubgraphFetchOperation {

impl Display for OperationDefinition {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if self
.operation_kind
.as_ref()
.is_none_or(|k| matches!(k, OperationKind::Query))
&& self.name.as_deref().is_none_or(str::is_empty)
&& self.variable_definitions.as_ref().is_none_or(Vec::is_empty)
{
// Short form for anonymous query
return self.selection_set.fmt(f);
}
if let Some(operation_kind) = &self.operation_kind {
write!(f, "{}", operation_kind)?;
}
Expand Down
Loading
Loading