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
 | 
					# 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.
 | 
					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
 | 
					      soldout: false
 | 
				
			||||||
      stores: [{ store: "London" }]
 | 
					      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
 | 
					### Returning a product through a query
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```graphql
 | 
					```graphql
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Add new image of this working in GraphiQL
 | 
					// 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.
 | 
					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 `!`.
 | 
					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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Descriptions are comments that allow you to document your Schema
 | 
					Descriptions are comments that allow you to document your Schema
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue