Add notes from Apollo GraphQL courses
This commit is contained in:
parent
2da598d3d3
commit
05a6d17a8e
4 changed files with 245 additions and 4 deletions
88
Databases/GraphQL/Apollo/Apollo_Client.md
Normal file
88
Databases/GraphQL/Apollo/Apollo_Client.md
Normal 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.
|
113
Databases/GraphQL/Apollo/Apollo_Server.md
Normal file
113
Databases/GraphQL/Apollo/Apollo_Server.md
Normal 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:
|
||||
|
||||

|
||||
|
||||
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 });
|
||||
```
|
|
@ -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:
|
|||
|
||||

|
||||
|
||||
// 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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue