GraphQL Interview Reference Sheet
Tags: graphql, webdev, beginners, tutorial
Published: 2023-03-05 09:50:26

Here's a quick reference sheet for everything GraphQL. I started building this while studying for interviews, and have kept it updated ever since. Enjoy!

### Schema First Design
Schema-first design typically involves three major steps:
1.  **Defining the schema**: We identify which data our feature requires, and then we structure our schema to provide that data as intuitively as possible.
2.  **Back-end implementation**: We build out our GraphQL API using Apollo Server and fetch the required data from whichever data sources contain it. In this first course, we will be using mocked data. In a following course, we'll connect our app to a live REST data source.
3.  **Front-end implementation**: Our client consumes data from our GraphQL API to render its views.

### Graph
The graph represents an app's data points and how they're connected as a collection of nodes and edges.

### Type Definition
```gql
type PascalCase {
	key1: String! (! means non-nullable)
	key2: Int
	key3: [OtherType] (array of OtherType)
}
```

### Query Type
The `Query` type's fields define which data clients can query from our schema. The `Query` type contains the entry points to our schema. There are 2 other possible entry points: `Mutation` and `Subscription`.

### Query Definition
```
query queryName {
	key1
	key2
}
```

#### Best practices when creating client queries
- Assign each query string to a constant with an ALL_CAPS name.
- Export query definitions for use in unit tests.
- Test out queries in the Apollo Studio Explorer and copy them over.
- Wrap each query in the gql template literal.

Queries must use valid GraphQL syntax and must only include schema-defined fields.

#### GraphQL Mutations
Mutation names should start with a verb, followed by whatever data you're modifying.

Queries and mutations are both types of GraphQL operations. Queries are read operations that always retrieve data. Mutations are write operations that always modify data. Similar to `Query` fields, fields of the `Mutation` type are also entry points into a GraphQL API.

#### GraphQL Variables
Variables are denoted by the $ symbol. They are used to provide dynamic values for  arguments to avoid including hardcoded values in a query. Each one's type must match the type specified in the schema.

```gql
  query getMission($isScheduled: Boolean) {
    mission(scheduled: $isScheduled) {
      id
      codename
    }
  }
```

### GraphQL Resolvers
A resolver function is responsible for populating the data for a single field in your schema.

When a query executes successfully, a data key containing a result object with the same shape as the query is returned.

#### Resolver Chains
One should define a separate resolver for each field, including subfields which need to fetch more data.

A resolver function populates the data for a field in your schema. The function has four parameters. The first, `parent`, contains the returned data of the previous function in the  resolver chain. The second, `args`, is an object that contains all the arguments provided to the field. We use the third parameter, `context`, to access data sources such as a database or REST API. Finally, the fourth parameter, `info`, contains informational properties about the operation state.

#### Apollo Data Sources
They help avoid the N+1 problem of data-fetching, which is, making N calls to the exact same endpoint to fetch the exact same data.

#### Resolver Cache
How might a resource cache be useful for our data source?
- It helps resolve query fields that have already been fetched much faster.
- It helps manage the mix of different endpoints with different cache policies.
- It prevents unnecessary REST API calls for data that doesn't get updated frequently.

### Apollo GraphQL
#### useQuery Hook
The useQuery hook returns an object with 3 useful properties that we use in our app: `loading` indicates whether the query has completed and results have been returned. `error` is an object that contains any errors that the operation has thrown. `data` contains the results of the query after it has completed. To set variables in our query, we declare them in the second parameter of the `useQuery` hook, inside an options object.

#### useMutation Hook
We use hooks to send requests to our GraphQL API from a React client. To send a mutation, we use the `useMutation` hook. This returns an array, where the first element is the mutate function used to trigger the mutation. The second element is an object with more information about the mutation, such as `loading`, `error` and `data` . This hook takes in a GraphQL operation as the first parameter. It also takes in an `options` object as the second parameter, where properties like `variables` are set.

### Entities
Entities are GraphQL Schemas can be resolved across multiple subgraphs.

### Anatomy of GraphQL Types
```
type Query {
  getMission(isScheduled: Boolean): [Mission!]!
}

type Mutation {
	createMission(updatedMission: Mission!): Mission
}

type Mission {
	id: ID!
	name: String
	# ...etc
}
```

### Security
Authentication is checking that a user is who they say they are. Authorization is checking that a user is allowed to do what they're trying to do.
-   **Authentication** is determining whether a given user is logged in, and subsequently determining which user someone is.
-   **Authorization** is determining what a given user has permission to do or see.

**Note:** `AuthenticationError` and `ForbiddenError` are both error subclasses defined by Apollo Server. For more information on these and other kinds of errors, check out the [Apollo Docs on error handling](https://www.apollographql.com/docs/apollo-server/data/errors/).

With field-level authorization, each resolver determines whether the logged-in user has permission to access a field, query, or mutation in the schema.

## GraphQL Directives
A **directive** decorates part of a GraphQL schema or operation with additional configuration. GraphQL servers can read a GraphQL document's directives and perform custom logic as appropriate.

Each directive can only appear in _certain_ locations within a GraphQL schema or operation. These locations are listed in the directive's definition.

```graphql
directive @deprecated( reason: String = "No longer supported" ) on FIELD_DEFINITION | ARGUMENT_DEFINITION | INPUT_FIELD_DEFINITION | ENUM_VALUE
```

### Defaults
1. Deprecated - Marks the schema definition of a field or enum value as deprecated with an optional reason.
2. Skip - If `true`, the decorated field or fragment in an operation is _not_ resolved by the GraphQL server.
3. Include - If `false`, the decorated field or fragment in an operation is _not_ resolved by the GraphQL server.

## Federation
In a federated architecture, your individual GraphQL APIs are called **subgraphs**, and they're composed into a **supergraph**. By querying your supergraph's router, clients can fetch data from all of your subgraphs with a single request:

![GraphQL Federation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4xq7piiozbs8d16o6wgh.png)

The **router** serves as the public access point for your supergraph. It receives incoming GraphQL operations and intelligently routes them across your subgraphs. To clients, this looks exactly the same as querying any other GraphQL server—no client-side configuration is required.

### References
- https://www.apollographql.com/docs/apollo-server/data/data-sources/