GraphQL - Apollo - Certificate Flashcards

1
Q

Which of these are benefits of schema-first design?

A

Schema-first design accelerates development by making teams more independent.

  • reduce total development time
  • it enables teams to work in parallel
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Which of these accurately describes a graph?

A

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

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

””” comment

A

Triple “double quotes” allow you to add line breaks for clearer formatting of lengthier comments.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

What does graphql package?

A

The graphql package provides the core logic for parsing and validating GraphQL queries.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

What does apollo-server package?

A

The apollo-server package provides a full-fledged, spec-compliant GraphQL server with some nice utilities like the gql template literal that we’ll use in a moment.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

What is this gql ?

A

const { gql } = require(‘apollo-server’);

It’s a tagged template literal, used for wrapping GraphQL strings like the schema definition we’re about to write.

This converts GraphQL strings into the format that Apollo libraries expect when working with operations and schemas, and it also enables syntax highlighting.

Next, let’s declare a typeDefs (short for “type definitions”) constant, assigning the gql template where our definitions will go. While we’re at it, let’s export typeDefs now, because we’ll need it for our server file later on.

const typeDefs = gql`
  # Schema definitions go here
`;
module.exports = typeDefs;
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

What does an exclamation mark after a field’s type indicate?

A

An exclamation mark after a field’s type marks it as non-nullable.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

What always true about the Query type?

A

The Query type’s fields define which data clients can query from our schema.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

On the back-end side, our first goal is to create a GraphQL server that can…

A
  1. Receive an incoming GraphQL query from our client
  2. Validate that query against our newly created schema
  3. Populate the queried schema fields with mocked data
  4. Return the populated fields as a response

The Apollo Server library helps us implement this server quickly, painlessly, and in a production-ready way.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

To enable basic mocked data, we could…

A

we could provide mocks:true to the ApolloServer constructor, like so:

const server = new ApolloServer({
  typeDefs,
  mocks: true,
});
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

Apollo Studio Explorer

A

To write our test query, we’ll use the Apollo Studio Explorer. The Explorer is free to use, and it provides awesome development features like interactive query building, query history, and response hints. This will make building our queries fast and fun.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

Apollo Studio Explorer: Create Graph

A

Click Create Graph to create a new development graph that’s connected to your local server. A development graph is only accessible to you, and it stays updated with any changes you make to your server’s schema.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

Apollo Client: 2 packages: graphql and @apollo/client

A
  • graphql provides the core logic for parsing GraphQL queries.
  • @apollo/client contains pretty much everything we need to build our client, including an in-memory cache, local state management, and error handling.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

ApolloClient

A

ApolloClient is the class that represents Apollo Client itself. We create a new client instance like so:

const client = new ApolloClient({
  // options go here
});

We need to provide a couple of options to the constructor. The first is the uri option, which we use to specify the location of our GraphQL server. Our server is running locally at localhost:4000, so the uri option looks like this:

uri: ‘http://localhost:4000’,

Second, every instance of ApolloClient uses an in-memory cache. This enables it to store and reuse query results so it doesn’t have to make as many network requests. This makes our app’s user experience feel much snappier.

We provide an InMemoryCache instance in the cache option, like so:

cache: new InMemoryCache(),

Final result:
const client = new ApolloClient({
  uri: 'http://localhost:4000',
  cache: new InMemoryCache(),
});
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

how do we make client available to the components in our React app?

A

ApolloProvider

Using ApolloProvider is a convenient way to make Apollo Client available everywhere it’s needed

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

ApolloProvider

A

The ApolloProvider component uses React’s Context API to make a configured Apollo Client instance available throughout a React component tree. To use it, we wrap our app’s top-level components in the ApolloProvider component and pass it our client instance as a prop:

ReactDOM.render(

,
document.getElementById(‘root’),
);

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
17
Q

useQuery React hook

A

The useQuery React hook is the primary API for executing queries in an Apollo application. We run a query within a React component by calling useQuery and passing it our GraphQL query string. This makes running queries from React components a breeze.

When our component renders, useQuery returns an object from Apollo Client that contains loading, error, and data properties that we can use to render our UI.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
18
Q

How do we execute queries in our front-end app?

A

Pass your query to the hook useQuery and render the response with loading, error and data properties.

19
Q

How does our Catstronauts client send queries to our GraphQL server?

A

Most GraphQL clients send queries in HTTP POST or GET requests. The query itself is formatted as a string.

20
Q

Which of these are actions that our GraphQL server takes when it receives a request?

A

When our server receives the HTTP request, it first extracts the query string.

It parses and transforms it into something it can better manipulate: a tree-structured document called an AST (Abstract Syntax Tree).

With this AST, the server validates the query against the types and fields in our schema.

If anything is off (e.g. a requested field is not defined in the schema or the query is malformed), the server throws an error and sends it right back to the app.

21
Q

Which of these are situations where our GraphQL server will throw an error?

A

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

22
Q

Which of these are responsibilities of a resolver function?

A

A resolver function is responsible for populating the data for a single field in your schema (from database or REST API)

23
Q

When a query executes successfully, which of these is included in the object returned by the GraphQL server?

A

A successful query’s result always matches the query’s shape.

24
Q

What is data sources?

A

The data that resolvers retrieve can come from all kinds of places: a database, a third-party API, webhooks, and so on. These are called data sources. The beauty of GraphQL is that you can mix any number of data sources to create an API that serves the needs of your client app.

25
Q

How GraphQL server can access REST API?

A

It could call the API directly using fetch, or we can use a handy helper class called a DataSource. This class takes care of a few challenges and limitations that come with the direct approach.

26
Q

What is N+1 problem?

A

Let’s say our /tracks endpoint returns 100 tracks. Then we’d make one call to get the array, followed by 100 additional calls to get each track’s author info.

Now, what if our 100 tracks were all made by the same author? We’d make one call for the tracks, retrieve our 100 tracks, then make 100 calls to get the exact same author.

Sounds pretty inefficient, right? We’d end up making 101 calls where we could have made only 2.

This is a classic example of the N+1 problem. “1” refers to the call to fetch the top-level tracks field and “N” is the number of subsequent calls to fetch the author subfield for each track.

27
Q

What makes the N + 1 problem inefficient?

A

Making N calls to the exact same endpoint to fetch the exact same data is very inefficient, especially if N is a large number!

28
Q

How might a resource cache be useful for our data source?

A

In an endpoint-based API, clients can use HTTP caching to easily avoid refetching resources, and for identifying when two resources are the same.

29
Q

We define a constructor method inside the class. Inside, we’ll call super(). Why?

A

We’ll call super() to make sure we get access to our RESTDataSource features.

30
Q

What is a resolver’s mission?

A

A resolver’s mission is to populate the data for a field in your schema.

31
Q

What exactly is a resolver?

A

A resolver is a function. It has the same name as the field that it populates data for. It can fetch data from any data source, then transforms that data into the shape your client requires.

32
Q

How will our resolvers interact with our data source?

A

This is where context comes in. Resolver functions have a specific signature with 4 optional parameters: parent, args, context, and info.

tracksForHome: (parent, args, context, info) => {},

Let’s go over each parameter briefly to understand what they’re responsible for:

parent:
parent is the returned value of the resolver for this field’s parent. This will be useful when dealing with resolver chains.

args:
args is an object that contains all GraphQL arguments that were provided for the field by the GraphQL operation. When querying for a specific item (such as a specific track instead of all tracks), in client-land we’ll make a query with an id argument that will be accessible via this args parameter in server-land. We’ll cover this further in Lift-off III.

context:
context is an object shared across all resolvers that are executing for a particular operation. The resolver needs this context argument to share state, like authentication information, a database connection, or in our case the RESTDataSource.

info:
info contains information about the operation’s execution state, including the field name, the path to the field from the root, and more. It’s not used as frequently as the others, but it can be useful for more advanced actions like setting cache policies at the resolver level.

33
Q

What is the context parameter useful for?

A

the third positional argument that’s passed to every resolver function.

34
Q

Best practice, when working on your resolvers and data sources?

A

Try to keep resolver functions as thin as possible. By doing so, you make your API more resilient to future changes.

You can safely refactor your data fetching code, or change the source entirely from a REST API to a database, without breaking your API.

This also keeps your resolvers readable and easier to understand, which comes in handy as you define more and more of them!

35
Q

Apollo Server - which 3 elements includes?

A

Apollo Server is where all the elements we’ve built previously (the schema, the resolvers, and the data sources) come together in perfect coordination.

36
Q

Why do we need to configure the dataSources key in ApolloServer options?

A

Configuring the dataSources option for our ApolloServer will make our RestDataSource API available to all resolvers from their context parameter.

37
Q

What is the difference between ‘node-fetch’ and ‘RESTDataSource’?

A

The subsequent calls to the query using RESTDataSource were much faster.

38
Q

errors

A

errors is an array containing each error that occurred as the server tried to execute the query. So yes, there could be multiple! ApolloServer provides error codes that will help to narrow down what caused the issues.

39
Q

Within a server response (with error), what keys can you expect to find in the JSON object?

A

‘data’ and ‘errors’ are the two keys you’ll find in the response.

40
Q

When you query a field that is not in the schema, what error code will the server send?

A

GRAPHQL_VALIDATION_FAILED error code means the GraphQL operation is not valid against the server’s schema. Either a field isn’t defined, or you might have a typo somewhere in your query!

41
Q

Given this schema field: missions: [Mission!], what does it mean?

A

The ! symbol means that the field is non-nullable. The list itself is nullable, but the items inside it (Mission!) are non-nullable.

42
Q

Where can we add entry points to our schema?

A

The Query type contains the entry points to our schema. In future courses, we’ll take a look at 2 other possible entry points: Mutation and Subscription.

43
Q

What is argument?

A

An argument is a value you provide for a particular field in your query.

Arguments can help you retrieve specific objects, filter through a set of objects, or even transform the field’s returned value.

44
Q

Resolver parameters

A

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.