# Retrieve a GraphQL Schema

## Enable Introspection

### Enabling Introspection on Your Application

#### Using Apollo

When creating a new instance of the `ApolloServer`, you have to provide an object describing your resolvers and type definitions. This object can also include an `introspection` parameter.

```ts
const server = new ApolloServer({
  typeDefs,
  resolvers,
  introspection: true,
})
```

This option is documented in the [`ApolloServer` reference](<https://www.apollographql.com/docs/apollo-server/api/apollo-server/#introspection>)

#### Fine-Tuning

Using [Apollo plugins](<https://www.apollographql.com/docs/apollo-server/integrations/plugins/>), you can also have better access control over this query. Here is an example of a plugin that prevents access to the introspection query if the request doesn't feature the CLI header.

```ts
const introspectionPlugin = {
  requestDidStart() {
    return {
      async willSendResponse(requestContext) {
        const { request, response } = requestContext;

        if (request.http.headers.get('x-cli-access') !== 'true') {
          if (request.operationName === 'IntrospectionQuery') {
            response.data = null;
            response.errors = [
              {
                message: 'Introspection query not allowed',
                extensions: {
                  code: 'FORBIDDEN'
                }
              }
            ];
          }
        }
      }
    };
  }
}
```

### Retrieving the Schema

You can retrieve the GraphQL schema using various methods:

#### Using cURL

```bash
curl --location 'https://example.com/graphql' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{"query":"query IntrospectionQuery { __schema { queryType { name } mutationType { name } subscriptionType { name } types { ...FullType } directives { name description locations args { ...InputValue } } } } fragment FullType on __Type { kind name description fields(includeDeprecated: true) { name description args { ...InputValue } type { ...TypeRef } isDeprecated deprecationReason } inputFields { ...InputValue } interfaces { ...TypeRef } enumValues(includeDeprecated: true) { name description isDeprecated deprecationReason } possibleTypes { ...TypeRef } } fragment InputValue on __InputValue { name description type { ...TypeRef } defaultValue } fragment TypeRef on __Type { kind name ofType { kind name ofType { kind name ofType { kind name ofType { kind name ofType { kind name ofType { kind name ofType { kind name } } } } } } } } } ","variables":{}}' \
> introspection.json
```
