Learn how to build an API using GraphQL with Apollo Server 2.0, using Firestore as a backend data source. https://github.com/arjunyel/firestore-apollo-graphql

- Get more episodes at https://angularfirebase.com/
- GraphQL https://graphql.org/learn/
- Apollo 2.0 https://www.apollographql.com/docs/apollo-server/v2/
2024-02-04T07:31:00.965Z
nova-2
2-general-nova
2024-01-09.29447
30089e05-99d1-4376-b32e-c263170674af
2921d95c-df03-43f4-937a-acbfdc97d0ed
f04ba4779bec9758cebba1b4ab4d3b928b7ce555bc21d0f1d38476f6ca0c4b3d
67875a7f-c9c4-48a0-aa55-5bdb8a91c34a
deprecated
One of the big predictions people are making in 2018 is that GraphQL will make RESTful APIs obsolete.
In today's episode, we'll learn how to build a GraphQL API from scratch using Apollo Server 2 point o and Node JS.
If you're new here, make sure to like and subscribe.
And I wanna send a huge thank you out to Arjun Yalamancelli.
He's the mastermind behind the code in this video.
And if you need a talented developer in Denver, he comes highly recommended.
So let's kick things off by talking about GraphQL from a very high level.
Imagine you have an Angular app that communicates with a bunch of different back end data sources.
Traditionally, you would do this with either a REST API or a client side SDK.
When you hit a REST one point, it's the server that determines the shape of the data that gets sent back to the client.
What happens is that you'll hit a REST one point and it will respond with a bunch of data that you don't know anything about and that you don't need.
GraphQL is a query language that solves this problem by sitting in between your back end and front end.
It allows the server to define exactly what data is available, and it allows the client to only request the data that it actually needs to provide the user experience.
What's really cool is that you can use it with any back end data source.
In this video, we'll use Firestore and set up a Node.
Js server with Apollo to deliver the API.
This video is a 2 part In this first installment, we will set up the back end API.
And in the second part, we will use Angular to consume this API from the front end.
When you set up a GraphQL API, it provides this really nice playground that you can use to start sending requests and this just works out of the box.
What we're going to do in the code is set up interfaces that describe the data that's available on the server.
This is super powerful because the client can probe the back end in advance to find out What types are available and how they can be requested.
This means you get amazing developer tooling even on a foreign API because you know exactly what's available and how it can be requested.
You can see here I've requested all the interface names and the ones we're interested in are tweet and user.
Let's say we want to request all of the tweets from our database, But we only want the ID and the number of alikes.
All we need to do is type out the shape of our data on the left and then send it to the server on the right and it will respond with JSON in the exact shape that we requested.
And this is live data you're looking at that lives in the Firestore database.
But it can come from any data source or even multiple data sources at the same time.
The tweets also have a text property.
So if we want to include text in our request, we just add that to the interface and it returns the text from the database.
This can be extremely useful if you have relational data that you need to join from multiple sources which is commonly the case with NoSQL databases.
Let's imagine we want to query a user plus all of that user's tweets which live in a completely different collection in Firestore.
You can pass arguments to GraphQL which in this will be the user ID, then we'll get autocomplete for all the properties available.
So if we wanna just pull the screen name, we can do that easily.
But tweets can also belong to a user and it's a property on the user interface.
So we can apply it here and then request some data about the tweets that we wanna return back that will only belong to this user.
So that's really only the tip of the iceberg with GraphQL.
But the main takeaway is that it allows you to request data in exactly the way it should be consumed in the front end, which is a big difference from REST APIs.
Now we're ready to write some code, but first, I have some really good news.
Just a couple days ago, Node.
Js became available on the App Engine standard runtime, which means you can use it for free and it's super easy to integrate into a Firebase project.
I first wanna point out that you can find the full setup Actions on the GitHub repo for this video, but I do wanna point out a few of the more important parts.
I'll be writing this in TypeScript, but the code is fully compatible with Vanilla JS if you prefer that.
The first thing you wanna do is install Apollo Server 2 point o as well as GraphQL.
Then to make things fully compatible with TypeScript, there's a few extra things Add it to the tsconfig, so make sure to grab the tsconfig from the repo.
From here, we can install Firebase Admin and then we'll need to go to the Firebase console tool and download our service account.
You can find it under settings and then go to service accounts and then download it into the root of the project as service account dot JSON.
I've set up an index dot ts file.
And in this file, I'm first going to import a few dependencies starting with firebase admin and then a reference to our service account, And then we'll initialize the app with that service account.
That gives us full access to the data in Firestore.
From here, we'll import Apollo Server and GraphQL.
We'll also bring in Apollo error and validation so we can handle errors gracefully on the server.
There are 2 main pieces to a GraphQL API.
The first one is your GraphQL type definitions, which is where you write actual GraphQL code to define the shape of the data that's available on the server.
The second half of this puzzle are your resolvers.
This is where you tell GraphQL how to return the actual data to the client through the API.
So first, let's start by defining our type definitions.
You can define an object by calling type with the name of the object.
And then there's a number of built in data types.
For example, ID is just a string that is supposed to be unique.
Then you have common data types that you would expect like string, integer, and things like that.
When you put brackets around something, that means that it should return an array of that interface.
You might also notice the exclamation point after each property.
That just means the API will always promise to return that data type.
It won't return a null value.
So a user can have an array of tweets, which we've modeled here, But a tweet can only have one user.
So we'll set some properties for our tweet object, but this time we'll type the user to the user schema that we just defined in the previous step.
But if you look in the database, you'll notice that our actual user data doesn't have any tweets objects nested on it.
Tweets are their own isolated collection that are completely decoupled from users.
That's important to make note of because in the next step, we'll use resolvers to combine all this stuff together.
Now the last thing we need in our schema is the query, which can be thought of as Like the main entry point into your API.
In this case, we can enter the API through tweets or we can enter it through the user with their user ID.
At this point, everything that's available to be fetched on our API is well defined, but we still need a method to actually retrieve this data.
For that, we'll define an object called resolvers where each property in this object matches one of our interfaces.
Data that already exists on the Firestore document can be inferred automatically.
But remember, we don't have any tweets available on the actual user itself.
So we need to write a method that can resolve that data.
In Firebase, this is really easy because we can use the admin database called the tweets collection and then just query where the user ID equals the user ID on this object.
Then we call git to return that as a promise, and that'll be a snapshot.
And the final step is to just map that snapshot down to its actual raw data object.
If this code fails at runtime, we want to throw an error to handle it gracefully which we can do inside of the try catch block by throwing an Apollo error.
Tweets will follow a very similar process.
In this case, we just need to return a single Firestore document because every tweet has an associated user ID.
But we wanna be able to return additional data if the user requests it on their GraphQL query.
The last resolver that we need is the query.
This defines how we get the data for the root documents being the tweet and the user.
Tweets are a collection, so we can simply return those as a Firestore collection.
So what we're looking at here is just Firebase 101.
We're pointing to a collection and then retrieving it as an array of documents.
The user query is also very similar, but the main difference is we're passing an argument to the method being the user ID.
We can Access the argument data as the second argument in this method.
So now we can retrieve our user based on the user ID that's passed in by whoever is making the GraphQL query.
It's very possible that they will pass in an ID that doesn't exist.
So we want to handle that with a validation error.
If you remember earlier, we used exclamation points to only return valid types.
If that user doesn't exist, we need to return a validation error instead.
Okay.
Just a couple of lines of code left.
We just need to combine these two pieces together by passing them to an Apollo Server instance.
The Apollo Server feels just like an Express JS server.
We just call listen on it and we're good to go.
All you need to do at this point is compile your TypeScript code, which you can do with the TSC command or there's a command in the main repo.
When you run the script, you can pull up localhost and get the Playground to start sending queries to your API.
But we're not just going to stop here.
There's this really cool thing called Apollo engine that can handle things like caching and tracing and it does it all in a really nice UI.
You'll first need to register for an Apollo engine API key, then all you need to do is add it to your Apollo Server config and you're good to go.
This gives you access to a dashboard where you monitor all the queries to see the exact latency of each one and also inspect errors in real time.
And let's also go ahead and deploy our app to a production server.
Assuming you have the Google Cloud command line tools installed, all you have to do is create an app dot YAML file with the Node JS 8 runtime in it.
Run gcloudapp deploy and your GraphQL API is now available for the world to use.
I'm gonna go ahead and wrap things up there.
If this video helped you, please like and subscribe.
And stay tuned for the 2nd installment where we build out the front end in Angular with the Apollo Angular Library.
And if you want to take things to the next level, consider becoming a pro member at AngularFire base.com.
Thanks for watching, and I'll talk to you soon.

Speaker 0: One of the big predictions people are making in 2018 is that GraphQL will make RESTful APIs obsolete. In today's episode, we'll learn how to build a GraphQL API from scratch using Apollo Server 2 point o and Node JS. If you're new here, make sure to like and subscribe. And I wanna send a huge thank you out to Arjun Yalamancelli. He's the mastermind behind the code in this video.

And if you need a talented developer in Denver, he comes highly recommended. So let's kick things off by talking about GraphQL from a very high level. Imagine you have an Angular app that communicates with a bunch of different back end data sources. Traditionally, you would do this with either a REST API or a client side SDK. When you hit a REST one point, it's the server that determines the shape of the data that gets sent back to the client.

What happens is that you'll hit a REST one point and it will respond with a bunch of data that you don't know anything about and that you don't need. GraphQL is a query language that solves this problem by sitting in between your back end and front end. It allows the server to define exactly what data is available, and it allows the client to only request the data that it actually needs to provide the user experience. What's really cool is that you can use it with any back end data source. In this video, we'll use Firestore and set up a Node.

Js server with Apollo to deliver the API. This video is a 2 part In this first installment, we will set up the back end API. And in the second part, we will use Angular to consume this API from the front end. When you set up a GraphQL API, it provides this really nice playground that you can use to start sending requests and this just works out of the box. What we're going to do in the code is set up interfaces that describe the data that's available on the server.

This is super powerful because the client can probe the back end in advance to find out What types are available and how they can be requested. This means you get amazing developer tooling even on a foreign API because you know exactly what's available and how it can be requested. You can see here I've requested all the interface names and the ones we're interested in are tweet and user. Let's say we want to request all of the tweets from our database, But we only want the ID and the number of alikes. All we need to do is type out the shape of our data on the left and then send it to the server on the right and it will respond with JSON in the exact shape that we requested.

And this is live data you're looking at that lives in the Firestore database. But it can come from any data source or even multiple data sources at the same time. The tweets also have a text property. So if we want to include text in our request, we just add that to the interface and it returns the text from the database. This can be extremely useful if you have relational data that you need to join from multiple sources which is commonly the case with NoSQL databases.

Let's imagine we want to query a user plus all of that user's tweets which live in a completely different collection in Firestore. You can pass arguments to GraphQL which in this will be the user ID, then we'll get autocomplete for all the properties available. So if we wanna just pull the screen name, we can do that easily. But tweets can also belong to a user and it's a property on the user interface. So we can apply it here and then request some data about the tweets that we wanna return back that will only belong to this user.

So that's really only the tip of the iceberg with GraphQL. But the main takeaway is that it allows you to request data in exactly the way it should be consumed in the front end, which is a big difference from REST APIs. Now we're ready to write some code, but first, I have some really good news. Just a couple days ago, Node. Js became available on the App Engine standard runtime, which means you can use it for free and it's super easy to integrate into a Firebase project.

I first wanna point out that you can find the full setup Actions on the GitHub repo for this video, but I do wanna point out a few of the more important parts. I'll be writing this in TypeScript, but the code is fully compatible with Vanilla JS if you prefer that. The first thing you wanna do is install Apollo Server 2 point o as well as GraphQL. Then to make things fully compatible with TypeScript, there's a few extra things Add it to the tsconfig, so make sure to grab the tsconfig from the repo. From here, we can install Firebase Admin and then we'll need to go to the Firebase console tool and download our service account.

You can find it under settings and then go to service accounts and then download it into the root of the project as service account dot JSON. I've set up an index dot ts file. And in this file, I'm first going to import a few dependencies starting with firebase admin and then a reference to our service account, And then we'll initialize the app with that service account. That gives us full access to the data in Firestore. From here, we'll import Apollo Server and GraphQL.

We'll also bring in Apollo error and validation so we can handle errors gracefully on the server. There are 2 main pieces to a GraphQL API. The first one is your GraphQL type definitions, which is where you write actual GraphQL code to define the shape of the data that's available on the server. The second half of this puzzle are your resolvers. This is where you tell GraphQL how to return the actual data to the client through the API.

So first, let's start by defining our type definitions. You can define an object by calling type with the name of the object. And then there's a number of built in data types. For example, ID is just a string that is supposed to be unique. Then you have common data types that you would expect like string, integer, and things like that.

When you put brackets around something, that means that it should return an array of that interface. You might also notice the exclamation point after each property. That just means the API will always promise to return that data type. It won't return a null value. So a user can have an array of tweets, which we've modeled here, But a tweet can only have one user.

So we'll set some properties for our tweet object, but this time we'll type the user to the user schema that we just defined in the previous step. But if you look in the database, you'll notice that our actual user data doesn't have any tweets objects nested on it. Tweets are their own isolated collection that are completely decoupled from users. That's important to make note of because in the next step, we'll use resolvers to combine all this stuff together. Now the last thing we need in our schema is the query, which can be thought of as Like the main entry point into your API.

In this case, we can enter the API through tweets or we can enter it through the user with their user ID. At this point, everything that's available to be fetched on our API is well defined, but we still need a method to actually retrieve this data. For that, we'll define an object called resolvers where each property in this object matches one of our interfaces. Data that already exists on the Firestore document can be inferred automatically. But remember, we don't have any tweets available on the actual user itself.

So we need to write a method that can resolve that data. In Firebase, this is really easy because we can use the admin database called the tweets collection and then just query where the user ID equals the user ID on this object. Then we call git to return that as a promise, and that'll be a snapshot. And the final step is to just map that snapshot down to its actual raw data object. If this code fails at runtime, we want to throw an error to handle it gracefully which we can do inside of the try catch block by throwing an Apollo error.

Tweets will follow a very similar process. In this case, we just need to return a single Firestore document because every tweet has an associated user ID. But we wanna be able to return additional data if the user requests it on their GraphQL query. The last resolver that we need is the query. This defines how we get the data for the root documents being the tweet and the user.

Tweets are a collection, so we can simply return those as a Firestore collection. So what we're looking at here is just Firebase 101. We're pointing to a collection and then retrieving it as an array of documents. The user query is also very similar, but the main difference is we're passing an argument to the method being the user ID. We can Access the argument data as the second argument in this method.

So now we can retrieve our user based on the user ID that's passed in by whoever is making the GraphQL query. It's very possible that they will pass in an ID that doesn't exist. So we want to handle that with a validation error. If you remember earlier, we used exclamation points to only return valid types. If that user doesn't exist, we need to return a validation error instead.

Okay. Just a couple of lines of code left. We just need to combine these two pieces together by passing them to an Apollo Server instance. The Apollo Server feels just like an Express JS server. We just call listen on it and we're good to go.

All you need to do at this point is compile your TypeScript code, which you can do with the TSC command or there's a command in the main repo. When you run the script, you can pull up localhost and get the Playground to start sending queries to your API. But we're not just going to stop here. There's this really cool thing called Apollo engine that can handle things like caching and tracing and it does it all in a really nice UI. You'll first need to register for an Apollo engine API key, then all you need to do is add it to your Apollo Server config and you're good to go.

This gives you access to a dashboard where you monitor all the queries to see the exact latency of each one and also inspect errors in real time. And let's also go ahead and deploy our app to a production server. Assuming you have the Google Cloud command line tools installed, all you have to do is create an app dot YAML file with the Node JS 8 runtime in it. Run gcloudapp deploy and your GraphQL API is now available for the world to use. I'm gonna go ahead and wrap things up there.

If this video helped you, please like and subscribe. And stay tuned for the 2nd installment where we build out the front end in Angular with the Apollo Angular Library. And if you want to take things to the next level, consider becoming a pro member at AngularFire base.com. Thanks for watching, and I'll talk to you soon.
One of the big predictions people are making in 2018 is that GraphQL will make RESTful APIs obsolete. In today's episode, we'll learn how to build a GraphQL API from scratch using Apollo Server 2 point o and Node JS. If you're new here, make sure to like and subscribe. And I wanna send a huge thank you out to Arjun Yalamancelli. He's the mastermind behind the code in this video.
And if you need a talented developer in Denver, he comes highly recommended. So let's kick things off by talking about GraphQL from a very high level. Imagine you have an Angular app that communicates with a bunch of different back end data sources. Traditionally, you would do this with either a REST API or a client side SDK.
databases
When you hit a REST one point, it's the server that determines the shape of the data that gets sent back to the client. What happens is that you'll hit a REST one point and it will respond with a bunch of data that you don't know anything about and that you don't need.
GraphQL is a query language that solves this problem by sitting in between your back end and front end. It allows the server to define exactly what data is available, and it allows the client to only request the data that it actually needs to provide the user experience. What's really cool is that you can use it with any back end data source. In this video, we'll use Firestore and set up a Node. Js server with Apollo to deliver the API. This video is a 2 part In this first installment, we will set up the back end API.
databases
streaming
youtube
And in the second part, we will use Angular to consume this API from the front end. When you set up a GraphQL API, it provides this really nice playground that you can use to start sending requests and this just works out of the box. What we're going to do in the code is set up interfaces that describe the data that's available on the server. This is super powerful because the client can probe the back end in advance to find out What types are available and how they can be requested. This means you get amazing developer tooling even on a foreign API because you know exactly what's available and how it can be requested. You can see here I've requested all the interface names and the ones we're interested in are tweet and user. Let's say we want to request all of the tweets from our database, But we only want the ID and the number of alikes. All we need to do is type out the shape of our data on the left and then send it to the server on the right and it will respond with JSON in the exact shape that we requested. And this is live data you're looking at that lives in the Firestore database. But it can come from any data source or even multiple data sources at the same time. The tweets also have a text property. So if we want to include text in our request, we just add that to the interface and it returns the text from the database. This can be extremely useful if you have relational data that you need to join from multiple sources which is commonly the case with NoSQL databases. Let's imagine we want to query a user plus all of that user's tweets which live in a completely different collection in Firestore. You can pass arguments to GraphQL which in this will be the user ID, then we'll get autocomplete for all the properties available.
databases
twitter
software development
software
programming
networking
So if we wanna just pull the screen name, we can do that easily. But tweets can also belong to a user and it's a property on the user interface. So we can apply it here and then request some data about the tweets that we wanna return back that will only belong to this user. So that's really only the tip of the iceberg with GraphQL. But the main takeaway is that it allows you to request data in exactly the way it should be consumed in the front end, which is a big difference from REST APIs. Now we're ready to write some code, but first, I have some really good news.
twitter
databases
Just a couple days ago, Node. Js became available on the App Engine standard runtime, which means you can use it for free and it's super easy to integrate into a Firebase project.
I first wanna point out that you can find the full setup Actions on the GitHub repo for this video, but I do wanna point out a few of the more important parts. I'll be writing this in TypeScript, but the code is fully compatible with Vanilla JS if you prefer that.
animation
The first thing you wanna do is install Apollo Server 2 point o as well as GraphQL. Then to make things fully compatible with TypeScript, there's a few extra things Add it to the tsconfig, so make sure to grab the tsconfig from the repo. From here, we can install Firebase Admin and then we'll need to go to the Firebase console tool and download our service account. You can find it under settings and then go to service accounts and then download it into the root of the project as service account dot JSON. I've set up an index dot ts file. And in this file, I'm first going to import a few dependencies starting with firebase admin and then a reference to our service account, And then we'll initialize the app with that service account.
That gives us full access to the data in Firestore. From here, we'll import Apollo Server and GraphQL. We'll also bring in Apollo error and validation so we can handle errors gracefully on the server. There are 2 main pieces to a GraphQL API. The first one is your GraphQL type definitions, which is where you write actual GraphQL code to define the shape of the data that's available on the server.
databases
The second half of this puzzle are your resolvers. This is where you tell GraphQL how to return the actual data to the client through the API. So first, let's start by defining our type definitions. You can define an object by calling type with the name of the object.
databases
And then there's a number of built in data types. For example, ID is just a string that is supposed to be unique. Then you have common data types that you would expect like string, integer, and things like that. When you put brackets around something, that means that it should return an array of that interface. You might also notice the exclamation point after each property.
That just means the API will always promise to return that data type. It won't return a null value. So a user can have an array of tweets, which we've modeled here, But a tweet can only have one user. So we'll set some properties for our tweet object, but this time we'll type the user to the user schema that we just defined in the previous step. But if you look in the database, you'll notice that our actual user data doesn't have any tweets objects nested on it. Tweets are their own isolated collection that are completely decoupled from users. That's important to make note of because in the next step, we'll use resolvers to combine all this stuff together.
twitter
Now the last thing we need in our schema is the query, which can be thought of as Like the main entry point into your API.
In this case, we can enter the API through tweets or we can enter it through the user with their user ID. At this point, everything that's available to be fetched on our API is well defined, but we still need a method to actually retrieve this data. For that, we'll define an object called resolvers where each property in this object matches one of our interfaces.
twitter
Data that already exists on the Firestore document can be inferred automatically.
But remember, we don't have any tweets available on the actual user itself. So we need to write a method that can resolve that data. In Firebase, this is really easy because we can use the admin database called the tweets collection and then just query where the user ID equals the user ID on this object. Then we call git to return that as a promise, and that'll be a snapshot. And the final step is to just map that snapshot down to its actual raw data object.
twitter
If this code fails at runtime, we want to throw an error to handle it gracefully which we can do inside of the try catch block by throwing an Apollo error. Tweets will follow a very similar process. In this case, we just need to return a single Firestore document because every tweet has an associated user ID. But we wanna be able to return additional data if the user requests it on their GraphQL query. The last resolver that we need is the query.
twitter
This defines how we get the data for the root documents being the tweet and the user. Tweets are a collection, so we can simply return those as a Firestore collection. So what we're looking at here is just Firebase 101. We're pointing to a collection and then retrieving it as an array of documents.
twitter
The user query is also very similar, but the main difference is we're passing an argument to the method being the user ID. We can Access the argument data as the second argument in this method. So now we can retrieve our user based on the user ID that's passed in by whoever is making the GraphQL query. It's very possible that they will pass in an ID that doesn't exist. So we want to handle that with a validation error. If you remember earlier, we used exclamation points to only return valid types. If that user doesn't exist, we need to return a validation error instead. Okay. Just a couple of lines of code left. We just need to combine these two pieces together by passing them to an Apollo Server instance. The Apollo Server feels just like an Express JS server. We just call listen on it and we're good to go. All you need to do at this point is compile your TypeScript code, which you can do with the TSC command or there's a command in the main repo. When you run the script, you can pull up localhost and get the Playground to start sending queries to your API. But we're not just going to stop here.
There's this really cool thing called Apollo engine that can handle things like caching and tracing and it does it all in a really nice UI. You'll first need to register for an Apollo engine API key, then all you need to do is add it to your Apollo Server config and you're good to go.
robotics
This gives you access to a dashboard where you monitor all the queries to see the exact latency of each one and also inspect errors in real time. And let's also go ahead and deploy our app to a production server. Assuming you have the Google Cloud command line tools installed, all you have to do is create an app dot YAML file with the Node JS 8 runtime in it. Run gcloudapp deploy and your GraphQL API is now available for the world to use.
google
I'm gonna go ahead and wrap things up there. If this video helped you, please like and subscribe. And stay tuned for the 2nd installment where we build out the front end in Angular with the Apollo Angular Library. And if you want to take things to the next level, consider becoming a pro member at AngularFire base.com. Thanks for watching, and I'll talk to you soon.
One of the big predictions people are making in 2018 is that GraphQL will make RESTful APIs obsolete. In today's episode, we'll learn how to build a GraphQL API from scratch using Apollo Server 2 point o and Node JS. If you're new here, make sure to like and subscribe. And I wanna send a huge thank you out to Arjun Yalamancelli. He's the mastermind behind the code in this video. And if you need a talented developer in Denver, he comes highly recommended. So let's kick things off by talking about GraphQL from a very high level. Imagine you have an Angular app that communicates with a bunch of different back end data sources. Traditionally, you would do this with either a REST API or a client side SDK. When you hit a REST one point, it's the server that determines the shape of the data that gets sent back to the client. What happens is that you'll hit a REST one point and it will respond with a bunch of data that you don't know anything about and that you don't need. GraphQL is a query language that solves this problem by sitting in between your back end and front end. It allows the server to define exactly what data is available, and it allows the client to only request the data that it actually needs to provide the user experience. What's really cool is that you can use it with any back end data source. In this video, we'll use Firestore and set up a Node. Js server with Apollo to deliver the API. This video is a 2 part In this first installment, we will set up the back end API. And in the second part, we will use Angular to consume this API from the front end. When you set up a GraphQL API, it provides this really nice playground that you can use to start sending requests and this just works out of the box. What we're going to do in the code is set up interfaces that describe the data that's available on the server. This is super powerful because the client can probe the back end in advance to find out What types are available and how they can be requested. This means you get amazing developer tooling even on a foreign API because you know exactly what's available and how it can be requested. You can see here I've requested all the interface names and the ones we're interested in are tweet and user. Let's say we want to request all of the tweets from our database, But we only want the ID and the number of alikes. All we need to do is type out the shape of our data on the left and then send it to the server on the right and it will respond with JSON in the exact shape that we requested. And this is live data you're looking at that lives in the Firestore database. But it can come from any data source or even multiple data sources at the same time. The tweets also have a text property. So if we want to include text in our request, we just add that to the interface and it returns the text from the database. This can be extremely useful if you have relational data that you need to join from multiple sources which is commonly the case with NoSQL databases. Let's imagine we want to query a user plus all of that user's tweets which live in a completely different collection in Firestore. You can pass arguments to GraphQL which in this will be the user ID, then we'll get autocomplete for all the properties available. So if we wanna just pull the screen name, we can do that easily. But tweets can also belong to a user and it's a property on the user interface. So we can apply it here and then request some data about the tweets that we wanna return back that will only belong to this user. So that's really only the tip of the iceberg with GraphQL. But the main takeaway is that it allows you to request data in exactly the way it should be consumed in the front end, which is a big difference from REST APIs. Now we're ready to write some code, but first, I have some really good news. Just a couple days ago, Node. Js became available on the App Engine standard runtime, which means you can use it for free and it's super easy to integrate into a Firebase project. I first wanna point out that you can find the full setup Actions on the GitHub repo for this video, but I do wanna point out a few of the more important parts. I'll be writing this in TypeScript, but the code is fully compatible with Vanilla JS if you prefer that. The first thing you wanna do is install Apollo Server 2 point o as well as GraphQL. Then to make things fully compatible with TypeScript, there's a few extra things Add it to the tsconfig, so make sure to grab the tsconfig from the repo. From here, we can install Firebase Admin and then we'll need to go to the Firebase console tool and download our service account. You can find it under settings and then go to service accounts and then download it into the root of the project as service account dot JSON. I've set up an index dot ts file. And in this file, I'm first going to import a few dependencies starting with firebase admin and then a reference to our service account, And then we'll initialize the app with that service account. That gives us full access to the data in Firestore. From here, we'll import Apollo Server and GraphQL. We'll also bring in Apollo error and validation so we can handle errors gracefully on the server. There are 2 main pieces to a GraphQL API. The first one is your GraphQL type definitions, which is where you write actual GraphQL code to define the shape of the data that's available on the server. The second half of this puzzle are your resolvers. This is where you tell GraphQL how to return the actual data to the client through the API. So first, let's start by defining our type definitions. You can define an object by calling type with the name of the object. And then there's a number of built in data types. For example, ID is just a string that is supposed to be unique. Then you have common data types that you would expect like string, integer, and things like that. When you put brackets around something, that means that it should return an array of that interface. You might also notice the exclamation point after each property. That just means the API will always promise to return that data type. It won't return a null value. So a user can have an array of tweets, which we've modeled here, But a tweet can only have one user. So we'll set some properties for our tweet object, but this time we'll type the user to the user schema that we just defined in the previous step. But if you look in the database, you'll notice that our actual user data doesn't have any tweets objects nested on it. Tweets are their own isolated collection that are completely decoupled from users. That's important to make note of because in the next step, we'll use resolvers to combine all this stuff together. Now the last thing we need in our schema is the query, which can be thought of as Like the main entry point into your API. In this case, we can enter the API through tweets or we can enter it through the user with their user ID. At this point, everything that's available to be fetched on our API is well defined, but we still need a method to actually retrieve this data. For that, we'll define an object called resolvers where each property in this object matches one of our interfaces. Data that already exists on the Firestore document can be inferred automatically. But remember, we don't have any tweets available on the actual user itself. So we need to write a method that can resolve that data. In Firebase, this is really easy because we can use the admin database called the tweets collection and then just query where the user ID equals the user ID on this object. Then we call git to return that as a promise, and that'll be a snapshot. And the final step is to just map that snapshot down to its actual raw data object. If this code fails at runtime, we want to throw an error to handle it gracefully which we can do inside of the try catch block by throwing an Apollo error. Tweets will follow a very similar process. In this case, we just need to return a single Firestore document because every tweet has an associated user ID. But we wanna be able to return additional data if the user requests it on their GraphQL query. The last resolver that we need is the query. This defines how we get the data for the root documents being the tweet and the user. Tweets are a collection, so we can simply return those as a Firestore collection. So what we're looking at here is just Firebase 101. We're pointing to a collection and then retrieving it as an array of documents. The user query is also very similar, but the main difference is we're passing an argument to the method being the user ID. We can Access the argument data as the second argument in this method. So now we can retrieve our user based on the user ID that's passed in by whoever is making the GraphQL query. It's very possible that they will pass in an ID that doesn't exist. So we want to handle that with a validation error. If you remember earlier, we used exclamation points to only return valid types. If that user doesn't exist, we need to return a validation error instead. Okay. Just a couple of lines of code left. We just need to combine these two pieces together by passing them to an Apollo Server instance. The Apollo Server feels just like an Express JS server. We just call listen on it and we're good to go. All you need to do at this point is compile your TypeScript code, which you can do with the TSC command or there's a command in the main repo. When you run the script, you can pull up localhost and get the Playground to start sending queries to your API. But we're not just going to stop here. There's this really cool thing called Apollo engine that can handle things like caching and tracing and it does it all in a really nice UI. You'll first need to register for an Apollo engine API key, then all you need to do is add it to your Apollo Server config and you're good to go. This gives you access to a dashboard where you monitor all the queries to see the exact latency of each one and also inspect errors in real time. And let's also go ahead and deploy our app to a production server. Assuming you have the Google Cloud command line tools installed, all you have to do is create an app dot YAML file with the Node JS 8 runtime in it. Run gcloudapp deploy and your GraphQL API is now available for the world to use. I'm gonna go ahead and wrap things up there. If this video helped you, please like and subscribe. And stay tuned for the 2nd installment where we build out the front end in Angular with the Apollo Angular Library. And if you want to take things to the next level, consider becoming a pro member at AngularFire base.com. Thanks for watching, and I'll talk to you soon.
One
one
of
of
the
the
big
big
predictions
predictions
people
people
are
are
making
making
in
in
2018
2018
is
is
that
that
GraphQL
graphql
will
will
make
make
RESTful
restful
APIs
apis
obsolete.
obsolete
In
in
today's
today's
episode,
episode
we'll
we'll
learn
learn
how
how
to
to
build
build
a
a
GraphQL
graphql
API
api
from
from
scratch
scratch
using
using
Apollo
apollo
Server
server
2
2
point
point
o
o
and
and
Node
node
JS.
js
If
if
you're
you're
new
new
here,
here
make
make
sure
sure
to
to
like
like
and
and
subscribe.
subscribe
And
and
I
i
wanna
wanna
send
send
a
a
huge
huge
thank
thank
you
you
out
out
to
to
Arjun
arjun
Yalamancelli.
yalamancelli
He's
he's
the
the
mastermind
mastermind
behind
behind
the
the
code
code
in
in
this
this
video.
video
And
and
if
if
you
you
need
need
a
a
talented
talented
developer
developer
in
in
Denver,
denver
he
he
comes
comes
highly
highly
recommended.
recommended
So
so
let's
let's
kick
kick
things
things
off
off
by
by
talking
talking
about
about
GraphQL
graphql
from
from
a
a
very
very
high
high
level.
level
Imagine
imagine
you
you
have
have
an
an
Angular
angular
app
app
that
that
communicates
communicates
with
with
a
a
bunch
bunch
of
of
different
different
back
back
end
end
data
data
sources.
sources
Traditionally,
traditionally
you
you
would
would
do
do
this
this
with
with
either
either
a
a
REST
rest
API
api
or
or
a
a
client
client
side
side
SDK.
sdk
When
when
you
you
hit
hit
a
a
REST
rest
one
one
point,
point
it's
it's
the
the
server
server
that
that
determines
determines
the
the
shape
shape
of
of
the
the
data
data
that
that
gets
gets
sent
sent
back
back
to
to
the
the
client.
client
What
what
happens
happens
is
is
that
that
you'll
you'll
hit
hit
a
a
REST
rest
one
one
point
point
and
and
it
it
will
will
respond
respond
with
with
a
a
bunch
bunch
of
of
data
data
that
that
you
you
don't
don't
know
know
anything
anything
about
about
and
and
that
that
you
you
don't
don't
need.
need
GraphQL
graphql
is
is
a
a
query
query
language
language
that
that
solves
solves
this
this
problem
problem
by
by
sitting
sitting
in
in
between
between
your
your
back
back
end
end
and
and
front
front
end.
end
It
it
allows
allows
the
the
server
server
to
to
define
define
exactly
exactly
what
what
data
data
is
is
available,
available
and
and
it
it
allows
allows
the
the
client
client
to
to
only
only
request
request
the
the
data
data
that
that
it
it
actually
actually
needs
needs
to
to
provide
provide
the
the
user
user
experience.
experience
What's
what's
really
really
cool
cool
is
is
that
that
you
you
can
can
use
use
it
it
with
with
any
any
back
back
end
end
data
data
source.
source
In
in
this
this
video,
video
we'll
we'll
use
use
Firestore
firestore
and
and
set
set
up
up
a
a
Node.
node
Js
js
server
server
with
with
Apollo
apollo
to
to
deliver
deliver
the
the
API.
api
This
this
video
video
is
is
a
a
2
2
part
part
In
in
this
this
first
first
installment,
installment
we
we
will
will
set
set
up
up
the
the
back
back
end
end
API.
api
And
and
in
in
the
the
second
second
part,
part
we
we
will
will
use
use
Angular
angular
to
to
consume
consume
this
this
API
api
from
from
the
the
front
front
end.
end
When
when
you
you
set
set
up
up
a
a
GraphQL
graphql
API,
api
it
it
provides
provides
this
this
really
really
nice
nice
playground
playground
that
that
you
you
can
can
use
use
to
to
start
start
sending
sending
requests
requests
and
and
this
this
just
just
works
works
out
out
of
of
the
the
box.
box
What
what
we're
we're
going
going
to
to
do
do
in
in
the
the
code
code
is
is
set
set
up
up
interfaces
interfaces
that
that
describe
describe
the
the
data
data
that's
that's
available
available
on
on
the
the
server.
server
This
this
is
is
super
super
powerful
powerful
because
because
the
the
client
client
can
can
probe
probe
the
the
back
back
end
end
in
in
advance
advance
to
to
find
find
out
out
What
what
types
types
are
are
available
available
and
and
how
how
they
they
can
can
be
be
requested.
requested
This
this
means
means
you
you
get
get
amazing
amazing
developer
developer
tooling
tooling
even
even
on
on
a
a
foreign
foreign
API
api
because
because
you
you
know
know
exactly
exactly
what's
what's
available
available
and
and
how
how
it
it
can
can
be
be
requested.
requested
You
you
can
can
see
see
here
here
I've
i've
requested
requested
all
all
the
the
interface
interface
names
names
and
and
the
the
ones
ones
we're
we're
interested
interested
in
in
are
are
tweet
tweet
and
and
user.
user
Let's
let's
say
say
we
we
want
want
to
to
request
request
all
all
of
of
the
the
tweets
tweets
from
from
our
our
database,
database
But
but
we
we
only
only
want
want
the
the
ID
id
and
and
the
the
number
number
of
of
alikes.
alikes
All
all
we
we
need
need
to
to
do
do
is
is
type
type
out
out
the
the
shape
shape
of
of
our
our
data
data
on
on
the
the
left
left
and
and
then
then
send
send
it
it
to
to
the
the
server
server
on
on
the
the
right
right
and
and
it
it
will
will
respond
respond
with
with
JSON
json
in
in
the
the
exact
exact
shape
shape
that
that
we
we
requested.
requested
And
and
this
this
is
is
live
live
data
data
you're
you're
looking
looking
at
at
that
that
lives
lives
in
in
the
the
Firestore
firestore
database.
database
But
but
it
it
can
can
come
come
from
from
any
any
data
data
source
source
or
or
even
even
multiple
multiple
data
data
sources
sources
at
at
the
the
same
same
time.
time
The
the
tweets
tweets
also
also
have
have
a
a
text
text
property.
property
So
so
if
if
we
we
want
want
to
to
include
include
text
text
in
in
our
our
request,
request
we
we
just
just
add
add
that
that
to
to
the
the
interface
interface
and
and
it
it
returns
returns
the
the
text
text
from
from
the
the
database.
database
This
this
can
can
be
be
extremely
extremely
useful
useful
if
if
you
you
have
have
relational
relational
data
data
that
that
you
you
need
need
to
to
join
join
from
from
multiple
multiple
sources
sources
which
which
is
is
commonly
commonly
the
the
case
case
with
with
NoSQL
nosql
databases.
databases
Let's
let's
imagine
imagine
we
we
want
want
to
to
query
query
a
a
user
user
plus
plus
all
all
of
of
that
that
user's
user's
tweets
tweets
which
which
live
live
in
in
a
a
completely
completely
different
different
collection
collection
in
in
Firestore.
firestore
You
you
can
can
pass
pass
arguments
arguments
to
to
GraphQL
graphql
which
which
in
in
this
this
will
will
be
be
the
the
user
user
ID,
id
then
then
we'll
we'll
get
get
autocomplete
autocomplete
for
for
all
all
the
the
properties
properties
available.
available
So
so
if
if
we
we
wanna
wanna
just
just
pull
pull
the
the
screen
screen
name,
name
we
we
can
can
do
do
that
that
easily.
easily
But
but
tweets
tweets
can
can
also
also
belong
belong
to
to
a
a
user
user
and
and
it's
it's
a
a
property
property
on
on
the
the
user
user
interface.
interface
So
so
we
we
can
can
apply
apply
it
it
here
here
and
and
then
then
request
request
some
some
data
data
about
about
the
the
tweets
tweets
that
that
we
we
wanna
wanna
return
return
back
back
that
that
will
will
only
only
belong
belong
to
to
this
this
user.
user
So
so
that's
that's
really
really
only
only
the
the
tip
tip
of
of
the
the
iceberg
iceberg
with
with
GraphQL.
graphql
But
but
the
the
main
main
takeaway
takeaway
is
is
that
that
it
it
allows
allows
you
you
to
to
request
request
data
data
in
in
exactly
exactly
the
the
way
way
it
it
should
should
be
be
consumed
consumed
in
in
the
the
front
front
end,
end
which
which
is
is
a
a
big
big
difference
difference
from
from
REST
rest
APIs.
apis
Now
now
we're
we're
ready
ready
to
to
write
write
some
some
code,
code
but
but
first,
first
I
i
have
have
some
some
really
really
good
good
news.
news
Just
just
a
a
couple
couple
days
days
ago,
ago
Node.
node
Js
js
became
became
available
available
on
on
the
the
App
app
Engine
engine
standard
standard
runtime,
runtime
which
which
means
means
you
you
can
can
use
use
it
it
for
for
free
free
and
and
it's
it's
super
super
easy
easy
to
to
integrate
integrate
into
into
a
a
Firebase
firebase
project.
project
I
i
first
first
wanna
wanna
point
point
out
out
that
that
you
you
can
can
find
find
the
the
full
full
setup
setup
Actions
actions
on
on
the
the
GitHub
github
repo
repo
for
for
this
this
video,
video
but
but
I
i
do
do
wanna
wanna
point
point
out
out
a
a
few
few
of
of
the
the
more
more
important
important
parts.
parts
I'll
i'll
be
be
writing
writing
this
this
in
in
TypeScript,
typescript
but
but
the
the
code
code
is
is
fully
fully
compatible
compatible
with
with
Vanilla
vanilla
JS
js
if
if
you
you
prefer
prefer
that.
that
The
the
first
first
thing
thing
you
you
wanna
wanna
do
do
is
is
install
install
Apollo
apollo
Server
server
2
2
point
point
o
o
as
as
well
well
as
as
GraphQL.
graphql
Then
then
to
to
make
make
things
things
fully
fully
compatible
compatible
with
with
TypeScript,
typescript
there's
there's
a
a
few
few
extra
extra
things
things
Add
add
it
it
to
to
the
the
tsconfig,
tsconfig
so
so
make
make
sure
sure
to
to
grab
grab
the
the
tsconfig
tsconfig
from
from
the
the
repo.
repo
From
from
here,
here
we
we
can
can
install
install
Firebase
firebase
Admin
admin
and
and
then
then
we'll
we'll
need
need
to
to
go
go
to
to
the
the
Firebase
firebase
console
console
tool
tool
and
and
download
download
our
our
service
service
account.
account
You
you
can
can
find
find
it
it
under
under
settings
settings
and
and
then
then
go
go
to
to
service
service
accounts
accounts
and
and
then
then
download
download
it
it
into
into
the
the
root
root
of
of
the
the
project
project
as
as
service
service
account
account
dot
dot
JSON.
json
I've
i've
set
set
up
up
an
an
index
index
dot
dot
ts
ts
file.
file
And
and
in
in
this
this
file,
file
I'm
i'm
first
first
going
going
to
to
import
import
a
a
few
few
dependencies
dependencies
starting
starting
with
with
firebase
firebase
admin
admin
and
and
then
then
a
a
reference
reference
to
to
our
our
service
service
account,
account
And
and
then
then
we'll
we'll
initialize
initialize
the
the
app
app
with
with
that
that
service
service
account.
account
That
that
gives
gives
us
us
full
full
access
access
to
to
the
the
data
data
in
in
Firestore.
firestore
From
from
here,
here
we'll
we'll
import
import
Apollo
apollo
Server
server
and
and
GraphQL.
graphql
We'll
we'll
also
also
bring
bring
in
in
Apollo
apollo
error
error
and
and
validation
validation
so
so
we
we
can
can
handle
handle
errors
errors
gracefully
gracefully
on
on
the
the
server.
server
There
there
are
are
2
2
main
main
pieces
pieces
to
to
a
a
GraphQL
graphql
API.
api
The
the
first
first
one
one
is
is
your
your
GraphQL
graphql
type
type
definitions,
definitions
which
which
is
is
where
where
you
you
write
write
actual
actual
GraphQL
graphql
code
code
to
to
define
define
the
the
shape
shape
of
of
the
the
data
data
that's
that's
available
available
on
on
the
the
server.
server
The
the
second
second
half
half
of
of
this
this
puzzle
puzzle
are
are
your
your
resolvers.
resolvers
This
this
is
is
where
where
you
you
tell
tell
GraphQL
graphql
how
how
to
to
return
return
the
the
actual
actual
data
data
to
to
the
the
client
client
through
through
the
the
API.
api
So
so
first,
first
let's
let's
start
start
by
by
defining
defining
our
our
type
type
definitions.
definitions
You
you
can
can
define
define
an
an
object
object
by
by
calling
calling
type
type
with
with
the
the
name
name
of
of
the
the
object.
object
And
and
then
then
there's
there's
a
a
number
number
of
of
built
built
in
in
data
data
types.
types
For
for
example,
example
ID
id
is
is
just
just
a
a
string
string
that
that
is
is
supposed
supposed
to
to
be
be
unique.
unique
Then
then
you
you
have
have
common
common
data
data
types
types
that
that
you
you
would
would
expect
expect
like
like
string,
string
integer,
integer
and
and
things
things
like
like
that.
that
When
when
you
you
put
put
brackets
brackets
around
around
something,
something
that
that
means
means
that
that
it
it
should
should
return
return
an
an
array
array
of
of
that
that
interface.
interface
You
you
might
might
also
also
notice
notice
the
the
exclamation
exclamation
point
point
after
after
each
each
property.
property
That
that
just
just
means
means
the
the
API
api
will
will
always
always
promise
promise
to
to
return
return
that
that
data
data
type.
type
It
it
won't
won't
return
return
a
a
null
null
value.
value
So
so
a
a
user
user
can
can
have
have
an
an
array
array
of
of
tweets,
tweets
which
which
we've
we've
modeled
modeled
here,
here
But
but
a
a
tweet
tweet
can
can
only
only
have
have
one
one
user.
user
So
so
we'll
we'll
set
set
some
some
properties
properties
for
for
our
our
tweet
tweet
object,
object
but
but
this
this
time
time
we'll
we'll
type
type
the
the
user
user
to
to
the
the
user
user
schema
schema
that
that
we
we
just
just
defined
defined
in
in
the
the
previous
previous
step.
step
But
but
if
if
you
you
look
look
in
in
the
the
database,
database
you'll
you'll
notice
notice
that
that
our
our
actual
actual
user
user
data
data
doesn't
doesn't
have
have
any
any
tweets
tweets
objects
objects
nested
nested
on
on
it.
it
Tweets
tweets
are
are
their
their
own
own
isolated
isolated
collection
collection
that
that
are
are
completely
completely
decoupled
decoupled
from
from
users.
users
That's
that's
important
important
to
to
make
make
note
note
of
of
because
because
in
in
the
the
next
next
step,
step
we'll
we'll
use
use
resolvers
resolvers
to
to
combine
combine
all
all
this
this
stuff
stuff
together.
together
Now
now
the
the
last
last
thing
thing
we
we
need
need
in
in
our
our
schema
schema
is
is
the
the
query,
query
which
which
can
can
be
be
thought
thought
of
of
as
as
Like
like
the
the
main
main
entry
entry
point
point
into
into
your
your
API.
api
In
in
this
this
case,
case
we
we
can
can
enter
enter
the
the
API
api
through
through
tweets
tweets
or
or
we
we
can
can
enter
enter
it
it
through
through
the
the
user
user
with
with
their
their
user
user
ID.
id
At
at
this
this
point,
point
everything
everything
that's
that's
available
available
to
to
be
be
fetched
fetched
on
on
our
our
API
api
is
is
well
well
defined,
defined
but
but
we
we
still
still
need
need
a
a
method
method
to
to
actually
actually
retrieve
retrieve
this
this
data.
data
For
for
that,
that
we'll
we'll
define
define
an
an
object
object
called
called
resolvers
resolvers
where
where
each
each
property
property
in
in
this
this
object
object
matches
matches
one
one
of
of
our
our
interfaces.
interfaces
Data
data
that
that
already
already
exists
exists
on
on
the
the
Firestore
firestore
document
document
can
can
be
be
inferred
inferred
automatically.
automatically
But
but
remember,
remember
we
we
don't
don't
have
have
any
any
tweets
tweets
available
available
on
on
the
the
actual
actual
user
user
itself.
itself
So
so
we
we
need
need
to
to
write
write
a
a
method
method
that
that
can
can
resolve
resolve
that
that
data.
data
In
in
Firebase,
firebase
this
this
is
is
really
really
easy
easy
because
because
we
we
can
can
use
use
the
the
admin
admin
database
database
called
called
the
the
tweets
tweets
collection
collection
and
and
then
then
just
just
query
query
where
where
the
the
user
user
ID
id
equals
equals
the
the
user
user
ID
id
on
on
this
this
object.
object
Then
then
we
we
call
call
git
git
to
to
return
return
that
that
as
as
a
a
promise,
promise
and
and
that'll
that'll
be
be
a
a
snapshot.
snapshot
And
and
the
the
final
final
step
step
is
is
to
to
just
just
map
map
that
that
snapshot
snapshot
down
down
to
to
its
its
actual
actual
raw
raw
data
data
object.
object
If
if
this
this
code
code
fails
fails
at
at
runtime,
runtime
we
we
want
want
to
to
throw
throw
an
an
error
error
to
to
handle
handle
it
it
gracefully
gracefully
which
which
we
we
can
can
do
do
inside
inside
of
of
the
the
try
try
catch
catch
block
block
by
by
throwing
throwing
an
an
Apollo
apollo
error.
error
Tweets
tweets
will
will
follow
follow
a
a
very
very
similar
similar
process.
process
In
in
this
this
case,
case
we
we
just
just
need
need
to
to
return
return
a
a
single
single
Firestore
firestore
document
document
because
because
every
every
tweet
tweet
has
has
an
an
associated
associated
user
user
ID.
id
But
but
we
we
wanna
wanna
be
be
able
able
to
to
return
return
additional
additional
data
data
if
if
the
the
user
user
requests
requests
it
it
on
on
their
their
GraphQL
graphql
query.
query
The
the
last
last
resolver
resolver
that
that
we
we
need
need
is
is
the
the
query.
query
This
this
defines
defines
how
how
we
we
get
get
the
the
data
data
for
for
the
the
root
root
documents
documents
being
being
the
the
tweet
tweet
and
and
the
the
user.
user
Tweets
tweets
are
are
a
a
collection,
collection
so
so
we
we
can
can
simply
simply
return
return
those
those
as
as
a
a
Firestore
firestore
collection.
collection
So
so
what
what
we're
we're
looking
looking
at
at
here
here
is
is
just
just
Firebase
firebase
101.
101
We're
we're
pointing
pointing
to
to
a
a
collection
collection
and
and
then
then
retrieving
retrieving
it
it
as
as
an
an
array
array
of
of
documents.
documents
The
the
user
user
query
query
is
is
also
also
very
very
similar,
similar
but
but
the
the
main
main
difference
difference
is
is
we're
we're
passing
passing
an
an
argument
argument
to
to
the
the
method
method
being
being
the
the
user
user
ID.
id
We
we
can
can
Access
access
the
the
argument
argument
data
data
as
as
the
the
second
second
argument
argument
in
in
this
this
method.
method
So
so
now
now
we
we
can
can
retrieve
retrieve
our
our
user
user
based
based
on
on
the
the
user
user
ID
id
that's
that's
passed
passed
in
in
by
by
whoever
whoever
is
is
making
making
the
the
GraphQL
graphql
query.
query
It's
it's
very
very
possible
possible
that
that
they
they
will
will
pass
pass
in
in
an
an
ID
id
that
that
doesn't
doesn't
exist.
exist
So
so
we
we
want
want
to
to
handle
handle
that
that
with
with
a
a
validation
validation
error.
error
If
if
you
you
remember
remember
earlier,
earlier
we
we
used
used
exclamation
exclamation
points
points
to
to
only
only
return
return
valid
valid
types.
types
If
if
that
that
user
user
doesn't
doesn't
exist,
exist
we
we
need
need
to
to
return
return
a
a
validation
validation
error
error
instead.
instead
Okay.
okay
Just
just
a
a
couple
couple
of
of
lines
lines
of
of
code
code
left.
left
We
we
just
just
need
need
to
to
combine
combine
these
these
two
two
pieces
pieces
together
together
by
by
passing
passing
them
them
to
to
an
an
Apollo
apollo
Server
server
instance.
instance
The
the
Apollo
apollo
Server
server
feels
feels
just
just
like
like
an
an
Express
express
JS
js
server.
server
We
we
just
just
call
call
listen
listen
on
on
it
it
and
and
we're
we're
good
good
to
to
go.
go
All
all
you
you
need
need
to
to
do
do
at
at
this
this
point
point
is
is
compile
compile
your
your
TypeScript
typescript
code,
code
which
which
you
you
can
can
do
do
with
with
the
the
TSC
tsc
command
command
or
or
there's
there's
a
a
command
command
in
in
the
the
main
main
repo.
repo
When
when
you
you
run
run
the
the
script,
script
you
you
can
can
pull
pull
up
up
localhost
localhost
and
and
get
get
the
the
Playground
playground
to
to
start
start
sending
sending
queries
queries
to
to
your
your
API.
api
But
but
we're
we're
not
not
just
just
going
going
to
to
stop
stop
here.
here
There's
there's
this
this
really
really
cool
cool
thing
thing
called
called
Apollo
apollo
engine
engine
that
that
can
can
handle
handle
things
things
like
like
caching
caching
and
and
tracing
tracing
and
and
it
it
does
does
it
it
all
all
in
in
a
a
really
really
nice
nice
UI.
ui
You'll
you'll
first
first
need
need
to
to
register
register
for
for
an
an
Apollo
apollo
engine
engine
API
api
key,
key
then
then
all
all
you
you
need
need
to
to
do
do
is
is
add
add
it
it
to
to
your
your
Apollo
apollo
Server
server
config
config
and
and
you're
you're
good
good
to
to
go.
go
This
this
gives
gives
you
you
access
access
to
to
a
a
dashboard
dashboard
where
where
you
you
monitor
monitor
all
all
the
the
queries
queries
to
to
see
see
the
the
exact
exact
latency
latency
of
of
each
each
one
one
and
and
also
also
inspect
inspect
errors
errors
in
in
real
real
time.
time
And
and
let's
let's
also
also
go
go
ahead
ahead
and
and
deploy
deploy
our
our
app
app
to
to
a
a
production
production
server.
server
Assuming
assuming
you
you
have
have
the
the
Google
google
Cloud
cloud
command
command
line
line
tools
tools
installed,
installed
all
all
you
you
have
have
to
to
do
do
is
is
create
create
an
an
app
app
dot
dot
YAML
yaml
file
file
with
with
the
the
Node
node
JS
js
8
8
runtime
runtime
in
in
it.
it
Run
run
gcloudapp
gcloudapp
deploy
deploy
and
and
your
your
GraphQL
graphql
API
api
is
is
now
now
available
available
for
for
the
the
world
world
to
to
use.
use
I'm
i'm
gonna
gonna
go
go
ahead
ahead
and
and
wrap
wrap
things
things
up
up
there.
there
If
if
this
this
video
video
helped
helped
you,
you
please
please
like
like
and
and
subscribe.
subscribe
And
and
stay
stay
tuned
tuned
for
for
the
the
2nd
2nd
installment
installment
where
where
we
we
build
build
out
out
the
the
front
front
end
end
in
in
Angular
angular
with
with
the
the
Apollo
apollo
Angular
angular
Library.
library
And
and
if
if
you
you
want
want
to
to
take
take
things
things
to
to
the
the
next
next
level,
level
consider
consider
becoming
becoming
a
a
pro
pro
member
member
at
at
AngularFire
angularfire
base.com.
base.com
Thanks
thanks
for
for
watching,
watching
and
and
I'll
i'll
talk
talk
to
to
you
you
soon.
soon
success
The speakers discuss how GraphQL will replace RESTful APIs in 2018. GraphQL is a query language that solves the problem of the server and allows the client to define data. GraphQL can be used to access and return data from any back end data source and set up interfaces for data. The process of defining objects and data types in GraphQL is discussed, including resolving bugs and combining data types with resolvers. A script is provided and a deployment app is discussed.
GraphQL with Apollo Server 2.0
One of the big predictions people are making in 2018 is that GraphQL will make RESTful APIs obsolete. In today's episode, we'll learn how to build a GraphQL API from scratch using Apollo Server 2 point o and Node JS. If you're new here, make sure to like and subscribe. And I wanna send a huge thank you out to Arjun Yalamancelli. He's the mastermind behind the code in this video. And if you need a talented developer in Denver, he comes highly recommended. So let's kick things off by talking about GraphQL from a very high level. Imagine you have an Angular app that communicates with a bunch of different back end data sources. Traditionally, you would do this with either a REST API or a client side SDK. When you hit a REST one point, it's the server that determines the shape of the data that gets sent back to the client. What happens is that you'll hit a REST one point and it will respond with a bunch of data that you don't know anything about and that you don't need. GraphQL is a query language that solves this problem by sitting in between your back end and front end. It allows the server to define exactly what data is available, and it allows the client to only request the data that it actually needs to provide the user experience. What's really cool is that you can use it with any back end data source. In this video, we'll use Firestore and set up a Node. Js server with Apollo to deliver the API. This video is a 2 part In this first installment, we will set up the back end API. And in the second part, we will use Angular to consume this API from the front end. When you set up a GraphQL API, it provides this really nice playground that you can use to start sending requests and this just works out of the box. What we're going to do in the code is set up interfaces that describe the data that's available on the server. This is super powerful because the client can probe the back end in advance to find out What types are available and how they can be requested. This means you get amazing developer tooling even on a foreign API because you know exactly what's available and how it can be requested. You can see here I've requested all the interface names and the ones we're interested in are tweet and user. Let's say we want to request all of the tweets from our database, But we only want the ID and the number of alikes. All we need to do is type out the shape of our data on the left and then send it to the server on the right and it will respond with JSON in the exact shape that we requested. And this is live data you're looking at that lives in the Firestore database. But it can come from any data source or even multiple data sources at the same time. The tweets also have a text property. So if we want to include text in our request, we just add that to the interface and it returns the text from the database. This can be extremely useful if you have relational data that you need to join from multiple sources which is commonly the case with NoSQL databases. Let's imagine we want to query a user plus all of that user's tweets which live in a completely different collection in Firestore. You can pass arguments to GraphQL which in this will be the user ID, then we'll get autocomplete for all the properties available. So if we wanna just pull the screen name, we can do that easily. But tweets can also belong to a user and it's a property on the user interface. So we can apply it here and then request some data about the tweets that we wanna return back that will only belong to this user. So that's really only the tip of the iceberg with GraphQL. But the main takeaway is that it allows you to request data in exactly the way it should be consumed in the front end, which is a big difference from REST APIs. Now we're ready to write some code, but first, I have some really good news. Just a couple days ago, Node. Js became available on the App Engine standard runtime, which means you can use it for free and it's super easy to integrate into a Firebase project. I first wanna point out that you can find the full setup Actions on the GitHub repo for this video, but I do wanna point out a few of the more important parts. I'll be writing this in TypeScript, but the code is fully compatible with Vanilla JS if you prefer that. The first thing you wanna do is install Apollo Server 2 point o as well as GraphQL. Then to make things fully compatible with TypeScript, there's a few extra things Add it to the tsconfig, so make sure to grab the tsconfig from the repo. From here, we can install Firebase Admin and then we'll need to go to the Firebase console tool and download our service account. You can find it under settings and then go to service accounts and then download it into the root of the project as service account dot JSON. I've set up an index dot ts file. And in this file, I'm first going to import a few dependencies starting with firebase admin and then a reference to our service account, And then we'll initialize the app with that service account. That gives us full access to the data in Firestore. From here, we'll import Apollo Server and GraphQL. We'll also bring in Apollo error and validation so we can handle errors gracefully on the server. There are 2 main pieces to a GraphQL API. The first one is your GraphQL type definitions, which is where you write actual GraphQL code to define the shape of the data that's available on the server. The second half of this puzzle are your resolvers. This is where you tell GraphQL how to return the actual data to the client through the API. So first, let's start by defining our type definitions. You can define an object by calling type with the name of the object. And then there's a number of built in data types. For example, ID is just a string that is supposed to be unique. Then you have common data types that you would expect like string, integer, and things like that. When you put brackets around something, that means that it should return an array of that interface. You might also notice the exclamation point after each property. That just means the API will always promise to return that data type. It won't return a null value. So a user can have an array of tweets, which we've modeled here, But a tweet can only have one user. So we'll set some properties for our tweet object, but this time we'll type the user to the user schema that we just defined in the previous step. But if you look in the database, you'll notice that our actual user data doesn't have any tweets objects nested on it. Tweets are their own isolated collection that are completely decoupled from users. That's important to make note of because in the next step, we'll use resolvers to combine all this stuff together. Now the last thing we need in our schema is the query, which can be thought of as Like the main entry point into your API. In this case, we can enter the API through tweets or we can enter it through the user with their user ID. At this point, everything that's available to be fetched on our API is well defined, but we still need a method to actually retrieve this data. For that, we'll define an object called resolvers where each property in this object matches one of our interfaces. Data that already exists on the Firestore document can be inferred automatically. But remember, we don't have any tweets available on the actual user itself. So we need to write a method that can resolve that data. In Firebase, this is really easy because we can use the admin database called the tweets collection and then just query where the user ID equals the user ID on this object. Then we call git to return that as a promise, and that'll be a snapshot. And the final step is to just map that snapshot down to its actual raw data object. If this code fails at runtime, we want to throw an error to handle it gracefully which we can do inside of the try catch block by throwing an Apollo error. Tweets will follow a very similar process. In this case, we just need to return a single Firestore document because every tweet has an associated user ID. But we wanna be able to return additional data if the user requests it on their GraphQL query. The last resolver that we need is the query. This defines how we get the data for the root documents being the tweet and the user. Tweets are a collection, so we can simply return those as a Firestore collection. So what we're looking at here is just Firebase 101. We're pointing to a collection and then retrieving it as an array of documents. The user query is also very similar, but the main difference is we're passing an argument to the method being the user ID. We can Access the argument data as the second argument in this method. So now we can retrieve our user based on the user ID that's passed in by whoever is making the GraphQL query. It's very possible that they will pass in an ID that doesn't exist. So we want to handle that with a validation error. If you remember earlier, we used exclamation points to only return valid types. If that user doesn't exist, we need to return a validation error instead. Okay. Just a couple of lines of code left. We just need to combine these two pieces together by passing them to an Apollo Server instance. The Apollo Server feels just like an Express JS server. We just call listen on it and we're good to go. All you need to do at this point is compile your TypeScript code, which you can do with the TSC command or there's a command in the main repo. When you run the script, you can pull up localhost and get the Playground to start sending queries to your API. But we're not just going to stop here. There's this really cool thing called Apollo engine that can handle things like caching and tracing and it does it all in a really nice UI. You'll first need to register for an Apollo engine API key, then all you need to do is add it to your Apollo Server config and you're good to go. This gives you access to a dashboard where you monitor all the queries to see the exact latency of each one and also inspect errors in real time. And let's also go ahead and deploy our app to a production server. Assuming you have the Google Cloud command line tools installed, all you have to do is create an app dot YAML file with the Node JS 8 runtime in it. Run gcloudapp deploy and your GraphQL API is now available for the world to use. I'm gonna go ahead and wrap things up there. If this video helped you, please like and subscribe. And stay tuned for the 2nd installment where we build out the front end in Angular with the Apollo Angular Library. And if you want to take things to the next level, consider becoming a pro member at AngularFire base.com. Thanks for watching, and I'll talk to you soon.
The speakers discuss how GraphQL will replace RESTful APIs in 2018. GraphQL is a query language that solves the problem of the server and allows the client to define data. GraphQL can be used to access and return data from any back end data source and set up interfaces for data. The process of defining objects and data types in GraphQL is discussed, including resolving bugs and combining data types with resolvers. A script is provided and a deployment app is discussed.