Add notes from Apollo GraphQL courses

This commit is contained in:
Thomas Bishop 2022-11-11 16:30:31 +00:00
parent 2da598d3d3
commit 05a6d17a8e
4 changed files with 245 additions and 4 deletions

View file

@ -0,0 +1,88 @@
---
title: Apollo Client
categories:
- Databases
tags: [graph-ql, apollo]
---
# Apollo Client
Apollo Client is the client-side counterpart to [Apollo Server](/Databases/GraphQL/Apollo/Apollo_Server.md). We use it for managing queries and mutations from the frontend to our Apollo GraphQL server. It is specifically designed to work with React.
## Initializing the client
We initialise the client and set-up in memory caching to reduce network requests:
```js
const client = new ApolloClient({
uri: "http://localhost:4000",
cache: new InMemoryCache(),
});
```
> The uri property must match the location of our Apollo server.
## Utilising the provider
Apollo Provides a top level application context that we can wrap our React app in. This will provide access to the client object from anywhere within the app, eg:
```jsx
ReactDOM.render(
<ApolloProvider client={client}>
<GlobalStyles />
<Pages />
</ApolloProvider>,
document.getElementById("root")
);
```
## Running a query
### Query constants
To run a query against our server we must define a query contant first. We use a `gql` literal again:
```js
import { gql } from "@apollo/client";
const TRACKS = gql`
query GetTracks {
tracksForHome {
id
title
thumbnail
length
modulesCount
author {
name
photo
}
}
}
`;
```
The convention is to name the query constant in `ALL_CAPS`.
### `useQuery` hook
The `useQuery` hook provides a straightforward wrapper for sending queries and receiving data back from the server.
When a component renders, `useQuery` returns an object from the Apollo Client that contains loading, error, and data properties.
```jsx
const { loading, error, data } = useQuery(TRACKS);
const Tracks = () => {
const { loading, error, data } = useQuery(TRACKS);
if (loading) return "Loading...";
if (error) return `Error! ${error.message}`;
return <Layout grid>{JSON.stringify(data)}</Layout>;
};
```
- We destructure the `loading, error, data` variables that are returned from the hook
- We pass in our query constant as an argument.
- In the example we just render the serialized data but we could of course pass the data as a prop and map through it in an embedded child component.

View file

@ -0,0 +1,113 @@
---
title: Apollo Server
categories:
- Databases
tags: [graph-ql, apollo]
---
# Apollo Server
> Apollo Server is the part of the Apollo suite that we use to create the backend of a GraphQL project; a GraphQL server.
It is able to do the following:
- Receive an incoming GraphQL query from a client
- Validate that query against the server schema
- Populate the queried schema fields
- Return the fields as a response
## Example schema
We will use the following schema in the examples
```js
const typeDefs = gql`
type Query {
"Get tracks array for homepage grid"
tracksForHome: [Track!]!
}
"A track is a group of Modules that teaches about a specific topic"
type Track {
id: ID!
"The track's title"
title: String!
"The track's main author"
author: Author!
"The track's main illustration to display in track card or track page detail"
thumbnail: String
"The track's approximate length to complete, in minutes"
length: Int
"The number of modules this track contains"
modulesCount: Int
}
"Author of a complete Track"
type Author {
id: ID!
"Author's first and last name"
name: String!
"Author's profile picture url"
photo: String
}
`;
module.exports = typeDefs;
```
## Setting up the server
```js
const { ApolloServer } = require("apollo-server");
const typeDefs = require("./schema");
const server = new ApolloServer({ typeDefs });
server.listen().then(() => {
console.log(`
Server is running!
Listening on port 4000
Query at http://localhost:4000
`);
});
```
When we access the local URL we are able to access the Apollo server using the Explorer GUI. This automatically loads our schema and is basically a more fancy version of GraphiQL:
![](/img/apollo-explorer.png)
It makes it easy to read descriptions of the dataypes and to construct queries by clicking to insert fields.
### Adding some mock data
We are not connected to a database yet but we can create a mock that will enable us to run test queries.
We do this just by updating the Apollo Server options. We can either use generic dummy data or provide our own mock.
#### Generic mock
```js
const server = new ApolloServer({ typeDefs, mocks: true });
```
#### Custom mock
```js
const mocks = {
Track: () => ({
id: () => "track_01",
title: () => "Astro Kitty, Space Explorer",
author: () => {
return {
name: "Grumpy Cat",
photo:
"https://res.cloudinary.com/dety84pbu/image/upload/v1606816219/kitty-veyron-sm_mctf3c.jpg",
};
},
thumbnail: () =>
"https://res.cloudinary.com/dety84pbu/image/upload/v1598465568/nebula_cat_djkt9r.jpg",
length: () => 1210,
modulesCount: () => 6,
}),
};
const server = new ApolloServer({ typeDefs, mocks });
```

View file

@ -7,7 +7,7 @@ tags: [graph-ql]
# Creating a GraphQL server
> We will use Node.js to create a basic GraphQL server that will serve data from a product database
> We will use Node.js to create a basic GraphQL server that will serve data from a product database.
Our server will allow us to add products to a database through a mutatation and to query the products that we have added. We will use a JS object instead of a real database.
@ -226,7 +226,11 @@ mutation {
soldout: false
stores: [{ store: "London" }]
}
)
) {
price
name
soldout
}
}
```
@ -234,12 +238,13 @@ This is represented in GraphiQL as follows:
![](/img/graphql3.png)
// TODO: Add bit about the value we want returned see 8:20 and explain what is returned
We should always return something, even if we are applying  mutation, hence we add the properties at the bottom as the ones we want to return.
### Returning a product through a query
```graphql
```
// Add new image of this working in GraphiQL

View file

@ -8,7 +8,9 @@ tags: [graph-ql]
SDL is the formal name for the syntax of GraphQL schemas.
A schema is a collection of object types that contain fields. Each field has a type of its own. A field's type can be a primitive/scalar value (such as an Int or a String), or it can be another object type (just like a custom type in TS).
## Types
A schema is a collection of object types that contain fields. Each field has a type of its own. A field's type can be a primitive/scalar value (such as an `Int` or a `String`), or it can be another object type (just like a custom type in TS).
A schema's type can be non-nullable which is to say, a required field. We indicate this with `!`.
@ -30,6 +32,39 @@ type Pet {
}
```
## Queries
A query is also a schema type but of a special sort.
> The fields of this type are entry points into the rest of the schema. These are the top-level fields that the client can query for.
For example if we had this type:
```graphql
type Track {
id: ID!
title: String!
author: Author!
thumbnail: String
length: Int
modulesCount: Int
}
```
We could define a type to access a give `Track` as follows:
```graphql
type Query {
tracksForHomePage: [Track!]!
}
```
Then use this type as the basis for a query:
```
```
## Descriptions
Descriptions are comments that allow you to document your Schema