graphql / graphql/graphql-spec

Proposal: Dot-notation projections as syntax sugar

Open
#467 3 comments 0 reactions 0 assignees View on GitHub
💭 Strawman (RFC 0)
Dominant language
JavaScript
Stars
14.6k
Forks
1.2k
PR merge metrics
No merged PRs in 30d

Description

## Brief Description:

This feature is just syntax sugar on top of existing features of GraphQL API. The dot-notation projection proposal is something like:

```
x.y.z
```

Which is expanded to:

```
x {
y {
z
}
}
```

The separator for the projection could be another token, such as `::` (for instance, `x::y::z`), but the goal here is to avoid too much typing and spare efforts.

---

## Rationale/why:

On large projects made of diverse relations, our queries & mutation payloads become quite complex. Indentation levels become deep, which hinders the source code reading. This syntax also favours and simplifies auto-complete toolings.

## Additional comments:

This feature is only useful for many-to-one relationships. On either one-to-many or many-to-many, we'll often resort to some kind of pagination (on most times, Relay/cursor-based). Nevertheless, the syntax can be extended to accept parameters on the last field of the chain of projections, for instance:

```
x.y.z(a: 1, b: 2, c: 3) {
field1
field2
# etc...
}
```

Being expanded to:

```
x {
y {
z(a: 1, b: 2, c: 3) {
field1
field2
# etc...
}
}
}
```

---

## Bad use cases:

The following code below is a counter-argument for this proposal:

```
hero(id: "vaan") {
mainWeapon.strength
mainWeapon.price
mainWeapon.description
}
```

Where a better and clean approach would just be:

```
hero(id: "vaan") {
mainWeapon {
strength
price
description
}
}
```

Or, who knows:

```
hero(id: "vaan").mainWeapon {
strength
price
description
}

```

The non-last parametrized fields are only "sound" on single-field projections, otherwise, a client could do that and thus break expansion:

```
hero(id: "vaan").mainWeapon {
strength
price
description
}

hero(id: "balthier").shield {
price
defense
}
```

Resulting in the following unsound/incorrect expansion:

```

hero(id: "vaan") {
mainWeapon {
strength
price
description
}
}

hero(id: "balthier") {
shield {
price
defense
}
}
```

---

## Compatibility breaking:

As far I'm concerned, there's no one.

## Cost analysis:

A new syntax is always a burden for compiler/parser writers. Despite that, because the syntax sugar expansion property, this syntax could be expanded before the parsing phase, and therefore, reuse the existing parsing/grammar rules already implemented.

---

I would like to hear opinions from you guys. Thanks in advance. :cat2:

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.