Coder Social home page Coder Social logo

Comments (10)

dschafer avatar dschafer commented on April 30, 2024 10

And to finish: how the client is supposed to send which operation to run if there are many operations in the document ?

Up to the server; the reference implementation just has the operationName as another parameter, so I could imagine having a HTTP Param for the operation name.

Until now I imagined graphql as a simple GraphQLQuery => Server => Response behavior. The client sending its query in string at a server endpoint. So I'm a bit disappointed by this many-operations document :-/

This is definitely the right way to think about things; a Document is just an additional concept that can contain many GraphQLQueries. If you send a document with only one query, then graphql is just QueryInDocument => Server => Response. If the document has many queries, then you specify a query so that we can go Document => Query => Server => Response

So now what wonder me is... what's the point of having a document that can contains many operations ?

The use is threefold:

  1. It's often useful to store GraphQL documents in a client side file; we use .graphql files on iOS and Android for this. We wanted the parser to work on these files as well (so the parser is universal), but you can (and we often do) include multiple queries in a single document.
  2. One optimization that can be made (and that we'll discuss in more detail in the future, I'm sure) is "persisting" documents; you send the document to the server who stores it for you and gives you an identifier for that, that way you don't have to send the whole document string up every time. If you do that, you can send a document up with all your queries, and then pass the document ID + operation name over the wire. This would optimize bytes being sent from the client to the server.
  3. It's possible to write a "batch" API for GraphQL, where you use the results from one query as the parameters to another. We're still working out the exact details there, but if you do that, it's useful to specify multiple queries in a single document; you'd specify which one you wanted to run at the start and the relationships between them.

You're absolutely correct that in the model we describe (pass a string to the server, get a response back), a Document with multiple operations isn't that useful; we wanted to permit it for the reasons described above.

from graphql-spec.

twidi avatar twidi commented on April 30, 2024 1

Ok I understand, thank you. I understood that the executor could only handle one operation at a time but maybe it could have been called many times one operation after the other.

So now what wonder me is... what's the point of having a document that can contains many operations ?

from graphql-spec.

dschafer avatar dschafer commented on April 30, 2024

For example what is the expected answer for this graphql query (dumb query just for the example):

We'd describe that as a Document at the parser layer that contains two Operations: LukeAndLeiaNames and LukeAndLeiaHomePlanet.

When executing, we need to know which Operation to run; http://facebook.github.io/graphql/#sec-Evaluating-requests covers this in the spec and https://github.com/graphql/graphql-js/blob/master/src/executor/executor.js#L162-168 in the reference implementation.

If you only have one operation in a Document, the common case, then it's implied to run that one. If you have more than one, you specify which operation to run in a given execution.

Hope this helps!

from graphql-spec.

twidi avatar twidi commented on April 30, 2024

@dschafer thanks for your answer but it doesn't help me a lot. I understand how it is supposed to work internally.

But, let's forget the server, consider it a black box and imagine I am a client.

If I send this document:

query LukeAndLeiaNames {
    luke: human(id: "1000") {
        name
    }
    leia: human(id: "1003") {
        name
    }
}

query LukeAndLeiaHomePlanet {
    luke: human(id: "1000") {
        homePlanet
    }
    leia: human(id: "1003") {
        homePlanet
    }
}

What do I get in response from the server?

from graphql-spec.

dschafer avatar dschafer commented on April 30, 2024

What do I get in response from the server?

An error. The Document contained multiple operations and the client didn't specify which one to run. If you wanted to send that document and run one specific query, you could pass an operationName parameter.

The spec:

To evaluate a request, the executor must have a parsed Document (as defined in the “Query Language” part of this spec) and a selected operation name to run.

The executor should find the Operation in the Document with the given operation name. If no such operation exists, the executor should throw an error. If the operation is found, then the result of evaluating the request should be the result of evaluating the operation according to the “Evaluating operations” section.

In our reference implementation, we implemented a helper where if there's only one operation in the document, it's implied that the operation name is the name of that operation (since that simplifies the common case). But you can't run multiple queries in the same request; if that's the desired behavior, a single query that combines them can be run instead. With fragments, that would become simple:

query LukeAndLeiaNames {
    ...LukeAndLeiaNamesFragment
}

fragment LukeAndLeiaNamesFragment on Query {
    luke: human(id: "1000") {
        name
    }
    leia: human(id: "1003") {
        name
    }
}

query LukeAndLeiaHomePlanet {
    ...LukeAndLeiaHomePlanetFragment
}

fragment LukeAndLeiaHomePlanetFragment on Query {
    luke: human(id: "1000") {
        homePlanet
    }
    leia: human(id: "1003") {
        homePlanet
    }
}

query LukeAndLeiaBoth {
    ...LukeAndLeiaHomePlanetFragment
    ...LukeAndLeiaNamesFragment
}

from graphql-spec.

twidi avatar twidi commented on April 30, 2024

And to finish: how the client is supposed to send which operation to run if there are many operations in the document ?

Until now I imagined graphql as a simple GraphQLQuery => Server => Response behavior. The client sending its query in string at a server endpoint. So I'm a bit disappointed by this many-operations document :-/

from graphql-spec.

twidi avatar twidi commented on April 30, 2024

Ok thanks a lot for your answers. I started to think like that about the argument for the operation to run, and for the "storage" of queries on the server (like redis does for lua scripts).

I now have a better understanding of the whole thing and can go back to my graphql server in python.

Thanks a lot.

from graphql-spec.

dschafer avatar dschafer commented on April 30, 2024

Thanks for the great questions!

from graphql-spec.

verneleem avatar verneleem commented on April 30, 2024

@dschafer I saw this and it peaked my curiosity. Did this ever make it into the spec? I haven't been able to find it anywhere yet.

It's possible to write a "batch" API for GraphQL, where you use the results from one query as the parameters to another. We're still working out the exact details there, but if you do that, it's useful to specify multiple queries in a single document; you'd specify which one you wanted to run at the start and the relationships between them.

from graphql-spec.

benjie avatar benjie commented on April 30, 2024

There's not an official spec for Facebook's implementation as far as I know; but Hot Chocolate have great documentation around their implementation of it via the @export directive: https://chillicream.com/docs/hotchocolate/v10/execution-engine/batching/#introduction there's also quite a long discussion here: graphql/graphql-over-http#5

from graphql-spec.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.