Skip to content

Proposal: Dot-notation projections as syntax sugar #467

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
marcoonroad opened this issue Jun 15, 2018 · 3 comments
Open

Proposal: Dot-notation projections as syntax sugar #467

marcoonroad opened this issue Jun 15, 2018 · 3 comments
Labels
💭 Strawman (RFC 0) RFC Stage 0 (See CONTRIBUTING.md)

Comments

@marcoonroad
Copy link

marcoonroad commented Jun 15, 2018

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. 🐈

@marcoonroad
Copy link
Author

marcoonroad commented Jun 15, 2018

It's strongly related (and possibly duplicated) of #174. Also related with #249.

@leebyron
Copy link
Collaborator

leebyron commented Oct 2, 2018

I'm concerned that this adds complexity and weight without adding much value. Generally I prefer there be only one way to express something. This proposal doesn't unlock any new use cases. Also, accepting this proposal would make #174 not possible, so the complexity cost here is real.

this syntax could be expanded before the parsing phase, and therefore, reuse the existing parsing/grammar rules already implemented.

Unfortunately that means this syntax would be only transient. Printing an AST would not be able to create this syntax.

@leebyron
Copy link
Collaborator

leebyron commented Oct 2, 2018

I'll leave this issue open as "Strawman" for now, but I think we need a much more compelling argument for why this is worth the cost.

@leebyron leebyron added the 💭 Strawman (RFC 0) RFC Stage 0 (See CONTRIBUTING.md) label Oct 2, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
💭 Strawman (RFC 0) RFC Stage 0 (See CONTRIBUTING.md)
Projects
None yet
Development

No branches or pull requests

2 participants