# Introduction to GraphQL

## [GraphQL terminology](https://docs.github.com/en/graphql/guides/introduction-to-graphql#graphql-terminology)

The GitHub GraphQL API represents an architectural and conceptual shift from the GitHub REST API. You will likely encounter some new terminology in the GraphQL API [reference docs](https://docs.github.com/en/graphql).

## [Schema](https://docs.github.com/en/graphql/guides/introduction-to-graphql#schema)

A schema defines a GraphQL API's type system. It describes the complete set of possible data (objects, fields, relationships, everything) that a client can access. Calls from the client are [validated](https://graphql.org/learn/validation/) and [executed](https://graphql.org/learn/execution/) against the schema. A client can find information about the schema via [introspection](https://docs.github.com/en/graphql/guides/introduction-to-graphql#discovering-the-graphql-api). A schema resides on the GraphQL API server. For more information, see [Discovering the GraphQL API](https://docs.github.com/en/graphql/guides/introduction-to-graphql#discovering-the-graphql-api).

## [Field](https://docs.github.com/en/graphql/guides/introduction-to-graphql#field)

A field is a unit of data you can retrieve from an object. As the [official GraphQL docs](https://graphql.org/learn/schema/) say: "The GraphQL query language is basically about selecting fields on objects."

The [official spec](https://spec.graphql.org/June2018/#sec-Language.Fields) also says about fields:

> All GraphQL operations must specify their selections down to fields which return scalar values to ensure an unambiguously shaped response.

This means that if you try to return a field that is not a scalar, schema validation will throw an error. You must add nested subfields until all fields return scalars.

## [Argument](https://docs.github.com/en/graphql/guides/introduction-to-graphql#argument)

An argument is a set of key-value pairs attached to a specific field. Some fields require an argument. [Mutations](https://docs.github.com/en/graphql/guides/forming-calls-with-graphql#about-mutations) require an input object as an argument.

## [Implementation](https://docs.github.com/en/graphql/guides/introduction-to-graphql#implementation)

A GraphQL schema may use the term *implements* to define how an object inherits from an [interface](https://docs.github.com/en/graphql/reference/interfaces).

Here's a contrived example of a schema that defines interface `X` and object `Y`:

```graphql
interface X {
  some_field: String!
  other_field: String!
}

type Y implements X {
  some_field: String!
  other_field: String!
  new_field: String!
}
```

This means object `Y` requires the same fields/arguments/return types that interface `X` does, while adding new fields specific to object `Y`. (The `!` means the field is required.)

In the reference docs, you'll find that:

- Each [object](https://docs.github.com/en/graphql/reference/objects) lists the interface(s) *from which it inherits* under **Implements**.
- Each [interface](https://docs.github.com/en/graphql/reference/interfaces) lists the objects *that inherit from it* under **Implementations**.

## [Connection](https://docs.github.com/en/graphql/guides/introduction-to-graphql#connection)

Connections let you query related objects as part of the same call. With connections, you can use a single GraphQL call where you would have to use multiple calls to a REST API. For more information, see [Migrating from REST to GraphQL](https://docs.github.com/en/graphql/guides/migrating-from-rest-to-graphql).

It's helpful to picture a graph: dots connected by lines. The dots are nodes, the lines are edges. A connection defines a relationship between nodes.

## [Edge](https://docs.github.com/en/graphql/guides/introduction-to-graphql#edge)

Edges represent connections between nodes. When you query a connection, you traverse its edges to get to its nodes. Every `edges` field has a `node` field and a `cursor` field. Cursors are used for pagination. For more information, see [Using pagination in the GraphQL API](https://docs.github.com/en/graphql/guides/using-pagination-in-the-graphql-api).

## [Node](https://docs.github.com/en/graphql/guides/introduction-to-graphql#node)

*Node* is a generic term for an object. You can look up a node directly, or you can access related nodes via a connection. If you specify a `node` that does not return a [scalar](https://docs.github.com/en/graphql/reference/scalars), you must include subfields until all fields return scalars. For information on accessing node IDs via the REST API and using them in GraphQL queries, see [Using global node IDs](https://docs.github.com/en/graphql/guides/using-global-node-ids).

## [Discovering the GraphQL API](https://docs.github.com/en/graphql/guides/introduction-to-graphql#discovering-the-graphql-api)

GraphQL is [introspective](https://graphql.org/learn/introspection/). This means you can query a GraphQL schema for details about itself.

- Query `__schema` to list all types defined in the schema and get details about each:

  ```graphql
  query {
    __schema {
      types {
        name
        kind
        description
        fields {
          name
        }
      }
    }
  }
  ```

- Query `__type` to get details about any type:

  ```graphql
  query {
    __type(name: "Repository") {
      name
      kind
      description
      fields {
        name
      }
    }
  }
  ```

- You can also run an *introspection query* of the schema via a `GET` request:

  ```shell
  curl -H "Authorization: bearer TOKEN" https://api.github.com/graphql
  ```

:::note
If you get the response `"message": "Bad credentials"` or `401 Unauthorized`, check that you are using a valid token. If you receive a `403` error with `Resource not accessible by personal access token`, ensure that your fine-grained personal access token is targeted to the correct resource owner. For example, it must target the organization that owns the repository you are trying to access.
:::
  

  The results are in JSON, so we recommend pretty-printing them for easier reading and searching. You can use a command-line tool like [jq](https://stedolan.github.io/jq/) or pipe the results into `python -m json.tool` for this purpose.

  Alternatively, you can pass the `idl` media type to return the results in IDL format, which is a condensed version of the schema:

  ```shell
  $ curl -H "Authorization: bearer TOKEN" -H "Accept: application/vnd.github.v4.idl" \
  https://api.github.com/graphql
  ```

:::note[]
The introspection query is probably the only `GET` request you'll run in GraphQL. If you're passing a body, the GraphQL request method is `POST`, whether it's a query or a mutation.
:::

  For more information about performing queries, see [Forming calls with GraphQL](https://docs.github.com/en/graphql/guides/forming-calls-with-graphql).
