graphql / graphql-spec

GraphQL is a query language and execution engine tied to any backend service.
https://spec.graphql.org
14.31k stars 1.13k forks source link

Proposal: Split spec into parts: Queries, Mutations, Subscriptions to encourage modular implementations #478

Closed idibidiart closed 6 years ago

idibidiart commented 6 years ago

Proposal

There should be three (3) GraphQL specs, for Queries, Mutations and Subscriptions.

When I looked at GraphQL-JS on Github which is supposed to be the Reference Implementation of the GraphQL spec, it seems to include Queries, Mutations and Subscriptions.

Sometimes we just need the Queries capability or Queries and Mutations but not Subscriptions.

By splitting the GraphQL spec into the three aforementioned parts (this Proposal) it will encourage modular implementations.

Thanks,

leebyron commented 6 years ago

Given that Mutations and Subscriptions only comprise a couple sections of the spec, I'm not sure removing them into separate spec document accomplishes anything of value.

Are you concerned that your GraphQL implementation is not spec compliant because it does not include mutations or subscriptions? http://facebook.github.io/graphql/June2018/#sec-Root-Operation-Types claims that Mutation and Subscription types are not required in a GraphQL service

leebyron commented 6 years ago

This might also be a challenge since aspects of GraphQL like Introspection make reference to mutation and subscription root types - presumably any service, even if only supporting queries, would need to respond well to introspection queries that reference these

idibidiart commented 6 years ago

This might also be a challenge since aspects of GraphQL like Introspection make reference to mutation and subscription root types - presumably any service, even if only supporting queries, would need to respond well to introspection queries that reference these

Hmm. I didn't think about that, but I'm not sure the service needs to respond to introspection queries referencing mutation and subscription root types with anything other than indicating lack of support for those queries. This way the spec is untangled.

Ideally, I should be able to implement separate concepts (Queries, Mutations, Subscriptions) separately. Subscriptions can conform to the GraphQL-Subscriptions spec but be used with Non-GraphQL Mutations. Why not? Same with Mutations, which can conform to the GraphQL-Mutations spec but be used with Non-GraphQL Subscriptions (like notifications streamed from the db's change log in some custom format using some streaming API with exactly-once processing, etc...)

idibidiart commented 6 years ago

I know all of it can be done today if you don't mind having more code to maintain than you have to (why should I implement GraphQL Mutations if I only need GraphQL Queries? Imagine I have to combine GraphQL Queries with Non-GraphQL Mutations (e.g. writes coming over Kafka Streams API directly from clients that are outside my scope of responsibility)

The question is why as implementor do I need to implement parts of the spec that I have no use for? Why are completely separate (or should be separate) concepts bundled together in one spec? What is special about the 'Queries, Subscriptions, Mutations' set that makes it immune to decomposition?

jlouis commented 6 years ago

At a point you can definitely build a process which follows Python's PEP (Python Enhancement Proposal), The Bittorrent BEP (Bittorrent enhancement proposal), or the scheme SRFI (Scheme Requests for Implementation).

The idea is that you have a base system which is the minimum requirement for compliance, and extensions are then numbered as BEP5, BEP17 and so on. Clients experimentally build those and they then become standardized later if enough clients de-facto implements them.

BitTorrent had the Azureus/Vuze client which were built in Java and was adding features at a much faster pace than every other client, and their features were rarely the ones the rest of the community ended up using. So all the BEPs were written down, and people steered around those proposals and implemented the other proposals (which were then accepted into the standard eventually).

Specifications evolve. Support the evolution.

I was afraid the Jun2018 specification would be bloated and mess up things, but luckily my worry was only that: a worry. The changes are mostly clarifications, and sensible extensions. It will take some time to adapt my GraphQL server code base, but we are slowly getting there :)

idibidiart commented 6 years ago

@jlouis yes that is exactly what I was hinting at but did not want to get into the how ahead of agreeing on the what of the proposal. The reference you make to the BitTorrent Azureus/Vuze client reminds me of Apollo server/client.

Thank you for framing it in historical context. I agree 100% that we need this kind of thinking in order for GraphQL to evolve naturally.

Maybe 3 years down the line someone will reference this and come out with the base spec and reference implementation that will support spec extensions in the way you described.

But for now I am getting massive resistance on Twitter (see discussions under my handle @marcfawzi)

@stubailo compared the argument to someone not wanting to use Underscore because they only need a few functions from it. I had to state that it’s about implementation cost not usage cost

I love your framing. Thank you. I think the case is pretty clear now.

I look forward to this getting resurrected in a few years when the community realizes that they need to have that level of abstraction in the process.

idibidiart commented 6 years ago

To be clear, the base case for me is Queries.

Everything above that (Mutations, Live Queries, Cache, Subscriptions, etc) should be an extension, IMO.

What is special about queries? Without them GraphQL is meaningless. I can’t say the same about Mutations and Subscriptions, as well as all other non-standard features out there.

leebyron commented 6 years ago

I’m also a big fan of PEP and the additive nature of spec proposals as they gain adoption. In fact, we’ve been following a related process with RFC documents. Subscriptions went through this process and was an RFC only for almost 2 years before being added to the spec (with minimal requirements). Another good example is the GraphQLHTTP spec which is intended to forever be a separate document.

What I’m more skeptical about is backwards breaking changes that remove functionality from the current spec into separate documents without a highly compelling reason to do so.

In this case what I mean by highly compelling is that it should unlock the ability to do something that is currently not possible today.

If it does not do at least that then we’re looking at pure cost (breaking changes, harder to read spec, more opportunity for ambiguity) with only theoretical benefit of creating “modular concepts”.

I’m not excited to put in the work for something that is net-costly instead of net-beneficial.

idibidiart commented 6 years ago

Fair enough. The onus on us (the community) to come up with a compelling case. I believe I have one at the moment (on the roadmap) but will be better informed when we do the actual work.

idibidiart commented 6 years ago

To clarify, the use case can be done with GraphQL as is today but it should demonstrate how a PEP-like process would allow us to contribute to the spec and partake in its evolution, as opposed to many folks in our position doing custom work in isolation.

That is the key point of this proposal.

I'll leave this open for a few days then close it, in case other have any other input.