graphql-spec icon indicating copy to clipboard operation
graphql-spec copied to clipboard

added mutation op type to examples 193, 194

Open rivantsov opened this issue 3 years ago • 17 comments

The examples clearly show mutating fields (changeBirthday); since mutating fields are allowed only on top level, we clearly see the 'top' level of mutation request; however, there is no op type 'mutation' before the first opening brace. If op type is missing, it is assumed to be query.

rivantsov avatar Aug 03 '22 06:08 rivantsov

Deploy Preview for graphql-spec-draft ready!

Name Link
Latest commit d490572965bcfcfd7d5b27471ffa3ca61f843c21
Latest deploy log https://app.netlify.com/sites/graphql-spec-draft/deploys/62ea16908505940008f19430
Deploy Preview https://deploy-preview-984--graphql-spec-draft.netlify.app/draft
Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site settings.

netlify[bot] avatar Aug 03 '22 06:08 netlify[bot]

@benji the commentary text does not matter, the examples should be CORRECT GraphQL docs, on their own. Unless of course you show a mistake. Again, my reasoning - we are seeing top level, entire DOC.

rivantsov avatar Aug 03 '22 07:08 rivantsov

Just for reference (I also stumbled over this and thought of it as a mistake at first), I opened a PR some months back that proposes an additional note that makes it very explicit that these examples depict selection sets. https://github.com/graphql/graphql-spec/pull/926

thomasheyenbrock avatar Aug 03 '22 08:08 thomasheyenbrock

What I really do not understand is this RESISTANCE to this simple change. If we add 'mutation' - will it change the story you are telling here, about executing selection sets? I think NO, the message/text will be the same. What it will do is - make the example into a VALID GraphQL executable document, and will shut up the annoying guys like Roman, who keep asking a question like "Why we show invalid document in an example, but format/color it as a CORRECT doc"?!

If you say it is not a complete doc, it's just part - then just give me an example of full valid executable doc with this part included. I can think about just one way to do it - same thing with 'mutation' before the first opening brace.

rivantsov avatar Aug 03 '22 16:08 rivantsov

@romanivantsov it would be inconsistent with the spec text that states:

For example, given the following selection set to be executed serially:

It looks at the execution behavior for the selection set and not for the operation as a whole.

@benjie I think an extra note can make this clearer, although the text is pretty clear on this. In general this is something people stumbled on more than once so I think lets add a note from #926 (merge it) and close this #984.

michaelstaib avatar Aug 03 '22 17:08 michaelstaib

@michaelstaib again, why adding notes which might confuse even more, rather than simply adding 'mutation' and ending all confusions? Mutation sets are 'selection sets', they return data which can be expanded/sub-selected more. Nothing in the surrounding text needs to be changed.

Clearly I am not the only one who finds it confusing thanks

rivantsov avatar Aug 03 '22 17:08 rivantsov

There are not Mutation sets there are only selection sets. IMO its the smaller change to do. The section talks about selection sets and execution behavior, not about operations.

michaelstaib avatar Aug 03 '22 17:08 michaelstaib

Or more clearly I would say its about the executor and how the executor will execute a given selection set. You would not have a mutation executor or a query executor but executor dealing with a certain execution behavior. graphql-dotnet for instance implemented these as strategies, we had the same in Hot Chocolate with version 10 before we moved to execution plans.

in graphql-js it looks like this:

function executeFieldsSerially(
  exeContext: ExecutionContext,
  parentType: GraphQLObjectType,
  sourceValue: unknown,
  path: Path | undefined,
  fields: Map<string, ReadonlyArray<FieldNode>>,
): PromiseOrValue<ObjMap<unknown>> {
  return promiseReduce(
    fields.entries(),
    (results, [responseName, fieldNodes]) => {
      const fieldPath = addPath(path, responseName, parentType.name);
      const result = executeField(
        exeContext,
        parentType,
        sourceValue,
        fieldNodes,
        fieldPath,
      );
      if (result === undefined) {
        return results;
      }
      if (isPromise(result)) {
        return result.then((resolvedResult) => {
          results[responseName] = resolvedResult;
          return results;
        });
      }
      results[responseName] = result;
      return results;
    },
    Object.create(null),
  );
}

Where you get passed in a list of grouped fields. This section explains to the reader how such an executor shall do its work not how a mutation is executed.

Further these executors can also be used in other cases. For instance, if we detect that we have a scoped ef core context in a selections set we will make sure to use serial execution since it is not thread safe. Just as an example that relates more to your world of thinking.

michaelstaib avatar Aug 03 '22 18:08 michaelstaib

We have mooted the idea of having GraphQL provide serial execution in more selection set locations in the past a few times (e.g. when talking about nested mutations if I recall correctly); so it's important to talk about serial execution of a selection set, rather than specifically execution of a mutation operation.

benjie avatar Aug 03 '22 18:08 benjie

This comment surprises me. If this has been mooted several times... presumably we do not expect this to change?... and there is only one case of serial execution by spec... root mutation fields, so wouldn't it be misleading to speak of serial execution generally in term of selection sets?

yaacovCR avatar Aug 03 '22 18:08 yaacovCR

It’s never been ruled out, it just doesn’t have a champion yet. GraphQL has many things like that, waiting for someone to pick up the torch and push them forward.

benjie avatar Aug 03 '22 18:08 benjie

Guys, I do not mind an example showing 'serial execution of selection sets', for whatever reason the SERIAL execution is selected. Service is free to choose any way.

It is the names of the fields: changeBirthday, changeTheNumber - these are clearly mutating fields, which means the operation is mutation. The example GraphQL is 'internally inconsistent'. What if you change the names to getBirthday, getTheNumber? it would make the example internally consistent - it is a query, or part of the query subtree. And then, since the service can execute it 'normally' (either parallel or serial), you can say: "Assuming the service chooses to execute this selection set serially, then here's how it should do it etc".

I would absolutely have no objections, everything is consistent now.

rivantsov avatar Aug 03 '22 19:08 rivantsov

Right, but I guess my point is that the spec as currently defined only has one serial execution and so it does NOT seem currently important to describe how that might work generally within the spec, as opposed to how it works in the context of mutations, which is the only selection set in which it is specified to work.

Either way, I agree with @rivantsov that the current text is ambiguous and confusing, with a change helpful. I am ultimately agnostic, however, as to whether we should change the example to include the mutation operation or just add a note.

yaacovCR avatar Aug 03 '22 19:08 yaacovCR

@yaacovCR , not sure what you mean:

the spec as currently defined only has one serial execution

the spec dictates SERIAL for mutation, but for queries it leaves the freedom of choice to service implementors; it is called 'execute normally' meaning parallel or serial, service's choice

rivantsov avatar Aug 03 '22 19:08 rivantsov

Indeed, implementation choice, so as you say, the example is talking about a mutation. The only reason that serial execution should be described in the spec is because of mutation root fields. Otherwise it is no different than reverse serial order, which is an implementation choice, but not described.

@benjie is correct that the example is referring to the selection set of a mutation rather than a query, and is correct as written, but as there is no way to distinguish within the example text between a default query operation and a selection set, I favor a change, either a note, or a change to reference the whole document. At this exact point, I favor a note, because I think in the long run it may be beneficial to remind spec readers that the spec may refer to a selection set, and get them used to that rather than have them always assume a leading curly brace is a query operation. It would be kind of limiting if we said the spec could never refer to selection sets in ANY example without including an operation...

yaacovCR avatar Aug 03 '22 19:08 yaacovCR

A mutation operation is not the only place in which a selection set must be executed serially even in the current GraphQL spec; both inline and named fragments may also be executed serially when referenced inside the mutation type:

mutation {
  ... {
    doTheThing
  }
  ...Frag
}

fragment Frag on Mutation {
  doTheThingAgain: doTheThing
}

benjie avatar Aug 04 '22 11:08 benjie

This is a duplicate of https://github.com/graphql/graphql-spec/pull/926

benjie avatar Nov 10 '23 13:11 benjie