GraphQL is a query language and execution engine tied to any backend service.

Related tags

GraphQL graphql-spec
Overview

GraphQL

GraphQL Logo

The GraphQL specification is edited in the markdown files found in /spec the latest release of which is published at https://graphql.github.io/graphql-spec/.

The latest draft specification can be found at https://graphql.github.io/graphql-spec/draft/ which tracks the latest commit to the master branch in this repository.

Previous releases of the GraphQL specification can be found at permalinks that match their release tag. For example, https://graphql.github.io/graphql-spec/October2016/. If you are linking directly to the GraphQL specification, it's best to link to a tagged permalink for the particular referenced version.

Overview

This is a Working Draft of the Specification for GraphQL, a query language for APIs created by Facebook.

The target audience for this specification is not the client developer, but those who have, or are actively interested in, building their own GraphQL implementations and tools.

In order to be broadly adopted, GraphQL will have to target a wide variety of backends, frameworks, and languages, which will necessitate a collaborative effort across projects and organizations. This specification serves as a point of coordination for this effort.

Looking for help? Find resources from the community.

Getting Started

GraphQL consists of a type system, query language and execution semantics, static validation, and type introspection, each outlined below. To guide you through each of these components, we've written an example designed to illustrate the various pieces of GraphQL.

This example is not comprehensive, but it is designed to quickly introduce the core concepts of GraphQL, to provide some context before diving into the more detailed specification or the GraphQL.js reference implementation.

The premise of the example is that we want to use GraphQL to query for information about characters and locations in the original Star Wars trilogy.

Type System

At the heart of any GraphQL implementation is a description of what types of objects it can return, described in a GraphQL type system and returned in the GraphQL Schema.

For our Star Wars example, the starWarsSchema.js file in GraphQL.js defines this type system.

The most basic type in the system will be Human, representing characters like Luke, Leia, and Han. All humans in our type system will have a name, so we define the Human type to have a field called "name". This returns a String, and we know that it is not null (since all Humans have a name), so we will define the "name" field to be a non-nullable String. Using a shorthand notation that we will use throughout the spec and documentation, we would describe the human type as:

type Human {
  name: String
}

This shorthand is convenient for describing the basic shape of a type system; the JavaScript implementation is more full-featured, and allows types and fields to be documented. It also sets up the mapping between the type system and the underlying data; for a test case in GraphQL.js, the underlying data is a set of JavaScript objects, but in most cases the backing data will be accessed through some service, and this type system layer will be responsible for mapping from types and fields to that service.

A common pattern in many APIs, and indeed in GraphQL is to give objects an ID that can be used to refetch the object. So let's add that to our Human type. We'll also add a string for their home planet.

type Human {
  id: String
  name: String
  homePlanet: String
}

Since we're talking about the Star Wars trilogy, it would be useful to describe the episodes in which each character appears. To do so, we'll first define an enum, which lists the three episodes in the trilogy:

enum Episode { NEWHOPE, EMPIRE, JEDI }

Now we want to add a field to Human describing what episodes they were in. This will return a list of Episodes:

type Human {
  id: String
  name: String
  appearsIn: [Episode]
  homePlanet: String
}

Now, let's introduce another type, Droid:

type Droid {
  id: String
  name: String
  appearsIn: [Episode]
  primaryFunction: String
}

Now we have two types! Let's add a way of going between them: humans and droids both have friends. But humans can be friends with both humans and droids. How do we refer to either a human or a droid?

If we look, we note that there's common functionality between humans and droids; they both have IDs, names, and episodes in which they appear. So we'll add an interface, Character, and make both Human and Droid implement it. Once we have that, we can add the friends field, that returns a list of Characters.

Our type system so far is:

enum Episode { NEWHOPE, EMPIRE, JEDI }

interface Character {
  id: String
  name: String
  friends: [Character]
  appearsIn: [Episode]
}

type Human implements Character {
  id: String
  name: String
  friends: [Character]
  appearsIn: [Episode]
  homePlanet: String
}

type Droid implements Character {
  id: String
  name: String
  friends: [Character]
  appearsIn: [Episode]
  primaryFunction: String
}

One question we might ask, though, is whether any of those fields can return null. By default, null is a permitted value for any type in GraphQL, since fetching data to fulfill a GraphQL query often requires talking to different services that may or may not be available. However, if the type system can guarantee that a type is never null, then we can mark it as Non Null in the type system. We indicate that in our shorthand by adding an "!" after the type. We can update our type system to note that the id is never null.

Note that while in our current implementation, we can guarantee that more fields are non-null (since our current implementation has hard-coded data), we didn't mark them as non-null. One can imagine we would eventually replace our hardcoded data with a backend service, which might not be perfectly reliable; by leaving these fields as nullable, we allow ourselves the flexibility to eventually return null to indicate a backend error, while also telling the client that the error occurred.

enum Episode { NEWHOPE, EMPIRE, JEDI }

interface Character {
  id: String!
  name: String
  friends: [Character]
  appearsIn: [Episode]
}

type Human implements Character {
  id: String!
  name: String
  friends: [Character]
  appearsIn: [Episode]
  homePlanet: String
}

type Droid implements Character {
  id: String!
  name: String
  friends: [Character]
  appearsIn: [Episode]
  primaryFunction: String
}

We're missing one last piece: an entry point into the type system.

When we define a schema, we define an object type that is the basis for all queries. The name of this type is Query by convention, and it describes our public, top-level API. Our Query type for this example will look like this:

type Query {
  hero(episode: Episode): Character
  human(id: String!): Human
  droid(id: String!): Droid
}

In this example, there are three top-level operations that can be done on our schema:

  • hero returns the Character who is the hero of the Star Wars trilogy; it takes an optional argument that allows us to fetch the hero of a specific episode instead.
  • human accepts a non-null string as a query argument, a human's ID, and returns the human with that ID.
  • droid does the same for droids.

These fields demonstrate another feature of the type system, the ability for a field to specify arguments that configure their behavior.

When we package the whole type system together, defining the Query type above as our entry point for queries, this creates a GraphQL Schema.

This example just scratched the surface of the type system. The specification goes into more detail about this topic in the "Type System" section, and the type directory in GraphQL.js contains code implementing a specification-compliant GraphQL type system.

Query Syntax

GraphQL queries declaratively describe what data the issuer wishes to fetch from whoever is fulfilling the GraphQL query.

For our Star Wars example, the starWarsQueryTests.js file in the GraphQL.js repository contains a number of queries and responses. That file is a test file that uses the schema discussed above and a set of sample data, located in starWarsData.js. This test file can be run to exercise the reference implementation.

An example query on the above schema would be:

query HeroNameQuery {
  hero {
    name
  }
}

The initial line, query HeroNameQuery, defines a query with the operation name HeroNameQuery that starts with the schema's root query type; in this case, Query. As defined above, Query has a hero field that returns a Character, so we'll query for that. Character then has a name field that returns a String, so we query for that, completing our query. The result of this query would then be:

{
  "hero": {
    "name": "R2-D2"
  }
}

Specifying the query keyword and an operation name is only required when a GraphQL document defines multiple operations. We therefore could have written the previous query with the query shorthand:

{
  hero {
    name
  }
}

Assuming that the backing data for the GraphQL server identified R2-D2 as the hero. The response continues to vary based on the request; if we asked for R2-D2's ID and friends with this query:

query HeroNameAndFriendsQuery {
  hero {
    id
    name
    friends {
      id
      name
    }
  }
}

then we'll get back a response like this:

{
  "hero": {
    "id": "2001",
    "name": "R2-D2",
    "friends": [
      {
        "id": "1000",
        "name": "Luke Skywalker"
      },
      {
        "id": "1002",
        "name": "Han Solo"
      },
      {
        "id": "1003",
        "name": "Leia Organa"
      }
    ]
  }
}

One of the key aspects of GraphQL is its ability to nest queries. In the above query, we asked for R2-D2's friends, but we can ask for more information about each of those objects. So let's construct a query that asks for R2-D2's friends, gets their name and episode appearances, then asks for each of their friends.

query NestedQuery {
  hero {
    name
    friends {
      name
      appearsIn
      friends {
        name
      }
    }
  }
}

which will give us the nested response

{
  "hero": {
    "name": "R2-D2",
    "friends": [
      {
        "name": "Luke Skywalker",
        "appearsIn": ["NEWHOPE", "EMPIRE", "JEDI"],
        "friends": [
          { "name": "Han Solo" },
          { "name": "Leia Organa" },
          { "name": "C-3PO" },
          { "name": "R2-D2" }
        ]
      },
      {
        "name": "Han Solo",
        "appearsIn": ["NEWHOPE", "EMPIRE", "JEDI"],
        "friends": [
          { "name": "Luke Skywalker" },
          { "name": "Leia Organa" },
          { "name": "R2-D2" }
        ]
      },
      {
        "name": "Leia Organa",
        "appearsIn": ["NEWHOPE", "EMPIRE", "JEDI"],
        "friends": [
          { "name": "Luke Skywalker" },
          { "name": "Han Solo" },
          { "name": "C-3PO" },
          { "name": "R2-D2" }
        ]
      }
    ]
  }
}

The Query type above defined a way to fetch a human given their ID. We can use it by hardcoding the ID in the query:

query FetchLukeQuery {
  human(id: "1000") {
    name
  }
}

to get

{
  "human": {
    "name": "Luke Skywalker"
  }
}

Alternately, we could have defined the query to have a query parameter:

query FetchSomeIDQuery($someId: String!) {
  human(id: $someId) {
    name
  }
}

This query is now parameterized by $someId; to run it, we must provide that ID. If we ran it with $someId set to "1000", we would get Luke; set to "1002", we would get Han. If we passed an invalid ID here, we would get null back for the human, indicating that no such object exists.

Notice that the key in the response is the name of the field, by default. It is sometimes useful to change this key, for clarity or to avoid key collisions when fetching the same field with different arguments.

We can do that with field aliases, as demonstrated in this query:

query FetchLukeAliased {
  luke: human(id: "1000") {
    name
  }
}

We aliased the result of the human field to the key luke. Now the response is:

{
  "luke": {
    "name": "Luke Skywalker"
  }
}

Notice the key is "luke" and not "human", as it was in our previous example where we did not use the alias.

This is particularly useful if we want to use the same field twice with different arguments, as in the following query:

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

We aliased the result of the first human field to the key luke, and the second to leia. So the result will be:

{
  "luke": {
    "name": "Luke Skywalker"
  },
  "leia": {
    "name": "Leia Organa"
  }
}

Now imagine we wanted to ask for Luke and Leia's home planets. We could do so with this query:

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

but we can already see that this could get unwieldy, since we have to add new fields to both parts of the query. Instead, we can extract out the common fields into a fragment, and include the fragment in the query, like this:

query UseFragment {
  luke: human(id: "1000") {
    ...HumanFragment
  }
  leia: human(id: "1003") {
    ...HumanFragment
  }
}

fragment HumanFragment on Human {
  name
  homePlanet
}

Both of those queries give this result:

{
  "luke": {
    "name": "Luke Skywalker",
    "homePlanet": "Tatooine"
  },
  "leia": {
    "name": "Leia Organa",
    "homePlanet": "Alderaan"
  }
}

The UseFragment and DuplicateFields queries will both get the same result, but UseFragment is less verbose; if we wanted to add more fields, we could add it to the common fragment rather than copying it into multiple places.

We defined the type system above, so we know the type of each object in the output; the query can ask for that type using the special field __typename, defined on every object.

query CheckTypeOfR2 {
  hero {
    __typename
    name
  }
}

Since R2-D2 is a droid, this will return

{
  "hero": {
    "__typename": "Droid",
    "name": "R2-D2"
  }
}

This was particularly useful because hero was defined to return a Character, which is an interface; we might want to know what concrete type was actually returned. If we instead asked for the hero of Episode V:

query CheckTypeOfLuke {
  hero(episode: EMPIRE) {
    __typename
    name
  }
}

We would find that it was Luke, who is a Human:

{
  "hero": {
    "__typename": "Human",
    "name": "Luke Skywalker"
  }
}

As with the type system, this example just scratched the surface of the query language. The specification goes into more detail about this topic in the "Language" section, and the language directory in GraphQL.js contains code implementing a specification-compliant GraphQL query language parser and lexer.

Validation

By using the type system, it can be predetermined whether a GraphQL query is valid or not. This allows servers and clients to effectively inform developers when an invalid query has been created, without having to rely on runtime checks.

For our Star Wars example, the file starWarsValidationTests.js contains a number of queries demonstrating various invalidities, and is a test file that can be run to exercise the reference implementation's validator.

To start, let's take a complex valid query. This is the NestedQuery example from the above section, but with the duplicated fields factored out into a fragment:

query NestedQueryWithFragment {
  hero {
    ...NameAndAppearances
    friends {
      ...NameAndAppearances
      friends {
        ...NameAndAppearances
      }
    }
  }
}

fragment NameAndAppearances on Character {
  name
  appearsIn
}

And this query is valid. Let's take a look at some invalid queries!

When we query for fields, we have to query for a field that exists on the given type. So as hero returns a Character, we have to query for a field on Character. That type does not have a favoriteSpaceship field, so this query:

# INVALID: favoriteSpaceship does not exist on Character
query HeroSpaceshipQuery {
  hero {
    favoriteSpaceship
  }
}

is invalid.

Whenever we query for a field and it returns something other than a scalar or an enum, we need to specify what data we want to get back from the field. Hero returns a Character, and we've been requesting fields like name and appearsIn on it; if we omit that, the query will not be valid:

# INVALID: hero is not a scalar, so fields are needed
query HeroNoFieldsQuery {
  hero
}

Similarly, if a field is a scalar, it doesn't make sense to query for additional fields on it, and doing so will make the query invalid:

# INVALID: name is a scalar, so fields are not permitted
query HeroFieldsOnScalarQuery {
  hero {
    name {
      firstCharacterOfName
    }
  }
}

Earlier, it was noted that a query can only query for fields on the type in question; when we query for hero which returns a Character, we can only query for fields that exist on Character. What happens if we want to query for R2-D2s primary function, though?

# INVALID: primaryFunction does not exist on Character
query DroidFieldOnCharacter {
  hero {
    name
    primaryFunction
  }
}

That query is invalid, because primaryFunction is not a field on Character. We want some way of indicating that we wish to fetch primaryFunction if the Character is a Droid, and to ignore that field otherwise. We can use the fragments we introduced earlier to do this. By setting up a fragment defined on Droid and including it, we ensure that we only query for primaryFunction where it is defined.

query DroidFieldInFragment {
  hero {
    name
    ...DroidFields
  }
}

fragment DroidFields on Droid {
  primaryFunction
}

This query is valid, but it's a bit verbose; named fragments were valuable above when we used them multiple times, but we're only using this one once. Instead of using a named fragment, we can use an inline fragment; this still allows us to indicate the type we are querying on, but without naming a separate fragment:

query DroidFieldInInlineFragment {
  hero {
    name
    ... on Droid {
      primaryFunction
    }
  }
}

This has just scratched the surface of the validation system; there are a number of validation rules in place to ensure that a GraphQL query is semantically meaningful. The specification goes into more detail about this topic in the "Validation" section, and the validation directory in GraphQL.js contains code implementing a specification-compliant GraphQL validator.

Introspection

It's often useful to ask a GraphQL schema for information about what queries it supports. GraphQL allows us to do so using the introspection system!

For our Star Wars example, the file starWarsIntrospectionTests.js contains a number of queries demonstrating the introspection system, and is a test file that can be run to exercise the reference implementation's introspection system.

We designed the type system, so we know what types are available, but if we didn't, we can ask GraphQL, by querying the __schema field, always available on the root type of a Query. Let's do so now, and ask what types are available.

query IntrospectionTypeQuery {
  __schema {
    types {
      name
    }
  }
}

and we get back:

{
  "__schema": {
    "types": [
      {
        "name": "Query"
      },
      {
        "name": "Character"
      },
      {
        "name": "Human"
      },
      {
        "name": "String"
      },
      {
        "name": "Episode"
      },
      {
        "name": "Droid"
      },
      {
        "name": "__Schema"
      },
      {
        "name": "__Type"
      },
      {
        "name": "__TypeKind"
      },
      {
        "name": "Boolean"
      },
      {
        "name": "__Field"
      },
      {
        "name": "__InputValue"
      },
      {
        "name": "__EnumValue"
      },
      {
        "name": "__Directive"
      }
    ]
  }
}

Wow, that's a lot of types! What are they? Let's group them:

  • Query, Character, Human, Episode, Droid - These are the ones that we defined in our type system.
  • String, Boolean - These are built-in scalars that the type system provided.
  • __Schema, __Type, __TypeKind, __Field, __InputValue, __EnumValue, __Directive - These all are preceded with a double underscore, indicating that they are part of the introspection system.

Now, let's try and figure out a good place to start exploring what queries are available. When we designed our type system, we specified what type all queries would start at; let's ask the introspection system about that!

query IntrospectionQueryTypeQuery {
  __schema {
    queryType {
      name
    }
  }
}

and we get back:

{
  "__schema": {
    "queryType": {
      "name": "Query"
    }
  }
}

And that matches what we said in the type system section, that the Query type is where we will start! Note that the naming here was just by convention; we could have named our Query type anything else, and it still would have been returned here if we had specified it as the starting type for queries. Naming it Query, though, is a useful convention.

It is often useful to examine one specific type. Let's take a look at the Droid type:

query IntrospectionDroidTypeQuery {
  __type(name: "Droid") {
    name
  }
}

and we get back:

{
  "__type": {
    "name": "Droid"
  }
}

What if we want to know more about Droid, though? For example, is it an interface or an object?

query IntrospectionDroidKindQuery {
  __type(name: "Droid") {
    name
    kind
  }
}

and we get back:

{
  "__type": {
    "name": "Droid",
    "kind": "OBJECT"
  }
}

kind returns a __TypeKind enum, one of whose values is OBJECT. If we asked about Character instead:

query IntrospectionCharacterKindQuery {
  __type(name: "Character") {
    name
    kind
  }
}

and we get back:

{
  "__type": {
    "name": "Character",
    "kind": "INTERFACE"
  }
}

We'd find that it is an interface.

It's useful for an object to know what fields are available, so let's ask the introspection system about Droid:

query IntrospectionDroidFieldsQuery {
  __type(name: "Droid") {
    name
    fields {
      name
      type {
        name
        kind
      }
    }
  }
}

and we get back:

{
  "__type": {
    "name": "Droid",
    "fields": [
      {
        "name": "id",
        "type": {
          "name": null,
          "kind": "NON_NULL"
        }
      },
      {
        "name": "name",
        "type": {
          "name": "String",
          "kind": "SCALAR"
        }
      },
      {
        "name": "friends",
        "type": {
          "name": null,
          "kind": "LIST"
        }
      },
      {
        "name": "appearsIn",
        "type": {
          "name": null,
          "kind": "LIST"
        }
      },
      {
        "name": "primaryFunction",
        "type": {
          "name": "String",
          "kind": "SCALAR"
        }
      }
    ]
  }
}

Those are our fields that we defined on Droid!

id looks a bit weird there, it has no name for the type. That's because it's a "wrapper" type of kind NON_NULL. If we queried for ofType on that field's type, we would find the String type there, telling us that this is a non-null String.

Similarly, both friends and appearsIn have no name, since they are the LIST wrapper type. We can query for ofType on those types, which will tell us what these are lists of.

query IntrospectionDroidWrappedFieldsQuery {
  __type(name: "Droid") {
    name
    fields {
      name
      type {
        name
        kind
        ofType {
          name
          kind
        }
      }
    }
  }
}

and we get back:

{
  "__type": {
    "name": "Droid",
    "fields": [
      {
        "name": "id",
        "type": {
          "name": null,
          "kind": "NON_NULL",
          "ofType": {
            "name": "String",
            "kind": "SCALAR"
          }
        }
      },
      {
        "name": "name",
        "type": {
          "name": "String",
          "kind": "SCALAR",
          "ofType": null
        }
      },
      {
        "name": "friends",
        "type": {
          "name": null,
          "kind": "LIST",
          "ofType": {
            "name": "Character",
            "kind": "INTERFACE"
          }
        }
      },
      {
        "name": "appearsIn",
        "type": {
          "name": null,
          "kind": "LIST",
          "ofType": {
            "name": "Episode",
            "kind": "ENUM"
          }
        }
      },
      {
        "name": "primaryFunction",
        "type": {
          "name": "String",
          "kind": "SCALAR",
          "ofType": null
        }
      }
    ]
  }
}

Let's end with a feature of the introspection system particularly useful for tooling; let's ask the system for documentation!

query IntrospectionDroidDescriptionQuery {
  __type(name: "Droid") {
    name
    description
  }
}

yields

{
  "__type": {
    "name": "Droid",
    "description": "A mechanical creature in the Star Wars universe."
  }
}

So we can access the documentation about the type system using introspection, and create documentation browsers, or rich IDE experiences.

This has just scratched the surface of the introspection system; we can query for enum values, what interfaces a type implements, and more. We can even introspect on the introspection system itself. The specification goes into more detail about this topic in the "Introspection" section, and the introspection file in GraphQL.js contains code implementing a specification-compliant GraphQL query introspection system.

Additional Content

This README walked through the GraphQL.js reference implementation's type system, query execution, validation, and introspection systems. There's more in both GraphQL.js and specification, including a description and implementation for executing queries, how to format a response, explaining how a type system maps to an underlying implementation, and how to format a GraphQL response, as well as the grammar for GraphQL.

Contributing to this repo

This repository is managed by EasyCLA. Project participants must sign the free (GraphQL Specification Membership agreement before making a contribution. You only need to do this one time, and it can be signed by individual contributors or their employers.

To initiate the signature process please open a PR against this repo. The EasyCLA bot will block the merge if we still need a membership agreement from you.

You can find detailed information here. If you have issues, please email [email protected].

If your company benefits from GraphQL and you would like to provide essential financial support for the systems and people that power our community, please also consider membership in the GraphQL Foundation.

Comments
  • Query all fields of a type in a simple expression [wildcard]

    Query all fields of a type in a simple expression [wildcard]

    Let us say this is the type :

    type Human {
      id: String
      name: String
      homePlanet: String
    }
    

    Then to query all the fields the query is :

    query HumanNameQuery {
       Human {
         id
         name
         homeplanet
        }
     }
    

    Should be something like this exist ??

    query HumanNameQuery {
       Human {
         *
       }
     }
    
    opened by AhmadAudeh 137
  • RFC: inputUnion type

    RFC: inputUnion type

    Related graphql-js PR: graphql/graphql-js#1196

    This is an RFC for a new type: inputUnion.

    An inputUnion is a union of one or more input types. It may be used in any location where an input is currently valid. When fulfilling an inputUnion an additional field __inputname must be specified in the map/object fulfilling the input, where the value of __inputname is the name of a single member of the inputUnion being fulfilled.

    Example:

    input PostInput {
      title: String!
      body: String!
    }
    input ImageInput {
      photo: String!
      caption: String
    }
    
    inputUnion MediaBlock = PostInput | ImageInput
    
    type Mutation {
       addContent(content: [MediaBlock]!): Post   
    }
    
    mutation AddContent($content: [MediaBlock]!) {
       addContent(content: $content) {
          id
       }
    }
    

    Valid $content value:

    [
      {__inputname: "PostInput", title: "Hello", content: "World"},
      {__inputname: "ImageInput", photo: "http://graphql.org/img/logo.svg", caption: "Logo"}
    ]
    

    Invalid Value Examples:

    {__inputname: "PostInput", title: "Invalid, missing 'content'"}
    
    {title: "Invalid, missing __inputname", content: "World"}
    
    {
      __inputname: "PostInput", 
      title: "Invalid, photo is not defined on PostInput", 
      content: "World", 
      photo: "http://graphql.org/img/logo.svg"
    }
    

    Checklist:

    Are we solving a real problem.

    Yes. Many of these problems or use cases are laid out in graphql/graphql-js#207 but to summarize:

    When creating input objects, both in mutations and queries you face a tradeoff when creating complex input structs, with one of two options:

    1. Enforce a well typed structure of the input via required fields !. Create multiple endpoints (mutation or query) utilizing these various strict, special case input types.
    2. Loosen the input type requirements and rely on runtime/server-side validation to determine the intended uses.

    This solution aims to offer a third path, where more complex combinations of strict input combinations may be utilized, while still keeping the input types fulfillment unambiguous via the __inputname field requirement.

    Does this enable new use cases.

    Yes. Many of the use cases are detailed in graphql/graphql-js#207. I think the biggest thing this unlocks is the list of heterogeneous inputs, which can be used to define an ordered set of instructions. This also reduces the need for many individual mutations while being able to maintain strictly typed inputs. In my experience tools like apollo-codegen and graphql-code-generator have proven invaluable in creating Flow/TypeScript definitions for validating queries. This change will work well in combination with those tools, making complex input semantics simpler to statically check.

    How common is this use case.

    Very common. This is the most commented issue in graphql-js, and I personally have run into the tradeoff of creating many highly restrictive mutations vs loosening them up and creating an ad-hoc server implementation. This sort of concept feels like the missing corollary to the expressiveness of the graphql Query execution (single "smart" entry point rather than many ad-hoc endpoints).

    Can we enable it without a change to GraphQL.

    No, at least not without pushing any type-checking semantics to the execution layer.

    Additional thoughts

    What about interfaces? There are several comments in related tickets expressing a desire for interfaces in addition to input unions. While it sounds nice for symmetry with querying, I don't see these as being useful or necessary in practice at the input layer. Interfaces are most useful when you wish to query for a generic partial representation of a more specific type. This same requirement does not exist for inputs and it is my opinion that inputInterface would not add enough additional value to justify its addition.

    Open questions:

    • Is the use of __inputname a valid option based on spec (__ is reserved for introspection, not sure if we can mirror this for execution)
    • Does __inputname make sense as the name for this?
    💡 Proposal (RFC 1) 
    opened by tgriesser 98
  • [RFC] GraphQL Input Union type

    [RFC] GraphQL Input Union type

    [RFC] GraphQL Input Union type

    Background

    There have been many threads on different issues and pull requests regarding this feature. The main discussion started with the graphql/graphql-js#207 on 17/10/2015.

    Currently, GraphQL input types can only have one single definition, and the more adoption GraphQL gained in the past years it has become clear that this is a serious limitation in some use cases. Although there have been multiple proposals in the past, this is still an unresolved issue.

    With this RFC document, I would like to collect and summarise the previous discussions at a common place and proposals and propose a new alternative solution.

    To have a better understanding of the required changes there is a reference implementation of this proposal, but that I will keep up to date based on future feeback on this proposal.

    The following list shows what proposals have been put forward so far including a short summary of pros and cons added by @treybrisbane in this comment

    • __inputname field by @tgriesser

      RFC document: #395

      Reference implementation: graphql/graphql-js#1196

      This proposal was the first official RFC which has been discussed at the last GraphQL Working Group meeting. This proposal in this current form has been rejected by the WG because of the __inputname semantics. However, everyone agrees that alternative proposals should be explored.

      • Pros:
        • Expresses the design intent within the schema
        • Supports unions of types with overlapping fields
        • Removes the costs of the tagged union pattern (both to the schema and field resolution)
        • Addresses the feature asymmetry of unions within the type system
      • Cons:
        • Adds complexity to the language in the form of input union-specific syntax
        • Adds complexity to the language in the form of additional validation (around __inputtype, etc)
        • Adds complexity to the request protocol in the form of a (input union-specific) constraint
    • Tagged union by @leebyron and @IvanGoncharov

      Original comment

      input MediaBlock = { post: PostInput! } | { image: ImageInput! }
      
      • Pros:
        • Expresses the design intent within the schema
        • Removes the costs of the tagged union pattern (both to the schema and field resolution)
        • Does not require changes to the request protocol
      • Cons:
        • No support for unions of types with overlapping fields
        • Introduces inconsistencies between the syntax for output unions and the syntax for input unions
        • Adds complexity to the language in the form of input union-specific syntax
        • Adds complexity to the language in the form of additional validation (around enforcing the stipulations on overlapping fields, nullability, etc)
        • Does not fully address the feature asymmetry of unions within the type system
    • Directive

      Original comment

      input UpdateAccountInput @inputUnion {
        UpdateAccountBasicInput: UpdateAccountBasicInput
        UpdateAccountContactInput: UpdateAccountContactInput
        UpdateAccountFromAdminInput: UpdateAccountFromAdminInput
        UpdateAccountPreferencesInput: UpdateAccountPreferencesInput
      }
      
      • Pros:
        • Requires no language or request prototcol changes beyond a new directive
        • Supports unions of types with overlapping fields
      • Cons:
        • Adds complexity to the language in the form of a new directive
        • Does not express the design intent within the schema (the presence of a directive completely changes the meaning of a type definition which would otherwise be used to describe a simple object type)
        • Does not remove the costs of the tagged union pattern
        • Does not address the feature asymmetry of unions within the type system

    Proposed solution

    Based on the previous discussions I would like to propose an alternative solution by using a disjoint (or discriminated) union type.

    Defining a disjoint union has two requirements:

    1. Have a common literal type field - called the discriminant
    2. A type alias that takes the union of those types - the input union

    With that our GraphQL schema definition would be the following (Full schema definition)

    literal ImageInputKind
    literal PostInputKind
    
    input AddPostInput {
      kind: PostInputKind!
      title: String!
      body: String!
    }
    
    input AddImageInput  {
      kind: ImageInputKind!
      photo: String!
      caption: String
    }
    
    inputUnion AddMediaBlock = AddPostInput | AddImageInput
    
    input EditPostInput {
      inputTypeName: PostInputKind!
      title: String
      body: String
    }
    
    input EditImageInput {
      inputTypeName: ImageInputKind!
      photo: String
      caption: String
    }
    
    inputUnion EditMediaBlock = EditPostInput | EditImageInput
    
    type Mutation {
      createMedia(content: [AddMediaBlock]!): Media   
      editMedia(content: [EditMediaBlock]!): Media
    }
    

    And a mutation query would be the following:

    mutation {
      createMedia(content: [{
        kind: PostInputKind
        title: "My Post"
        body: "Lorem ipsum ..."
      }, {
        kind: ImageInputKind
        photo: "http://www.tanews.org.tw/sites/default/files/imce/admin/user2027/6491213611_c4fc290a33_z.jpg"
        caption: "Dog"
      }]) {
        content {
          ... on PostBlock {
            title
            body
          }
          ... on ImageBlock {
            photo
            caption
          }
        }
      }
    }
    

    or with variables

    mutation CreateMediaMutation($content: [AddMediaBlock]!) {
      createMedia(content: $content) {
        id
        content {
          ... on PostBlock {
            title
            body
          }
          ... on ImageBlock {
            photo
            caption
          }
        }
      }
    }
    
    {
      "content": [{
        "kind": "PostInputKind",
        "title": "My Post",
        "body": "Lorem ipsum ...",
      }, {
        "kind": "ImageInputKind",
        "photo": "http://www.tanews.org.tw/sites/default/files/imce/admin/user2027/6491213611_c4fc290a33_z.jpg",
        "caption": "Dog"
      }]
    }
    

    New types

    Literal type

    The GraphQLLiteralType is an exact value type. This new type enables the definition a discriminant field for input types that are part of an input union type.

    Input union type

    The GraphQLInputUnionType represent an object that could be one of a list of GraphQL Input Object types.

    Input Coercion

    The input union type needs a way of determining which input object a given input value correspond to. Based on the discriminant field it is possible to have an internal function that can resolve the correct GraphQL Input Object type. Once it has been done, the input coercion of the input union is the same as the input coercion of the input object.

    Type Validation

    Input union types have a potential to be invalid if incorrectly defined:

    • An input union type must include one or more unique input objects
    • Every included input object type must have:
      • One common field
      • This common field must be a unique Literal type for every Input Object type

    Using String or Enum types instead of Literal types

    While I think it would be better to add support for a Literal type, I can see that this type would only be useful for Input unions; therefore, it might be unnecessary. However, it would be possible to use String or Enum types for the discriminant field, but in this case, a resolveType function must be implemented by the user. This would also remove one of the type validations required by the input type (2.2 - The common field must be a unique Literal type for every Input Object type).

    Final thoughts

    I believe that the above proposal addresses the different issues that have been raised against earlier proposals. It introduces additional syntax and complexity but uses a concept (disjoint union) that is widely used in programming languages and type systems. And as a consequence I think that the pros of this proposal outweigh the cons.

    • Pros

      • Expresses the design intent within the schema
      • The discriminant field name is configurable
      • Supports unions of types with overlapping fields
      • Addresses the feature asymmetry of unions within the type system
      • Does not require changes to the request protocol
    • Cons

      • Adds complexity to the language in the form of literal-specific syntax (might not need)
      • Adds complexity to the language in the form of input union-specific syntax
      • Adds complexity to the language in the form of additional validations (input union, discriminant field, input union resolving (might not need))

    However, I think there are many questions that needs some more discussions, until a final proposal can be agreed on - especially around the new literal type, and if it is needed at all.

    💭 Strawman (RFC 0) 
    opened by frikille 94
  • Subscriptions RFC: Are Subscriptions and Live Queries the same thing?

    Subscriptions RFC: Are Subscriptions and Live Queries the same thing?

    Re-define Live Queries? Can Live Queries make Subscriptions unnecessary? @smolinari @paralin @laneyk @dschafer @taion @Siyfion @jamesgorman2 @leebyron

    Continuing the conversation from: https://github.com/facebook/graphql/pull/267#issuecomment-281576156

    opened by robzhu 78
  • [RFC] GraphQL Schema Definition Language (SDL)

    [RFC] GraphQL Schema Definition Language (SDL)

    This adds the type definition syntax to the GraphQL specification.

    There are some remaining issues to solve:

    • [x] Include reference in Execution chapter about non-executable GraphQL
    • [x] Description is not yet represented
    • [x] Deprecation is not yet represented
    • [x] Directives are not yet represented
    • [x] Top level Schema is not yet represented
    • [x] Investigate impact on validation rules
    • [x] Decide on any or many rules for type fields / enum values
    • [x] Combine into type system chapter
    • [x] Consider separating into two top level grammars
    • [x] Solve ambiguity for extending interfaces (https://github.com/graphql/graphql-js/pull/1166)
    opened by leebyron 60
  • GraphQL Patent Infringement Issues

    GraphQL Patent Infringement Issues

    Hi Guys,

    First, thank you for your incredibly hard work and brilliant design. You've helped me and many others.

    I believe that there's an IP issue over GraphQL that needs to be brought to Facebook's attention. GraphQL patents are issuing and there are no patent grants in the specification. I read these patents to cover core functionality and difficult (thought not impossible) to design around. However, the current spec leads most implementations to be infringers.

    For more, here are my full thoughts.

    https://medium.com/@dwalsh.sdlr/using-graphql-why-facebook-now-owns-you-3182751028c9

    I've been a Facebook licensing defender for other OSS like React, but I think this is a completely different issue and hope this can start a dialogue up the chain.

    Thank you!

    opened by LawJolla 49
  • RFC: Allow interfaces to implement other interfaces

    RFC: Allow interfaces to implement other interfaces

    This fixes #295 by describing the way in which an interface may implement another interface. The rules are essentially identical to the rules governing implementation of an interface by an object. I'd be more than happy to champion this change (per the CONTRIBUTING.md process) so please direct any questions my way.

    This is a pretty small change, but adds substantially to the expressiveness of GraphQL's type system.

    If someone in the WG can give me a nod, I'll go ahead and implement it in graphql-js.

    Thanks in advance!

    🏁 Accepted (RFC 3) 
    opened by mike-marcacci 46
  • Recursively nested objects

    Recursively nested objects

    Suppose we have a forum where users can reply to comments recursively:

    type RootQuery {
      message(id: String): Message
      messages: [Message]
    }
    
    type Message {
      id: String!
      content: String
      comments: [Message]
    }
    

    How could the client query for the nested comments?

    This only goes three levels deep:

    {
      messages {
        comments {
          id
          content
          comments {
            id
            content
            comments {
              id
              content       
            }
          }
        }   
      }
    }
    

    Would a consecutive query starting at the last comment be the right solution?

    {
      message as comment($commentId) {
        comments {
          id
          content
          comments {
            ...
          }
        }
      }
    }
    

    Original SO post

    opened by petrbela 44
  • [RFC] Null value

    [RFC] Null value

    This proposal adds a null literal to the GraphQL language and allows it to be provided to nullable typed arguments and input object fields.

    This presents an opportunity for a GraphQL service to interpret the explicitly provided null differently from the implicitly not-provided value, which may be especially useful when performing mutations using a per-field set API.

    For example, this query may represent the removal/clearing of the "bar" field from thing with id: 4.

    mutation editThing {
      editThing(id: 4, edits: { foo: "added", bar: null }) {
        # ...
      }
    }
    

    In addition to allowing null as a literal value, this also proposes interpretting the variables JSON to distinguish between explicit null and implicit not provided:

    mutation editThing($edits: EditObj) {
      editThing(id: 4, edits: $edits) {
        # ...
      }
    }
    

    This variables results in the unsetting of bar

    { "edits": { "foo": "added", "bar": null } }
    

    Finally, this proposes following the not-provided-ness of variables to their positions in arguments and input-obj fields

    mutation editThing($editBaz: String) {
      editThing(id: 4, edits: { foo: "added", bar: null, baz: $editBaz }) {
        # ...
      }
    }
    

    Such that the three variables are semantically different:

    • {} The "baz" input field is "not provided"
    • {"editBaz": null} The "baz" input field is null
    • {"editBaz": "added"} The "baz" input field is "added"
    opened by leebyron 35
  • RFC: Map type

    RFC: Map type

    This is an RFC for a new "Map" type to be added to GraphQL.

    I acknowledge issue #101, that has 79 comments and 150+ 👍 votes. @leebyron locked the issue with the comment

    If someone feels strongly that this concept deserves first-class support in GraphQL, I suggest following the RFC procedure to take this from a general suggestion to an actual proposal.`

    This is that proposal.

    Problem statement

    This proposal aims to keep in mind "The Guiding Principles" laid out in the CONTRIBUTING.md.

    Currently, GraphQL doesn't offer a way to return a Map/Dictionary response.

    A workaround is to return a key/value pair response as suggested in https://stackoverflow.com/questions/56705157/best-way-to-define-a-map-object-in-graphql-schema

    type ArticleMapTuple {
         key: String!
         value: Article!
    }
    
    type Article {
      name: String!
    }
    

    response

    [
      {
        "key": "foo1",
        "value": {name: "Foo1"}
      },
      {
        "key": "foo2",
        "value": {name: "Foo2"}
      },
      {
        "key": "foo3",
        "value": {name: "Foo3"}
      },
    ]
    

    The problem is searching for the key "foo3" in the list requires traversing through the list. The alternative is to process the response into a local object via Object.fromEntries and then use it for fast lookups.

    Maps/Dictionaries are core data types in most languages. The json spec supports objects with key: value pairs. By having support for Maps, GraphQL clients can make effient key:value lookups on responses.

    This proposal introduces field: { Type } syntax to specify Maps. Similar to existing field: [ List ] syntax.

    The primary motivation in this proposal is the idea that Maps are Lists with ID! (non-null string) keys, and should behave similar to Lists.

    Most relational databases have tables with schemas in the format:

    type SomeEntity {
      id: ID!
      field1: String!
      field2: Int!
    }
    

    Having the response with IDs as keys gives GraphQL consumers/clients the ability for O(1) map lookups instead of O(n) list lookups.

    {
     "idAbc": {field1: "foo", field2: 123}
    }
    

    The other argument is that in many instances, GraphQL sits on top of an existing REST-ful api which returns responses with map responses. A real-world example is algolia.

    Algolia indexes map fields for very fast facet lookups. e.g.

    {
     id: "123"
     name: "K95 Face Shield 24 PK",
     stockByLocation: {
       "seattle": 30,
       "portland": 40,
       "miami": 30,
       "st_louis": 10,
       ...
     }
    }
    

    To implement a GraphQL api over algolia, it would require changing the shape of stockByLocation response. By having GraphQL as schema enforcer, Map type would open a lot more possibilities of GraphQL adoption.

    The schema for above response would be:

    
    type InventoryItem {
      id: ID!
      name: String!
      stockByLocations: { Int! }!
    }
    

    List type

    Currently, the List type is the only unbounded type in GraphQL.

    SDL

    type Query {
      users: [User!]!
    }
    
    type User {
      id: ID!
      firstName: String!
      lastName: String!
    }
    

    query:

    {
      users {
        id
        firstName
        lastName
      }
    }
    

    response:

    {
      "users": [
        {"id": "foo", "firstName": "Foo", "lastName": "Bar"},
        {"id": "hello", "firstName": "Hello", "lastName": "World"}
      ]
    }
    

    Notice how the query didn't specify [] to specify a list response. Based on the type declaration users: [User!]!, only the fields of the List's value type are specified.

    {
      users [{
        id
        firstName
        lastName
      }]
    }
    

    ^ NOTE: this is an invalid gql query.

    The response can return any number of items in the list. GraphQL doesn't control what will be returned at the 0th index of the list, or the 1st index. This is upto the GraphQL service to determine.

    A list can be seen a map with incremental numeric keys. It supports fast lookups at an index.

    [
        0: {"id": "foo", "firstName": "Foo", "lastName": "Bar"},
        1: {"id": "hello", "firstName": "Hello", "lastName": "World"},
        2: {"id": "jsmith", "firstName": "John", "lastName": "Smith"}
    ]
    

    Map type

    Following the principle of "Maps are Lists with string keys, and should behave simiar to Lists."

    Note: The value type will still need to be explicitly specified. This is not an escape hatch for Any type.

    SDL

    type Query {
      users: {User!}!
    }
    
    type User {
      id: ID!
      firstName: String!
      lastName: String!
    }
    

    query:

    {
      users {
        firstName
        lastName
      }
    }
    

    response:

    {
      "users": {
        "foo": {"firstName": "Foo", "lastName": "Bar"},
        "hello": {"firstName": "Hello", "lastName": "World"}
      }
    }
    

    Q: Why non-null string keys only?

    A: Because grapqhl responses are json, and json only supports string keys.

    Alternative syntax is field: {ID!: Type}, however that would indicate that GraphQL may support other key types like Ints. I'd love for users to fall into the pit of success, so feel the semantics should be simple. Only string key types. Less is more.

    field: { Type } for Maps, field: [ Type ] for Lists. The non-null versions being. field: { Type! }! and field: [ Type! ]!.

    --

    Q: What about nested Maps?

    A: Nested lists work e.g. field: [[ Type ]], therefore, nested maps should also work in a similar fashion i.e. field: {{ Type }}. The difference is that there would be no automatic coercion. If the shape of response doesn't match then there is a type error.

    💭 Strawman (RFC 0) 
    opened by nojvek 34
  • Consolidate Input Union discussions

    Consolidate Input Union discussions

    Over the years there have been many discussions around the topic of Input Unions in GraphQL. To help further the effort, we have begun building a single RFC document. The goal of this document is to consolidate all related ideas to help move the proposal forward.

    • https://github.com/graphql/graphql-spec/blob/master/rfcs/InputUnion.md

    To help this effort, I'd like @leebyron to consider commenting on & closing all related open Issues / PRs in favor of the main RFC document, which will contain & reference all of these previous discussions.

    • Polymorphic input types https://github.com/graphql/graphql-spec/issues/114 @luisobo
    • RFC: inputUnion type https://github.com/graphql/graphql-spec/pull/395 @tgriesser
    • Input polymorphism https://github.com/graphql/graphql-spec/issues/415 @jayhasyee
    • [RFC] GraphQL Input Union type https://github.com/graphql/graphql-spec/issues/488 @frikille
    • [RFC] Input Objects accepting exactly @oneField https://github.com/graphql/graphql-spec/pull/586 @benjie

    @leebyron @IvanGoncharov

    opened by binaryseed 27
  • Add a style guide to the specification

    Add a style guide to the specification

    @rivantsov pointed out in #981 that there is inconsistent capitalization in the spec.

    I've done some research and have concluded that our style seems to most-closely match the AP style guide, so I have worked my way through every heading in the document and applied this style to them. I've also outlined the very basics of this in a style guide document.

    You can see some of my analysis in this comment:

    https://github.com/graphql/graphql-spec/pull/981#issuecomment-1342515414

    After that I expanded to looking at all headings in the document. I include below the before/after for the document headings, sorted alphabetically, using grep -hEr '(^#|^\*\*.*\*\*$)' . | sort -u

    before
    # A. Appendix: Notation Conventions
    # B. Appendix: Grammar Summary
    # Execution
    # GraphQL
    # Introspection
    # Language
    # Overview
    # Response
    # Type System
    # Validation
    # [Appendix: Grammar Summary](Appendix%20B%20--%20Grammar%20Summary.md)
    # [Appendix: Notation Conventions](Appendix%20A%20--%20Notation%20Conventions.md)
    # [Execution](Section%206%20--%20Execution.md)
    # [Introspection](Section%204%20--%20Introspection.md)
    # [Language](Section%202%20--%20Language.md)
    # [Overview](Section%201%20--%20Overview.md)
    # [Response](Section%207%20--%20Response.md)
    # [Type System](Section%203%20--%20Type%20System.md)
    # [Validation](Section%205%20--%20Validation.md)
    ## Algorithms
    ## Arguments
    ## Context-Free Grammar
    ## Descriptions
    ## Directives
    ## Document
    ## Document Syntax
    ## Documents
    ## Enums
    ## Executing Fields
    ## Executing Operations
    ## Executing Requests
    ## Executing Selection Sets
    ## Field Alias
    ## Fields
    ## Fragments
    ## Grammar Notation
    ## Grammar Semantics
    ## Ignored Tokens
    ## Input Objects
    ## Input Values
    ## Interfaces
    ## Lexical Tokens
    ## Lexical and Syntactical Grammar
    ## List
    ## Non-Null
    ## Objects
    ## Operations
    ## Response Format
    ## Scalars
    ## Schema
    ## Schema Introspection
    ## Selection Sets
    ## Serialization Format
    ## Source Text
    ## Type Name Introspection
    ## Type References
    ## Type System Extensions
    ## Types
    ## Unions
    ## Values
    ## Variables
    ### @deprecated
    ### @include
    ### @skip
    ### @specifiedBy
    ### All Variable Usages are Allowed
    ### All Variable Uses Defined
    ### All Variables Used
    ### Anonymous Operation Definitions
    ### Argument Names
    ### Argument Uniqueness
    ### Boolean
    ### Boolean Value
    ### Coercing Field Arguments
    ### Coercing Variable Values
    ### Combining List and Non-Null
    ### Comments
    ### Data
    ### Directives Are Defined
    ### Directives Are In Valid Locations
    ### Directives Are Unique Per Location
    ### Enum Extensions
    ### Enum Value
    ### Errors
    ### Executable Definitions
    ### Field Arguments
    ### Field Collection
    ### Field Deprecation
    ### Field Selection Merging
    ### Field Selections
    ### Float
    ### Float Value
    ### Fragment Declarations
    ### Fragment Spreads
    ### Handling Field Errors
    ### ID
    ### Ignored Tokens
    ### Inline Fragments
    ### Input Object Extensions
    ### Input Object Field Names
    ### Input Object Field Uniqueness
    ### Input Object Required Fields
    ### Input Object Values
    ### Input and Output Types
    ### Insignificant Commas
    ### Int
    ### Int Value
    ### Interface Extensions
    ### JSON Serialization
    ### Leaf Field Selections
    ### Lexical Tokens
    ### Line Terminators
    ### List Value
    ### Mutation
    ### Named Operation Definitions
    ### Names
    ### Normal and Serial Execution
    ### Null Value
    ### Object Extensions
    ### Punctuators
    ### Query
    ### Root Operation Types
    ### Scalar Extensions
    ### Schema Extension
    ### Serialized Map Ordering
    ### String
    ### String Value
    ### Subscription
    ### Subscription Operation Definitions
    ### The \_\_Directive Type
    ### The \_\_EnumValue Type
    ### The \_\_Field Type
    ### The \_\_InputValue Type
    ### The \_\_Schema Type
    ### The \_\_Type Type
    ### Type Conditions
    ### Type Extensions
    ### Union Extensions
    ### Validating Requests
    ### Value Completion
    ### Value Resolution
    ### Values of Correct Type
    ### Variable Uniqueness
    ### Variables Are Input Types
    ### White Space
    ### Wrapping Types
    #### Fragment Name Uniqueness
    #### Fragment Spread Type Existence
    #### Fragment spread is possible
    #### Fragment spread target defined
    #### Fragment spreads must not form cycles
    #### Fragments Must Be Used
    #### Fragments On Composite Types
    #### Lone Anonymous Operation
    #### Operation Name Uniqueness
    #### Required Arguments
    #### Response Stream
    #### Single root field
    #### Source Stream
    #### Unsubscribe
    ##### Abstract Spreads in Abstract Scope
    ##### Abstract Spreads in Object Scope
    ##### Object Spreads In Abstract Scope
    ##### Object Spreads In Object Scope
    **Allowing optional variables when default values exist**
    **Arguments are unordered**
    **Block Strings**
    **Built-in Directives**
    **Built-in Scalars**
    **Byte order mark**
    **Circular References**
    **Coercing Results**
    **Conformance**
    **Conforming Algorithms**
    **Constraints**
    **Copyright notice**
    **Custom Directives**
    **Custom Scalars**
    **Default Root Operation Type Names**
    **Delivery Agnostic**
    **Deprecation**
    **Directive order is significant**
    **Enum**
    **Error result format**
    **Errors and Non-Null Fields**
    **Escape Sequences**
    **Event Streams**
    **Examples**
    **Explanatory Text**
    **Field Ordering**
    **Field errors**
    **First Class Documentation**
    **Formal Specification**
    **Input Coercion**
    **Input Object**
    **Input object fields are unordered**
    **Interface Spreads in implemented Interface Scope**
    **Interface**
    **Interfaces Implementing Interfaces**
    **Introduction**
    **Lexical Analysis & Syntactic Parse**
    **Licensing**
    **List**
    **Lookahead Restrictions**
    **Merging Selection Sets**
    **Non-Normative Portions**
    **Non-Null**
    **Nullable vs. Optional**
    **Object**
    **Optionality and Lists**
    **Parameterized Grammar Productions**
    **Query shorthand**
    **Request errors**
    **Reserved Names**
    **Resolving Abstract Types**
    **Result Coercion and Serialization**
    **Result Coercion**
    **Scalar**
    **Schema Introspection Schema**
    **Schema Validation**
    **Semantics**
    **Static Semantics**
    **Supporting Subscriptions at Scale**
    **Type Validation**
    **Type system evolution**
    **Union**
    **Validation**
    **Variable use within Fragments**
    
    after
    # A. Appendix: Notation Conventions
    # B. Appendix: Grammar Summary
    # Execution
    # GraphQL
    # Introspection
    # Language
    # Overview
    # Response
    # Type System
    # Validation
    # [Appendix: Grammar Summary](Appendix%20B%20--%20Grammar%20Summary.md)
    # [Appendix: Notation Conventions](Appendix%20A%20--%20Notation%20Conventions.md)
    # [Execution](Section%206%20--%20Execution.md)
    # [Introspection](Section%204%20--%20Introspection.md)
    # [Language](Section%202%20--%20Language.md)
    # [Overview](Section%201%20--%20Overview.md)
    # [Response](Section%207%20--%20Response.md)
    # [Type System](Section%203%20--%20Type%20System.md)
    # [Validation](Section%205%20--%20Validation.md)
    ## Algorithms
    ## Arguments
    ## Context-Free Grammar
    ## Descriptions
    ## Directives
    ## Document
    ## Document Syntax
    ## Documents
    ## Enums
    ## Executing Fields
    ## Executing Operations
    ## Executing Requests
    ## Executing Selection Sets
    ## Field Alias
    ## Fields
    ## Fragments
    ## Grammar Notation
    ## Grammar Semantics
    ## Ignored Tokens
    ## Input Objects
    ## Input Values
    ## Interfaces
    ## Lexical Tokens
    ## Lexical and Syntactical Grammar
    ## List
    ## Non-Null
    ## Objects
    ## Operations
    ## Response Format
    ## Scalars
    ## Schema
    ## Schema Introspection
    ## Selection Sets
    ## Serialization Format
    ## Source Text
    ## Type Name Introspection
    ## Type References
    ## Type System Extensions
    ## Types
    ## Unions
    ## Values
    ## Variables
    ### @deprecated
    ### @include
    ### @skip
    ### @specifiedBy
    ### All Variable Usages Are Allowed
    ### All Variable Uses Defined
    ### All Variables Used
    ### Anonymous Operation Definitions
    ### Argument Names
    ### Argument Uniqueness
    ### Boolean
    ### Boolean Value
    ### Coercing Field Arguments
    ### Coercing Variable Values
    ### Combining List and Non-Null
    ### Comments
    ### Data
    ### Directives Are Defined
    ### Directives Are Unique per Location
    ### Directives Are in Valid Locations
    ### Enum Extensions
    ### Enum Value
    ### Errors
    ### Executable Definitions
    ### Field Arguments
    ### Field Collection
    ### Field Deprecation
    ### Field Selection Merging
    ### Field Selections
    ### Float
    ### Float Value
    ### Fragment Declarations
    ### Fragment Spreads
    ### Handling Field Errors
    ### ID
    ### Ignored Tokens
    ### Inline Fragments
    ### Input Object Extensions
    ### Input Object Field Names
    ### Input Object Field Uniqueness
    ### Input Object Required Fields
    ### Input Object Values
    ### Input and Output Types
    ### Insignificant Commas
    ### Int
    ### Int Value
    ### Interface Extensions
    ### JSON Serialization
    ### Leaf Field Selections
    ### Lexical Tokens
    ### Line Terminators
    ### List Value
    ### Mutation
    ### Named Operation Definitions
    ### Names
    ### Normal and Serial Execution
    ### Null Value
    ### Object Extensions
    ### Punctuators
    ### Query
    ### Root Operation Types
    ### Scalar Extensions
    ### Schema Extension
    ### Serialized Map Ordering
    ### String
    ### String Value
    ### Subscription
    ### Subscription Operation Definitions
    ### The \_\_Directive Type
    ### The \_\_EnumValue Type
    ### The \_\_Field Type
    ### The \_\_InputValue Type
    ### The \_\_Schema Type
    ### The \_\_Type Type
    ### Type Conditions
    ### Type Extensions
    ### Union Extensions
    ### Validating Requests
    ### Value Completion
    ### Value Resolution
    ### Values of Correct Type
    ### Variable Uniqueness
    ### Variables Are Input Types
    ### White Space
    ### Wrapping Types
    #### Fragment Name Uniqueness
    #### Fragment Spread Is Possible
    #### Fragment Spread Target Defined
    #### Fragment Spread Type Existence
    #### Fragment Spreads Must Not Form Cycles
    #### Fragments Must Be Used
    #### Fragments on Composite Types
    #### Lone Anonymous Operation
    #### Operation Name Uniqueness
    #### Required Arguments
    #### Response Stream
    #### Single Root Field
    #### Source Stream
    #### Unsubscribe
    ##### Abstract Spreads in Abstract Scope
    ##### Abstract Spreads in Object Scope
    ##### Object Spreads in Abstract Scope
    ##### Object Spreads in Object Scope
    **Allowing Optional Variables When Default Values Exist**
    **Arguments Are Unordered**
    **Block Strings**
    **Built-in Directives**
    **Built-in Scalars**
    **Byte Order Mark**
    **Circular References**
    **Coercing Results**
    **Conformance**
    **Conforming Algorithms**
    **Constraints**
    **Copyright Notice**
    **Custom Directives**
    **Custom Scalars**
    **Default Root Operation Type Names**
    **Delivery Agnostic**
    **Deprecation**
    **Directive Order Is Significant**
    **Enum**
    **Error Result Format**
    **Errors and Non-Null Fields**
    **Escape Sequences**
    **Event Streams**
    **Examples**
    **Explanatory Text**
    **Field Errors**
    **Field Ordering**
    **First Class Documentation**
    **Formal Specification**
    **Input Coercion**
    **Input Object Fields Are Unordered**
    **Input Object**
    **Interface Spreads in Implemented Interface Scope**
    **Interface**
    **Interfaces Implementing Interfaces**
    **Introduction**
    **Lexical Analysis & Syntactic Parse**
    **Licensing**
    **List**
    **Lookahead Restrictions**
    **Merging Selection Sets**
    **Non-Normative Portions**
    **Non-Null**
    **Nullable vs. Optional**
    **Object**
    **Optionality and Lists**
    **Parameterized Grammar Productions**
    **Query Shorthand**
    **Request Errors**
    **Reserved Names**
    **Resolving Abstract Types**
    **Result Coercion and Serialization**
    **Result Coercion**
    **Scalar**
    **Schema Introspection Schema**
    **Schema Validation**
    **Semantics**
    **Static Semantics**
    **Supporting Subscriptions at Scale**
    **Type System Evolution**
    **Type Validation**
    **Union**
    **Validation**
    **Variable Use Within Fragments**
    

    Closes #981

    opened by benjie 1
  • Field error from list arg with nullable variable entry (nullable=optional clash?)

    Field error from list arg with nullable variable entry (nullable=optional clash?)

    Consider the following currently valid schema and query:

    type Query {
      sum(numbers:[Int!]!): Int
    }
    
    query Q ($number: Int = 3) {
      sum(numbers: [1, $number, 3])
    }
    

    With the following variables:

    {
      "number": null
    }
    

    Now following through 6.1.2 Coercing Variable Values:

    1. Let coercedValues be an empty unordered Map. ✅
    2. Let variablesDefinition be the variables defined by operation. ✅
    3. For each variableDefinition in variablesDefinition: ✅
      1. Let variableName be the name of variableDefinition. ✅
      2. Let variableType be the expected type of variableDefinition. ✅
      3. Assert: IsInputType(variableType) must be true. ✅
      4. Let defaultValue be the default value for variableDefinition. ✅
      5. Let hasValue be true if variableValues provides a value for the name variableName. ✅
      6. Let value be the value provided in variableValues for the name variableName. ✅
      7. If hasValue is not true and defaultValue exists (including null):
        1. Add an entry to coercedValues named variableName with the value defaultValue.
      8. Otherwise if variableType is a Non-Nullable type, and either hasValue is not true or value is null, raise a request error.
      9. Otherwise if hasValue is true: ✅
        1. If value is null: ✅
          1. Add an entry to coercedValues named variableName with the value null. ✅

    For the variable definition $number: Int = 3:

    • variableType is Int (NOT Int!).
    • defaultValue is 3
    • hasValue is true since number is provided in variables (even though it's null)
    • value is null

    Thus coercedValues becomes { number: null }.

    When it comes to executing the field, this results in CoerceArgumentValues() raising a field error at 5.j.iii.1 (since [1, null , 3] cannot be coerced to [Int!]!).

    Had the query have been defined with ($number: Int! = 3) then this error could not have occurred; but we explicitly allow the nullable Int with default in IsVariableUsageAllowed(). Presumably this is so that we can allow a default value to apply in the list, except this is a ListValue so there cannot be a default value there.

    We've discussed "optionality" versus "nullability" a few times, but I'd like to get the WG's read on this.

    Reproduction:

    const { graphqlSync, GraphQLSchema, GraphQLList, GraphQLNonNull, GraphQLInt, GraphQLObjectType, validateSchema } = require('graphql');
    
    const Query = new GraphQLObjectType({
      name: 'Query',
      fields: {
        sum: {
          type: GraphQLInt,
          args: {
            numbers: {
              type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(GraphQLInt))),
            }
          },
          resolve(_, args) {
            let total = 0;
            for (const n of args.numbers) {
              total += n;
            }
            return total;
          }
        }
      }
    });
    
    const schema = new GraphQLSchema({
      query: Query
    });
    
    const errors = validateSchema(schema);
    if (errors.length > 0) {
      throw errors[0];
    }
    
    {
      console.log('Testing query with variables and null');
      const result = graphqlSync({
        schema,
        source: `query Q($number: Int = 3) {sum(numbers:[1,$number,3])}`,
        variableValues: {
          number: null
        }
      });
      console.dir(result);
    }
    
    opened by benjie 6
  • Conditional resolving / optional expanding

    Conditional resolving / optional expanding

    It would be nice if you could somehow make resolving conditional whether i request subfieds at all:

    ExampleData:

    vehicleData = [
      {
        licenseplate: "AB-CD123",
        customerNo: "1234"
      },
    ...
    ]
    
    customerData = [
      {
        CusteormNo: "1234",
        Name: "John Doe"
      }
    ]
    
    

    How it is

    schemas:
    
    type vehicle {
      licenseplate: String
      CustomerNo: String
      Customer: Customer
    }
    
    type Customer {
      CustomerNo: String
      Name: String
    }
    
    Resolver: 
    
     Vehicle: {
        Customer: ({ CustomerNo }, args, context, info) => {
         return customers.find( x => x.CustomerNo == CustomerNo )
        },
      },
    
    query for vehicle without customer:
    
    query ExampleQuery {
      vehicles{
        licenseplate
        CustomerNo
      }
    }
    
    query for vehicle with customer:
    
    query ExampleQuery {
      vehicles{
        licenseplate
        Customer {
          CustomerNo
          Name
        }
      }
    }
    
    

    How i wish it would be

    schemas:
    
    type vehicle {
      licenseplate: String
      Customer: String | Customer  <- dynamic fields? 
    }
    
    type Customer {
      CustomerNo: String
      Name: String
    }
    
    Resolver: 
    
    Vehicle: {
      Customer: ({ Customer }, args, context, info) => {
      if( _noSubfields_ ) return Customer; /* no expensive resolving */
       return customers.find( x => x.Customer== Customer)
      },
    },
    
    query for vehicle without customer:
    
    query ExampleQuery {
      vehicles{
        licenseplate
        Customer 
      }
    }
    
    query for vehicle with customer:
    
    query ExampleQuery {
      vehicles{
        licenseplate
        Customer {
          CustomerNo
          Name
        }
      }
    }
    
    
    opened by demsr 0
  • introduce CollectRootFields and CollectSubfields

    introduce CollectRootFields and CollectSubfields

    Rather than merging subSelectionSets of a field set using MergeSelectionSets and then calling CollectFields, this PR introduces CollectSubfields allows the field set's groupedSubfieldSet to be calculated directly.

    The reference implementation already uses this algorithm so that this change actually aligns the specification to the reference implementation, and is ipso facto non-breaking.

    Motivation: reformulating the specification in this manner may be helpful if the specification were ever to be altered such that additional state beyond the current selection set were to be required to calculate the response, i.e. if it were to be required to know the originating selectionSet of a given field within the fieldSet for determining when to communicate a reference signal. In such a scenario, it may still be quite possible to merge the set of requested data from a field set's subSelectionSets, but it may not be possible to express that merged data as an equivalent selectionSet.

    In particular, currently:

    {
      a {
        subfield1
      }
      ...ExampleFragment
    }
    
    fragment ExampleFragment on Query {
      a {
        subfield2
      }
      b
    }
    

    For the given set of fields:

    a {
      subfield1
    }
    a {
      subfield2
    }
    

    These can currently be trivially merged as:

    a {
      subfield1
      subfield2
    }
    

    However, the requested information for a in:

    {
      a {
        subfield1
      }
      Ref1 { completed } : ...ExampleFragment
    }
    
    fragment ExampleFragment on Query {
      a {
        subfield2
      }
      b
    }
    

    cannot be contained in a merged selection set under A, because some of those fields will be related to Ref1 and some will not. The requsted information can still be merged, but it cannot be expressed in selection set format.

    opened by yaacovCR 1
  • add spec edits for references

    add spec edits for references

    References (soft aliases?) are an alternative syntax for fragment metafields such as __fulfilled

    The goal is to create an easily manageable way of requesting different types of fragment spread signals. Multiple metafields or signals will likely be necessary, as after incremental delivery lands, operation writers might be interested in whether a spread has been collected, which can be signaled immediately, or whether all of its fields have been delivered, which may happen only later if the spread has been deferred.

    references collect all of these potential signals into a single locus within the response ("the reference") and use "selection set"-style syntax to indicate which signals are of interest. For example, after incremental delivery lands, the following might be valid:

    query FragmentReferences {
      nodes(ids: [1, 42]) {
        id
        UserFields { selected }: ...userFragment
        SuperUserFields { selected completed}: ...superUserFragment @defer
      }
    }
    
    fragment userFragment on User {
      friends {
        count
      }
    }
    
    fragment superUserFragment on SuperUser {
      privilegeLevel
    }
    

    This would yield the following data right away:

    {
      "nodes": [
        {
          "id": 1,
          "UserFields": { "selected": null },
          "friends": { "count": 1234 }
        },
        {
          "id": 42,
          "UserFields": { "selected": null },
          "friends": { "count": 5678 },
          "SuperUserFields": { "selected": null },
        }
      ]
    }
    

    And the following additional payload at path nodes.1 when the deferred fields complete:

    {
      "SuperUserFields": { "completed": null },
      "privilegeLevel": 20
    }
    

    The existing spec edits only describe the "selected" signal. I am working on the completed signal alongside a version of incremental delivery that does not branch execution or duplicate fields.

    💭 Strawman (RFC 0) 
    opened by yaacovCR 1
  • Expand @deprecated to Objects

    Expand @deprecated to Objects

    Problem

    Take as a motivating example:

    type Query {
      animals: [Animal]
    }
    
    interface Animal {
      name: String
    }
    
    type Dog implements Animal {
      name: String
    }
    
    type Baiji implements Animal {
      name: String
    }
    

    The Baiji type corresponds to an Animal that is no longer known to exist, and the server will no longer return this type. We would like to delete the code for this type and eventually remove from the schema, but first clients must remove all references of this type from their queries. Currently, there is no good way to indicate to clients that they should no longer spread on this type in their queries.

    Solution

    Allow @deprecated on objects. Marking as deprecated indicates to clients that this type will no longer be returned from the server. This can indicate to client build tooling that references to this object should be removed from client queries.

    type Baiji implements Animal @deprecated {
      name: String
    }
    

    Alternative Solutions

    The most compelling use-case for deprecating types is when they are union members or interface implementations. A potential alternative would be to instead deprecate the membership/implementation instead of the type itself. The main challenge with this approach is with syntax, since it unclear how one would unambiguously annotate an interface implementation using the current @deprecated directive. Some possible alternatives:

    New directive location - @deprecated on UNION_MEMBER

    union Animal = Dog | Cat | Baiji @deprecated
    

    New directive @deprecatedMembers on UNION

    union Animal @deprecatedMembers(members: ["Baiji"]) = Dog | Cat | Baiji
    

    New directive @deprecatedImplementations on OBJECT

    type Baiji implements Node & Animal @deprecatedImplementations(implementations: ["Animal"]) {
      id: ID!
      name: String
    }
    

    New directive @deprecatedImplementations on INTERFACE

    interface Animal @deprecatedImplementations(implementations: ["Baiji"]) {
      id: ID!
      name: String
    }
    
    💡 Proposal (RFC 1) 
    opened by fotoetienne 13
Releases(October2021)
  • October2021(Oct 27, 2021)

    https://spec.graphql.org/October2021/

    The first release of the GraphQL spec ratified by the GraphQL Foundation.

    Since the previous release, 35 contributors have made nearly 100 changes to the spec text ranging from minor clarifications to major changes.

    Source code(tar.gz)
    Source code(zip)
  • June2018(Jun 11, 2018)

    http://facebook.github.io/graphql/June2018/

    The June 2018 edition of the GraphQL specification represents extensive refinement and improvement by the editors and community. It is the first edition to no longer be considered a "Draft RFC" (4cd6824a661f5035616e821a41bf128fe9001fe7) to reflect its extensive use in production. GraphQL continues to become a "stable base" atop which many companies have built new an interesting things.

    This edition also contains definitions of the Type System Definition Language (often referred to as GraphQL's "SDL") and a definition for delivering live data over GraphQL subscriptions. It is also the first edition to contain the new license from last year's relicensing effort.

    Huge thanks to everyone who contributed to this release.

    All commits since last release

    New / Potentially-Breaking:

    • Type System Definition Language (#90, #428, #454)

      Originally used as a short-hand in the spec to describe examples, today the type system definition language is the source of truth for many GraphQL services. The grammatical and semantic rules for defining types in the GraphQL language are now included in the specification.

      This also introduces more comprehensive "schema validation" - ensuring that the types and schema defined by a service is coherent and complies with the expected and specified behavior.

    • Error paths in response (#230)

      Errors now have a more strict format they must contain, including a path property which explains where in a response an error corresponds.

    • GraphQL Subscriptions (#267, #283, #304, #305, #392)

      Subscriptions provides the top level type, primitives, and execution and error flow algorithms for providing event-based live data within a GraphQL server.

    • Block String (#327, #394)

      A new multi-line-string literal, particularly useful for writing free-form text and descriptions within the type system definition language.

    • Relicensed to the OWFa v1.0 (#363, #368)

      Previous editions of this spec had an ill-fitting license which is replaced in this edition with Open Web Foundation Agreement (OWFa) v1.0. Additionally, definitions of terms like "conformance" and "non-normative" were added to make it formally clear what would be covered by the new license.

    • Change order of fields inside Response (#384)

      Previous editions suggested that a data property be contained in a result before errors, however this has been reversed for easier human debugging.

    • Add optional 'extensions' entry to errors (#407)

      Previously GraphQL did not make it clear how services should add additional data to errors. After #230, there was a concern that adding new features to errors could accidentally conflict with this additional data. Now, any additional data on an error should be contained within an extensions field.

    • Fix ambiguity with null variable values and default values (#418)

      Previously, providing null to a variable which was later passed to a Non-Null argument was under-defined which could result in undefined behavior. Now, there are clear rules for how to handle null values with respect to the default values of both variables and arguments.

      This also adds new capabilities for default values for arguments and allows new kinds of queries that couldn't be sent before. For more about this change, see #418.

    Clarifications:

    • Add additional mentions about the __ prefix being reserved for introspection use only (#244)
    • Forbid duplicate member types in Union (#266, #441, #464)
    • Forbid implementing the same interface twice (#262)
    • Add missing description of __EnumValue type (#270)
    • Requires descriptions to be written in the CommonMark dialect of Markdown (#290)
    • Clarify handling of null handling within lists (#317)
    • Better clarify different types of errors in spec text (#385)
    • Improve the Input Object input coercion subsection with more examples (#388)
    • Generalize validation of value literals, changing the names of validation rules but not changing the validity of documents (#389)
    • Fix ExecuteSelectionSet algorithm where fieldType may not be defined, but will never be null (#433)
    • Make it clear that field result coercion should throw errors before data loss (#434)
    • Clarify list coercion rules, especially with respect to null values, including examples (#436, #440)
    • Clarify serialization formats, make it clear JSON is not required and the more sophisticated formats are allowed (#437)
    • Clarify errors from executing a selection set may result in sibling fields not being executed (#438)
    • Definitions of Input & Output types (#462)
    • Clarify that Field Selections on Enums types must also be empty (#452)
    Source code(tar.gz)
    Source code(zip)
  • July2015(Jun 11, 2018)

  • October2016(Oct 31, 2016)

    http://facebook.github.io/graphql/October2016/

    GraphQL is a working draft specification, initially released as a technical preview. In September 2016 the technical preview verbiage was removed [ba1bbe5] in recognition of GraphQL being used in production by companies large and small.

    The October 2016 edition of the GraphQL specification is the first since this announcement and represents the latest draft of the specification. It is also the first in a planned 6-month release cycle.

    Many thanks to everyone who contributed to this release.

    All commits since last release

    New/Breaking:

    These are syntactic rules or semantic behavior which are different from the previous version. GraphQL service libraries should ensure these incorporated.

    • [#229] New Validation Rule: Unique directives per location.
    • [#83] New Literal Value: null.
    • [#221] Arguments enforce Non-Null types with field errors, and Variables and Arguments distinguish between null and not-provided when applying default values.
    • [#191] JSON object serialization should order keys in a predictable way.

    Clarifying:

    These are clarifications and improvements to the specification which in many cases make ambiguous sections more explicit. GraphQL service libraries should check to ensure their behavior matches the specifiction.

    • [c9b6827] Better explanation of interpreting escape sequences in strings.
    • [f42dab5] Explain when build-in scalars can be omitted from a schema.
    • [79caa41] Use U+1234 instead of 0x1234 to refer to unicode code points.
    • [#221] Adds full algorithm definitions for Execution.
    • [#219] Ensure | is included as a possible Punctuator.
    • [#213] Clarify how to coerce null for List types.
    • [#177] Fix issue with value completion for objects with sub-selections.
    • [0599414] Object and Interfaces must declare at least one field.
    • [7c36326] Removed reference to experimental subscriptions feature.

    Note: Many grammar and consistency commits were provided by the community, but only changes notable for their clarification of ambiguity were listed.

    Source code(tar.gz)
    Source code(zip)
  • April2016(Apr 7, 2016)

    http://facebook.github.io/graphql/April2016/

    GraphQL is still an active working draft specification. As GraphQL is used by more teams in more environments it continues to improve. This milestone represents the most up to date version of the GraphQL specification for those building GraphQL services.

    Most of the changes since the October 2015 edition have been clarifying edits and fixing small mistakes, however there have been notable additions, changes, and clarifications.

    A huge thanks to all community members who submitted pull requests and reported issues that lead to these improvements!

    Breaking:

    • Introspection of Directives now queries for a locations Enum instead of onField, onOperation, onFragment booleans. (https://github.com/facebook/graphql/commit/1c38e6ac16de82a2a28487c8f193d673e39a1e33)
    • The @skip and @include directives are no longer allowed to be used directly on Fragment Definitions. (https://github.com/facebook/graphql/commit/1c38e6ac16de82a2a28487c8f193d673e39a1e33)

    Changes:

    • The order of fields in the response is now well defined by the query. (https://github.com/facebook/graphql/commit/d4b4e67f083ff6699a8f5fac5e069faba89c5bbb)
    • Implementation of an interface allows for additional field arguments, provided that those arguments are not required. (https://github.com/facebook/graphql/commit/5741ea734ebfc7d44f28b1763092b0894f24f48d)
    • Implementation of an interface allows for a covariant rather than invariant return type. (https://github.com/facebook/graphql/commit/0b4fd58f1765fb80506f872209c3fea3c50db3f1)
    • Directives are allowed to be different on overlapping fields. (https://github.com/facebook/graphql/commit/6a639dada86699edcc9e633b73d8d5b8992ac102)
    • Two overlapping fields which can never be queried on the same object are allowed to have different arguments. (https://github.com/facebook/graphql/commit/6a639dada86699edcc9e633b73d8d5b8992ac102)
    • Two overlapping fields must have compatible response shapes rather than equal return types. (https://github.com/facebook/graphql/commit/d481d173749a03e342434070d14fb47116272dfa)
    • An operation must not define two variables of the same name. (https://github.com/facebook/graphql/commit/89475ac11668efdbafd16e0b784b37982ca0cede)

    Clarifications:

    • Better explanation for when validation must occur, including support for memoizing the result of validation before execution. (https://github.com/facebook/graphql/commit/1feb5622f61ba17d69728f7f9c42efc305c822d9)
    • Provided variable values need to be coerced before execution. (https://github.com/facebook/graphql/commit/ffbb14e0215f8b1d3a2ad6ab4f60f66fd1f856f0)
    • When @skip and @include directives are both used, one does not have precedence over the other. (https://github.com/facebook/graphql/commit/914c62aa1895ea6a73026a6d82d5c5169d7c21e5)
    • Overlapping field validation is recursive. (https://github.com/facebook/graphql/commit/14c93e8cc713a9075db380565c724f7e9fdb4b2b)
    • When a non-null field throws an error, that error is propagated. (https://github.com/facebook/graphql/commit/c589e2ef23d0bd0347418ff133237bee465be6ac)
    Source code(tar.gz)
    Source code(zip)
    GraphQL-Spec-April-2016.zip(48.18 KB)
  • October2015(Oct 2, 2015)

    http://facebook.github.io/graphql/October2015/

    The GraphQL Specification Working Draft was first published three months ago today and what has happened since has been stunning. GraphQL is now available in many other languages, all built by members of the community.

    Part of the reason for publishing a working draft was to get feedback and improve. We've gotten tons of great feedback which has led to many improvements in GraphQL. There are more exciting improvements ahead as research continues in GraphQL query subscription, streaming responses, and more.

    As improvements continue, we thought it would be helpful to tag regular "releases" of the GraphQL Spec drafts and publish a changelog to make it easier to follow GraphQL's development. This marks the first in what will become regular releases of the GraphQL Spec.

    Copious improvements have been made to clarity. There is still more to be done to make the spec as clear as possible, but a huge thanks to the many awesome contributors who submitted pull requests and issues in an effort to make the GraphQL spec easier to understand.

    In addition to clarifying changes, there also have been quite a few grammar and semantic changes as GraphQL continues to evolve.

    Grammar and Semantic Changes:

    • Inline fragments type conditions are now optional (664fc0e94a8cd8fa20427990190c75ba824cec92)
    • Operation names are now optional (02af0fde955b7e7a3887a75fc6740efbfc5be2e1)
    • Unicode support has been clarified and restricted (11fba0296096f50e8f914e94559348160516a5ea, af5c288b1f4f833a07c12b08e2047a37c10b3231)
    • Input objects now parse redundant fields, but this becomes a validation error (794e69937009663b9c9e7a748e45b2d777f2e6cb)
    • Object types implementing interfaces validation became stricter (90784b462cc19a19653a6aa7c83a194161095174)
    • Union types now only require one type, loosening validation (972fd5aae01195b018d305c82e43f714f9a41679)
    • Added validation rule that arguments to a field must be unique (c5b3b649f9d3ca30e0f7da94b6c16de4cd779915)
    • Added validation rule that operation names in a document must be unique (65d46bbc4f7c091a589cf7b3b6247ef944707ce8)
    • Added validation rule that fragment names in a document must be unique (994ba71790796d08864ef11706d55db929e258d8)
    • Ensure __type introspection field always has name argument by speccing it to be Non-Null (43c31140550bdbb9c96817099930c29752f07349)
    • Float literals may omit a decimal part if they include an exponent part (d04ea228ba2bb0d0cb3bcef43f656a135169f97b)
    • Enum values cannot be true, false, or null (a12f6df77772cc4c86b69e01d9e4ea7addb09dce)
    • Variable types can be List and Non-Null (5c6e700f630d0741979691ec41f85a53fa68ab8e)
    • Fully described Names (5c27ccb8c7e17c9314396b5c2ecf0f7b39ef01e2)
    • Directives can now take arguments and introduced @include and @skip directives (9e68777f0ee50809de1f10c55fdd909e618e7fe1)
    Source code(tar.gz)
    Source code(zip)
    GraphQL-Spec-October-2015.zip(45.87 KB)
GraphQL security auditing script with a focus on performing batch GraphQL queries and mutations

BatchQL BatchQL is a GraphQL security auditing script with a focus on performing batch GraphQL queries and mutations. This script is not complex, and

Assetnote 267 Dec 24, 2022
A Django GraphQL Starter that uses graphene and graphene_django to interface GraphQL.

Django GraphQL Starter GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data... According to the doc

0101 Solutions 1 Jan 10, 2022
MGE-GraphQL is a Python library for building GraphQL mutations fast and easily

MGE-GraphQL Introduction MGE-GraphQL is a Python library for building GraphQL mutations fast and easily. Data Validations: A similar data validation w

MGE Software 4 Apr 23, 2022
A Python 3.6+ port of the GraphQL.js reference implementation of GraphQL.

GraphQL-core 3 GraphQL-core 3 is a Python 3.6+ port of GraphQL.js, the JavaScript reference implementation for GraphQL, a query language for APIs crea

GraphQL Python 458 Dec 13, 2022
This is a simple Python that will parse instanceStats GraphQL Query into a CSV

GraphQL Python Labs - by Gabs the CSE Table of Contents About The Project Getting Started Prerequisites Installation and Usage Roadmap Contributing Li

Gabriel (Gabs) Cerioni 1 Oct 27, 2021
tartiflette-aiohttp is a wrapper of aiohttp which includes the Tartiflette GraphQL Engine, do not hesitate to take a look of the Tartiflette project.

tartiflette-aiohttp is a wrapper of aiohttp which includes the Tartiflette GraphQL Engine. You can take a look at the Tartiflette API documentation. U

tartiflette 60 Nov 8, 2022
ASGI support for the Tartiflette GraphQL engine

tartiflette-asgi is a wrapper that provides ASGI support for the Tartiflette Python GraphQL engine. It is ideal for serving a GraphQL API over HTTP, o

tartiflette 99 Dec 27, 2022
GraphQL Engine built with Python 3.6+ / asyncio

Tartiflette is a GraphQL Server implementation built with Python 3.6+. Summary Motivation Status Usage Installation Installation dependencies Tartifle

tartiflette 839 Dec 31, 2022
tartiflette-aiohttp is a wrapper of aiohttp which includes the Tartiflette GraphQL Engine, do not hesitate to take a look of the Tartiflette project.

tartiflette-aiohttp is a wrapper of aiohttp which includes the Tartiflette GraphQL Engine. You can take a look at the Tartiflette API documentation. U

tartiflette 60 Nov 8, 2022
ASGI support for the Tartiflette GraphQL engine

tartiflette-asgi is a wrapper that provides ASGI support for the Tartiflette Python GraphQL engine. It is ideal for serving a GraphQL API over HTTP, o

tartiflette 99 Dec 27, 2022
graphw00f is Server Engine Fingerprinting utility for software security professionals looking to learn more about what technology is behind a given GraphQL endpoint.

graphw00f - GraphQL Server Fingerprinting graphw00f (inspired by wafw00f) is the GraphQL fingerprinting tool for GQL endpoints. Table of Contents How

Dolev Farhi 282 Jan 4, 2023
Lavrigon - A Python Webservice to check the status of any given local service via a REST call

lavrigon A Python Webservice to check the status of any given local service via

null 3 Jan 2, 2022
Django registration and authentication with GraphQL.

Django GraphQL Auth Django registration and authentication with GraphQL. Demo About Abstract all the basic logic of handling user accounts out of your

pedrobern 301 Dec 9, 2022
Django Project with Rest and Graphql API's

Django-Rest-and-Graphql # 1. Django Project Setup With virtual environment: mkdir {project_name}. To install virtual Environment sudo apt-get install

Shubham Agrawal 5 Nov 22, 2022
Generate a FullStack Playground using GraphQL and FastAPI 🚀

FastQL - FastAPI GraphQL Playground Generate a FullStack playground using FastAPI and GraphQL and Ariadne ?? . This Repository is based on this Articl

OBytes 109 Dec 23, 2022
This is a minimal project using graphene with django and user authentication to expose a graphql endpoint.

Welcome This is a minimal project using graphene with django and user authentication to expose a graphql endpoint. Definitely checkout how I have mana

yosef salmalian 1 Nov 18, 2021
🔪 Facebook Messenger to email bridge based on reverse engineered auth and GraphQL APIs.

Unzuckify This repository has a small Python application which allows me to receive an email notification when somebody sends me a Facebook message. W

Radon Rosborough 33 Dec 18, 2022
Blazing fast GraphQL endpoints finder using subdomain enumeration, scripts analysis and bruteforce.

Graphinder Graphinder is a tool that extracts all GraphQL endpoints from a given domain. Run with docker docker run -it -v $(pwd):/usr/bin/graphinder

Escape 76 Dec 28, 2022
A plug and play GraphQL API for Wagtail, powered by Strawberry 🍓

Strawberry Wagtail ?? A plug and play GraphQL API for Wagtail, powered by Strawberry ?? ⚠️ Strawberry wagtail is currently experimental, please report

Patrick Arminio 27 Nov 27, 2022