End-To-End Type Safety with React, GraphQL & Prisma

Bookmark

In this workshop, you will get a first-hand look at what end-to-end type safety is and why it is important. To accomplish this, you’ll be building a GraphQL API using modern, relevant tools which will be consumed by a React client.


Prerequisites: 

- Node.js installed on your machine (12.2.X / 14.X)

- It is recommended (but not required) to use VS Code for the practical tasks

- An IDE installed (VSCode recommended)

- (Good to have)*A basic understanding of Node.js, React, and TypeScript



Transcription


Thank you guys for joining me here. I see that there's a couple participants and people are still filtering in so that's super cool to see I'm glad you could all join me this morning or it's morning here. I'm in California, but I know this is a remote Global conference. So you never know where people are from so good morning. Good afternoon. Good night to everybody. I hope you're ready to jump into some coding. We're gonna be looking at a full stack application and we're gonna be building basically an application that has full end-to-end type safety and we're gonna do it from the ground up and just sort of talk about all the different pieces that you need to worry about and that you need to think about when you're implementing and type safety and we're gonna look at how a couple of these tools make it pretty easy for us to do and make it actually quite a joy to do once you set up an application like this. If you're anything like me you're going to you're gonna end up nerding out about it afterwards and just have a whole lot of fun setting all of this stuff up. I see there's a question already. What's the link to the Discord server? The one I'm emailed doesn't work. Let me see if I can get you a link there as more people are filtering in. Let's see. like people There is the link there I've posted it. So if anyone else needs the Discord link, I have posted it in the answered questions, so it should be there. But okay moving on a little bit more on the agenda for today. I'm gonna post a link in the chat and this is just gonna be a link to a notion document and what this is going to be is sort of the source of Truth for this whole Workshop that we've got going here. And this is going to be where we have all the information about what we're going to be doing and I've actually split up this Workshop into different lessons. So we'll take them one at a time. We'll start off with this databases section and we'll slowly move on to the bottom. But just some information about this about the workshop. Here's the resources up here. This is the link just to this notion doc that I just posted. If you have any issues opening that link, please let me know in the chat or in the questions and I can help you out with that. And this is going to be the GitHub repository that we're going to be working with so we can if you pop that open just be able to get that ready once we get going. You can't see my screen. That's probably an issue see. How is that is that better? I actually chats disabled for some people. see Here's the link to that notion document in the public Channel. Cool, great. I see that people are chatting on the Discord about the screen. So that's that's perfect. You can all see me now. Yeah, some I'll send the link there. We could just default to the to the Discord chat if that other chat isn't working. There you go. So it looks like people are thumbs upping that so the links working. So I'll just continue to talk through this first page as people get that open and get going. So there are some prerequisites to to this the prerequisites are just that you need to have no JS installed on your machine. Everything that we're going to be doing is going to use node. So we'll just want to make sure we have that installed and I'll give you time to install that if you don't have it already as we move forward and then it is recommended that you use vs code for this. There are a couple plugins that just make life a little bit easier with working with Prisma specifically so vs. Code is sort of my suggested IDE. But if you have another one that you like to use that you prefer feel free to go ahead and use that. And then just the basic understanding of node.js react in typescript is good to have it's not necessary because I will be walking you through everything but it would be good to know at least a little bit and have some experience with no JS react and typescript. And then moving on through this what'll you do section? If you want to read through this in more detail, feel free to take a minute just to read it. But essentially this just goes over sort of the agenda we have for today. This goes over all the different pieces of the workshop that we're gonna do so it's sort of breaks it down into little descriptions. So for example, we're going to be starting off by building out our sqlite database and then we're going to be setting up graphql yoga, which is a graphql server and then building out that server and then finally building up the client and connecting all of those different pieces. I see more hands being raised. So let me see what's going on here. So I see a question. Will there be a repo after yes, there will be a repo. And then it looks like chats disabled for people. Yeah, so we'll just default to the Discord chat. Where's the link? Exactly? Okay. So for everybody looking for the link, I'm gonna go into the chat again, or actually, I think the let's see. I'll get everybody in the Discord chat. I've posted a link to the Discord in our chat join that and then go to the rav workshops Channel. And then if you go into the channel for this Workshop, you should see the link to the notion. And I'll give just a couple minutes for people to to get into there. Cool, so I click the link. It looks like it's working there. So that's good. Cool. Okay, so then down here to the actual timeline agenda. So we are just going to be kicking this off like we're doing right now and then we're going to be setting up Prisma. We're gonna set up the graphql server. After that. We're gonna actually build out the graphql resolvers and all the different pieces there and then we're going to build the react client and Bridge the type gap between the back end and the front end. And then I am going to be splitting up these lessons into two different parts. There's going to be the first part where I'm just going to walk you through everything here. So I'll be walking you through the different lessons. I'll walk through each little step that we're going to do and I'll try to explain the process as we go and for this part I encourage you not to code along with me. I encourage you to just sort of listen and sort of taking the information. I'm giving you because I will have some little tips and tricks in there as I go and then afterwards I'll provide you about 20 minutes after each little lesson to work through all the pieces on your own and then get some feedback from me via the chat if you have any questions, so that that's gonna be the time where I encourage you to do your coding then that way you get the information and you get some time to code afterwards. It's sort of a win-win situation. And then before I get started, I just a little bit about me. My name is Steven Adams. I'm a developer Advocate at Prisma and I've spent the last roughly eight years working as a full stack developer, and I've just recently sort of jumped into developer advocacy, and it's been awesome because I get to do cool workshops like this and get to hang out with people like you every day and just teach you how to code and do different random coding things and it's been great. I'm loving it, and I'm super excited to be giving this Workshop. I have all of my contact information here. So if you want to message me about anything after this conference or just after after maybe an individual section and you need to reach out to me, feel free to reach out to me in any of these formats here and I will try to respond as soon as possible. And then lastly if you want to host this Workshop yourself this document. I've provided the link that way everyone can to sort of have access to it. This is something that I'll just be keeping up and if you ever want to just steal this and give this Workshop maybe at a local Meetup or if you are just interested in maybe getting into some speaking and you want to use what you learned today to sort of teach your friends. Feel free to steal this workshop for me. I I definitely believe that all of these resources should be open and available for everybody. So this isn't mine explicitly. This is for everybody to use if you would like, so please feel free to do so. So with that all out of the way, I think we'll go ahead and jump into the first lesson. But before we do, I'm just going to double check some chats and make sure everything is looking good here. So I see a question from Ben about joining the Discord in case you haven't already I posted a link in the live chat. So that should be good a link to the repository that's going to be in the notion document and that's all the way up at the top in the resources section and the link to the notion document is in Discord. So I'll actually go in there and pin it. I see Alex added a good link that looks like it's working for people. So yeah, go ahead and get it there. Some of you can't join Discord. Let's see. I will post the good link to this chat. and go ahead and try to access that one. So that should be in the chat now Ben. And while you're doing that I'll go ahead and just start talking through the very first lesson. So jumping in here the way this is gonna work is we're just gonna go over the different goals. We're gonna go over the setup for this project and then we're gonna go through each of the tasks. And once I get through all of these tasks, I will give you some time to do this on your own. So coming over here. I'm Gonna Bump the size up for you guys a little bit. And right up at the top. So the goal of this first lesson is just to set up your database. We're gonna be modeling out our schema. We're going to be seating our database which will be a sqlite database and we're setting it up using prismas. So that way we can actually manage our database schema and our applications database client all through one tool and that is Prisma. So by the end of this what you're going to have is a back-end we're going to start off our backend servers project. We're going to know the shape of our database and how to interact with it in the type safe manner because Prisma will give you a nice type safe client to do all this with so the very first thing we're going to do is we're going to clone the starter project from GitHub. So there's gonna be a link here for you guys. Once we get to that point, I will copy that over. And I'll pop open to terminal. And in this terminal I'm just going to be on my desktop and I will run get clone and I'll paste this here. So this is just going to clone down the repository. This has some initial setup for us and it should just have a couple of different things now go through what it's got in the beginning. So within here you're going to see a couple of different folders you're going to see a client folder And this is going to have our react application. This is just sort of the the start of it. We're going to add to this later. But this is just a starting point that I have put together for you guys. And then the same thing with the server. All we have right now is a package Json a couple of with a couple of packages already installed to get typescript going and the typescript config and that's about it for now. We're going to be adding everything else on our own. Let me move this chat over so that I can move some things. cool All right. So back in the notion document. So we've got this and so we've cloned it and then we can follow the instructions on the readme just to get all the packages installed and whatnot. So I'll go through that in just a second but important we need to make sure that we have part one checked out. This is a branch that I put together and every different lesson in this Workshop is going to have a branch associated with it as a starting point. So for example, we're in the first lesson. So we're gonna check out part one that will give us the starting point if you get stuck in any of these lessons, so for example, if you get stuck in part one and you have a problem with it, then you can just check out the part 2 Branch if I move on and maybe you haven't finished the previous section and it'll get you to the starting point that you need to be at to start that next section. If you have any questions about that or any concerns, feel free to shoot a message if you do get stuck and you don't remember how to get there, but that's generally how you're going to do it. You can check out the park branches for the specific sections. And for this specific for the specific section of the workshop, we will be working in server directory for the entirety of the lesson. So we're just going to be working on the server code. So let's go ahead and go here to the readme and I'll pop this open as a preview so that we can see it a little bit better. So we've cloned repository now. We just need to install dependencies in both of the projects and then we can start the servers. I won't actually start the servers right now because there's no need for it, but I will go into the server and I will npm install. So that just installs all the dependencies that we already have to use typescript. And those will be found here. And then we can move on to the first task. So these set of tasks are going to Define what we do in the section. So the very first thing that we're going to do is install Prisma as a development dependency, we're going to use Prisma to scaffold out the database as I mentioned before and we need to have the CLI tool installed to actually initialize Prisma in our project and you're gonna see these solution dropdowns. These are the solutions for each task. If you do get stuck on a task. The solutions are here in case you need that little extra help to get to the next task. I encourage you to try to get through these without looking at the solutions first, but if you do get stuck those are there for you to to lean on a bit so I'm gonna go into my server code again. I'm in the server directory and I'm going to do npmi-d Prisma and this will install Prisma as a development dependency for you. And then we're going to do npx Charisma emit. And then we can use this data source provider flag to tell it that we want a sqlite database. And there we go. So we're going to see that. Our Prisma was initialized. We're going to see that Prisma schema was created for us. It's going to have a little starter schema and then it gives us some next steps, which we don't really need to follow here for for this piece. I'm going to move this over to the right. So it's a little readable. But let's go look at what he gave us. So we're gonna see that we now have this Prisma folder. And it has the schema.chrisma file in it. And this file is just going to have a generator defined for us. And this is what's going to Define how to generate Prisma client, which is how we're going to access our database. Once we run Prisma generate. It's going to use our database model to generate that client for us. We also have our database our actually our data source block here. And this is how we Define how to connect to our database and what kind of database we're connecting to so we can see here that we are connecting to a sqlite database and it's going to look in an environment variable called database URL to find our connection string and Prisma notice that we didn't have a DOT EnV file already. So it created one and it went ahead and created a default database file for us. And that's what we're going to use. This is a database file that sqlite uses to store its data. So going back to the to the steps here. It looks like we've got that first step done. And if you do want any more help with the init commands or just any commands in general. I do have docs leak throughout this document. So feel free to look at those. So that's the first task we've done that and now we can move on to creating our user models. So our database is gonna have a user table and this user table is going to have a couple of different things. We want it to have an ID and a name. And so the way we Define that in our Christmas schema as we have to set up a model block, so I'll go ahead and pop open the schema.prisonment here. And we're going to create a new model. It's going to be called user. And what we want this to have is the ID like we said, so I'll do an integer for the ID and we're going to say that this is the primary key of our model. So I use this at ID and then we want to give this a default value of Auto increment that way every time a new record is created. It will just increment one onto that. So the first record we'll have an idea of one the next one. I'll have two and so on and so forth. And then the next piece that we needed was a name, I believe so a name. So we're gonna add a name field here. And we'll make that name a stream so. Now we've got a user model that has an ID and a name and currently we don't actually have a generated database client to actually work with this data or store it in our database. And actually this model isn't even in our database yet. We've simply defined it in our prism schema and we can go from there. But before we do that, what we need next is to actually create the note model. So what we're going to have is a user and a note in our database and the way this is going to work by the end of this is that a user will have many notes associated with it and they can go ahead and create a note on their on the react client that we add. So let's go ahead and add a note model as well and that note model is going to need to have all of these fields. So I'm going to go back into here. I'll create a model called note. And then I'll copy over this ID because it's going to be the exact same ID for this. And then we're going to need a message field. So I'll create message. So your string. And then create it at and updated that so when a record is created we want to take a timestamp of when the record was created and then whenever the record gets updated. We also want an updated timestamp. So let's go ahead and do the created at So be a date time field. And we're gonna set a default value to the function now. So this is just going to say by default when a record is created stick a current timestamp into it. And then similarly we'll do updated at this will be a date time as well. And we have an attribute in Prisma called updated app that will keep this updated to a current timestamp anytime. The record is updated or changed. So that's helpful there. We've got that ready to go. And then finally we need to have a user ID. And what this user ID is going to do is this is going to be the foreign key that points to a user so that we know which user there's no actually belongs to so we're going to say that this is a user ID and it's an integer. Cool, so that that finishes up our note model for now. The last thing that we really need to do is create a one-to-many relationship between the user and the note that way we can have a user that has many notes associated with it. So in order to do that, we need to actually use the relation attribute and set up the relations in our schema. So let's go ahead and do that here and I'll just take a quick second to look at the chat and looks like there is no current question. So I will move on cool. So for the note, let's go ahead and set the relationship up on the Note side. So the relationship is going to be related to a user. So I'm going to add a field called user. And then this user field will be of the type user which we defined up here in our model. And then we can use the relation attribute to actually set up this relationship. And this is going to take two different two different values. It's going to take fields which will be an array and this is going to be user ID. This is specifying which fields on the current model are going to point to the relation model. And then next we need to do references. So this is going to be what column on the relationship model our foreign key references. So we want to reference the ID. And then this is going to say that there's an issue because our relation hasn't been defined on the opposite side within Prisma. You do need to Define relationships on both sides. So within both models that way that way But when you're using Prisma client, you know how to get from a user to a note and you know how to get from a note to a user. So in order to do that. We simply need to do notes. So I'm creating a field called notes and it's going to be note and it's an array. So that sets up our relationship. We now have a user that has many notes and each note has a single user and knows how to get to its user. I'm looking over at the chat see npx Prisma and knit data source provider sqlite. Okay. So Alex, I see your question there. And the problem is that before data source provider you need to dashes so actually post the the fixed. fixed snippet here There you go. So that should do it for you but moving on so we've got that relationship set up now. And I'll pop open our tasks again. Now that we have this done. We need to actually create a migration. So this is currently only in our database schema. This isn't actually in our database. It's in our Prisma schema. Sorry, so we need to actually apply this to our database using a migration. So to do that we can actually use the migrate Dev command and this commands can create a new migration file and then apply it to your database and this migrate Dev command specifically the command that you're going to use while you're on development because it will just simply apply the whole migration to your database. So I'm going to go ahead and go back to our terminal. I pop this terminal open. And I can type in MPX. Prisma migrate debt, and then we want to give this migration a name so - - name and then I'll just call it init. This is our initial migration. Oh, this is here is that I'm not in the server folder. So CD server, and then I'll run that migration. Cool. So this went to our Prisma schema it loaded it up. It created a set of migrations for us and then it actually applied it to our database. If you want to actually look at the migration that got created you can go into migrations. You could pop open the SQL file. And this is what actually got generated and applied to our to our database. So now that we've got that done, we now have a database with our scheme of applied to it. Now. It's simply needs some data. So in order to actually get some data into it, we're going to see the database and to do so, we need to add a new file called seed.ts and this file is just going to contain this code that provided here to throw in some data for us. So I'll copy this over. if I can get the copy to work see there we go. Copy cool and then head over into our code again. And then within this Prisma folder I'm gonna create a file called feed.ts This is just gonna be the file that we run to add all of our data in you don't need to know too much about what this is actually doing. Although it is pretty fall easy to follow. This is just deleting all the records out of our database and then adding new data in and to actually run this we're going to go into our package Json and we're going to add a key in here called Prisma. And this will be an object. That has a value in it called seed. And what this is going to do is it's going to run TS node. Def Prisma seed that PS and the reason I set it up this way is because we can now go into our terminal and I'm going to move this to the bottom. And we can run npx Charisma BBC and that'll actually run this command. So it's gonna go into here and it's going to run this seed command. So if we run this Let's see here. You see any project need to add Prism without C? I thought I did that. Oh again, I'm not in the server directory. There we go. So now it's running that seed command. We can see here that it actually ran our seed.ts file and that our data has been seeded and that the command was executed. So at this point we have a database now that's fully seated with data and ready to work with and so at this point this is where I'm going to turn it over to you guys. So I've walked through all these steps and sort of walked through how these are working at this point. I'm gonna let you have a couple of minutes to work through this on your own. So go to this lesson one page and then just follow through all the tasks. And what I'm going to actually do is I'm going to turn off my audio for a bit and I'll just be quiet and I'll let you work through this and if you have any questions at all, please post them in the Q&A or post them on Discord. I'll be monitoring both and I will answer them as soon as I can and I'm gonna give you about 20 minutes to do this and then I will be back for for you guys to follow along. So at this point, I'll turn it over to you guys. All right, so that's that's time on that. So I hope you guys all had fun walk working through that first piece. And if you did have any problems with it, don't worry. I'll be walking through how to get caught up in just a second. So let's go ahead and look at this second section. So if you go back to the home page, we're gonna be on this back-end set up a graphql server section. And goal of this lesson is to just set up our graphql server. This is what's going to expose our data that we set up in our database. That way we can actually query it from our react application graphql is a strongly typed language that's going to allow the front end to make requests for exactly the data that it needs in a way that's type safe and self-documented using the graphql schema that we generate. So in order to set up this if you did miss the first section, this is going to be our GitHub repository here. This is the link and we're going to be working in the server directory. And if you are just now starting you could check out the part two Branch. This is the starting point for this section. Otherwise, just keep working on the project that you started in the previous one. So basically what we're doing in this piece here is we're gonna set up Prisma in our application. We're gonna set up some of the initial tools to set up the to set up the type safety that we're going to use in this application. And one of those tools is going to be called Pathos and we're gonna use that to actually build out our graphql schema and set up our graphql server with graphql yoga. So let's go ahead and get started on that. The first step that I have here is Task one. What we need to do is actually set up an instance of our prism of client that is built in a way that's reusable and shareable throughout the application. So I'm gonna pop open the code base here. I'll get rid of this. And within our server directory, I'm just going to create a new file and I'm going to call it db.ts. This is where we're gonna hold our prisoner client. We're going to instantiate it and we're going to export it from here. So I'll import Charisma client. And this is going to be from at Christmas slash client. This is where prism of client gets generated when you actually run a migration what the migration did was it applied our database schema to our database but as a side effect it also generated Prisma for us without us having to run the command. So what that does is it takes our Christmas schema and it generates this client here, which is called Prisma client JS, and that's what we're going to use to query our database. So I've imported Prisma client next step is going to be to actually instantiate it so I'm going to say export const Prisma equals new Prisma client. I'm exporting it because we do want to export this and use it in different places in our application. And then after that just as a little helper, I'm also going to export the prism client type because we will need it a little bit further down the line. So I'll export just Prisma client. There we go. So that should be all we needed to be for that first task. We just instantiated and exported prisoner client that way it's its own module. And if you actually look at the solution here, it should be similar to what we have. And now getting into more of the meat and bones of our graphql server in this next task. We're going to set up pathos which is a generator that we're going to use with Prisma schema. There's a nice plugin and if you aren't familiar with pothos and actually I think even before explaining pothos I would like to go into what a graphql schema is and sort of how they can be generated. So generally there's two different ways that you can build your graphql schema. You can either actually write it yourself. You can manually write the graphql schema language and build out your different types and different queries and mutations and all of that and then apply that to your graphql server. And the graphql server will parse that and set up the different types and stuff in the playground for you. But there's another way called code first graphql schemas, which is where you actually use a generator Library similar to Pathos and what this is going to do is we're going to be able to actually build our graphql schema via our code. So it has a set of helper functions that help us sort of build our graphql schema up in the code and what the generated asset of that is is an actual graphql schema that we can then apply to our graphql server. Now if that doesn't make sense that's totally fine. We're gonna be walking through all the steps and I'll be explaining it as we go but just know that we're going to take this code first approach using pathos where we're actually going to build our schema via the code and we're going to use a nice plugin with pop those called pathos Prisma that actually builds it adds some type safety into how we actually build our graphql resolvers and types based on our prisoner schema. So we get that nice safety even within our back end server. So let's get this started. I'm going to take this command here and I'm just going to copy it so I don't mess up on the typing what this is going to do is it's going to install Pathos in our application and it's going to install the Prisma plugin, which we will be using so I'm going to go into here pop open a terminal and I will CD into the server part and paste this so I'm just installing those packages there. And what this is going to do specifically with the plugin Prisma package is this is going to give us access to another custom generator that we can use in our prismas schema that actually generates some types that will be used in the pathos setup to actually build out these graphql types and mutations and queries and whatnot. So in order to actually make use of that, let's go over to our Prisma schema. And we can go into our generator blocks and I'm going to add a new generator. And I'm just gonna call this pathos. And this generator is simply going to have a provider. And the provider is going to be called Prisma Athos. types So this prismopathos types, this is what we just installed with that pothos plugin. This is the generator that's going to get used and essentially what that means is when we parse this this prism of schema when we run Prisma generate it's going to take that parsed like syntax AST from this and it's going to apply it to whatever function this provides and builds types based off of that. So what we need to do now that we actually have that generator provided here is we need to go into our Project and we need to run MPX Prisma generate again. That way it'll regenerate our Prisma client and it's going to regenerate or it's going to for the first time generate these pathos types. So I'll do this. And we could see now that we have two success messages here instead of one like we had last time we have generated Prisma client. So our client was regenerated correctly and it's also generated our pathos integration for us. And so these are like, I've been saying it's just a set of types that pop those is going to use to actually give us type safety when building our graphql schema. And so going back over to the tasks that finishes up this task for us and now we can go in and actually configure the schema Builder that pop those gives us the schema Builder class is what gives us the set of functions that actually gets used to build our graphql schema. So let's create a new file. I'm gonna go in here into the server and I'm going to create a file called Builder dot. Yes. And within this file we're going to need to do a couple of things. We're going to need to import schema Builder. We're gonna need to import the Prisma plugin. And we're going to need to import all the generated types and our prizma client. So let's go ahead and do that. I'll import. schema Builder from pathos course and then we also need the prizma plugin. from pathos plugin Prisma and then our types so import by where's my types? from papos plugin Prisma generated And if you're wondering how I remember where all of these paths are, I don't I have some notes over here that I'm looking at and I've also provided some links in this document. So if you need to know where all these generated types get put at the very bottom what you can see down here is a link to this the plug-in doc so you can actually know where all of these things are. So don't worry too much about memorizing those I definitely don't have good memorized either but we did we missed once so I'll import the prismic quiet that we have so I will import Prisma and we can go ahead and import prize my client as well. the type from this is going to be from BB. There we go. So those are all the Imports that we're going to need for now to actually build out our schema Builder and what we need to do next is actually create an instance of that schema Builder. So let's go ahead and do that. We're gonna export this because we are going to use it elsewhere in our application. It's just gonna be called Builder and it's going to be a new. schema Builder and this schema builder takes in a generic which is going to allow us to provide some Hypes and safety in there. And what we're going to provide there right now is these prismat types because we are using this Prisma pop those plugin. We need to provide the Prisma types to the schema Builder. So that is actually aware of what types we're going to be using and what our model looks like. So We're gonna do Prisma types here. And this is just going to be Prisma types. There we go. So we've applied those and now it's going to be aware of what we're actually using for our business. And then within the actual functions object, this is the first parameter of the schema Builder Constructor. It's just going to take in an object with a set of configuration and the very first one is plugins. This is just where we're going to Define which plugins we're using so we are using this Charisma plugin we imported And the next is gonna be our actual Prisma instance. So now that we have this plugin Prisma we see that we get this red squiggly lines and it's letting us know that we need this Prisma property pop those as smart enough to know that if we are using the Prisma plug-in we might want Prisma instantiated in here. So let's go ahead and provide that we have to give it a client and we're gonna give it our Charisma client. So that's our Builder. We've set it up with all the different types we need and we're gonna see a little bit later down the line why it was important to actually provide all of these different types once we're building out a resolver, but for now just know that that provides pathos with the set of types that we need to actually build our resolvers in a type Safe Way. And I think for now that actually finishes up the task three here. All we needed to do was build out this schema Builder. And the next thing we need to do is actually configure a little bit further if you remember in our Prisma schema, and I'll actually go over to it now just to show you we have these date times. We have created that and updated at within our notes. These are date fields and graphql by default does not actually support the date fields. It supports a certain set of scalars which include integer strings booleans and things like that, but it doesn't by default have a date type. So we're gonna need to add a custom type into our project. And apply it to our graphql schema Builder. That way we can handle these dates and to do that. We're going to need to First install a package and this is called graphql scalars. This is a this is a community tool that has been just upked by the community and has a set of different types that maybe graphql default or it doesn't support by default. So let's go ahead and install that it's going to be called graphqlers. And it looks like that installed properly so that's good there. And then now within our Builder dot. Yes, I'll pop open the notion page again just to show where we're at. We need to add this date scalar type. And it's going to implement the date resolver scaler that gets given to us by graphql scalers. So we're gonna need to import that first of all, so if we get this date resolve around copy this over import, They resolver. from graphql scalars Go. cool And then we're going to need to do is we're going to need to actually apply that to our to our Builder. So the way we can do that is we can go back into the generics here. We can go scalars. This is how we're going to add our scalar values and then we're going to add a date scalar and I'm gonna type this out real quick and then I'll explain what this actually means. So we're gonna have an input and an output and so what this is going to be is this is gonna be how we're going to actually Define this date scaler in our resolvers and in our query responses actually, so the inputs and outputs are just defining how to handle this date time field in those different situations in our schema. The next thing that we need to do is we need to actually register the scalar type within the Builder itself. So this just set up the types for it, but we need to actually handle the resolver how to actually resolve this so we'll do the Builder Dot adscaler. And we're just going to call this a date. And this is going to use the date resolver. And then there is a configuration object at the end, but we're just going to leave that empty for now. So that's all the setup that you need to actually set up this date resolver. You just set up the scalar type for it and then actually apply the resolver to the to the server. And so at this point now we have it all set up and configured with the proper types that we're going to need to run our to run our queries and we need to actually build a root query so we can get our server going. So in Builder TS, we're just going to add a root query that's called hello and it's going to return the street world just that we can actually get something working for now so that we can pop open the playground and see what see what's going on in there. So I'm going to just paste this little snippet here. Feel free to copy this over. This is in the this is in the notion document. But what this is doing is it's just adding a query so it's adding the query type to our graphql schema and it's creating a a hello query and all it does is resolves to the word stream. And so with that we can move on to task 6, we need to create a module that actually exports a generated schema. So right now we're just defining how to generate the schema and we need to actually run the generate function generate the schema and return that and to do that. We're going to create a new file once again, and this one's going to be called schema.ts. So in our server creating file called schema.ts. And we're going to import the Builder here so import. Builder from Builder and this one's gonna be really easy. We're just going to do export const schema equals Builder. Dot to schema. So this is just taking our graphql schema configuration. It's actually running the two schema function which is going to generate the graphql schema abstract syntax tree, which is what gets used by our graphql server to actually spin up the server and Define how you can interact with the server and then we're exporting that so that we can use it elsewhere. So that's all we needed to do there. Next. We need to actually set up our graphql server up until now. We've just been configuring the schema, but we don't actually have the server running. So we're going to use graphql yoga to do that. This is just a popular graphical server that you can run and get set up very easily. So I'm copying over this install command to install graphql yoga. And I'll install that there. And then we need an index file. This is going to be the root of our application. So let's create index.ps. And we're going to import a function from graphql yoga that's actually going to spin up our server and this is called create server. so import create server. from a graphs there we go from graphql yoga slash node, because we are using the node implementation. And then we also need to import our schema that gets generated from schema. And then we need to actually use the create server function. So let's do const server equals create server. So what we're doing here is we're creating a new server and we are storing it within a server variable and this takes a bunch of different options that you can scroll through here. But the one that we care about is the schema because we need to actually provide a schema to this application. So we're giving it our schema. This is just short hand for writing something like this. And then lastly we need to actually start the server so we can do server dot start. And so at this point we have defined our graphql schema, or at least the very start of it with the simple. Hello world query. We are generating our graphql schema here. And now we're importing it into our index file and actually applying it to our graphql yoga server. So with that I think we are just about ready to actually run the server and looks like we are so if you head over to a terminal you can run npm run Dev. And let's see what this package missing is. cannot find modules Source index TS from okay package, Json. this might be the piece that oh, is it not in the source folder? Let me see. Oh, you're very right. Yes. I apologize everybody for this mistake here all of these files that we've been creating. All these TS files should have been in a source folder. Thanks for putting that Jason. Let's move. everything over I think I had skipped that over in the document. But yes, you should all be in a source folder just to keep things nice and organized. And now I can run it here Monday, hopefully. now it says string. Oh, I think this was something to do with one of these packages. I'm going to delete that. Just bear with me here. This was an issue that I had found before the before this workshop and we're seeing this coming up. So I'm going to do and install. Cool, so that looks good. Now I just need to update some of these. some of these here unable to find module dot dot slash and Builder. Cool. So thanks for bearing me with me there. There was some packages in this specific branch that were messed up and I just had to reinstall them. So now we've got our graphql server running at localhost 4000 and we can pop that open. I'll just do control click to open this. And what we're going to see is the graphql playground. This is given to us by default by graphql yoga, and it comes with a bunch of cool different features. We have some docs on what's actually available within our graphql schema so we can see our hello query here and then we have an Explorer where we can actually look at all of our queries and mutations. So I'm just going to run this. Hello query. And we see that we get data back and it's the world response and that's exactly what we defined in our resolver. So that looks good there. Um, and if we go back to our to our section here, it looks like that's the last step in this section. This is the last task here. So at this point I'm going to once again turn it over to you guys. I'm going to give you about 20 minutes to go through this section on your own. If you finish early feel free to just play around in the graphql playground and explore what's available there. I will be posting a message in the Discord chat prompting you guys for thumbs up when you guys are finished that way I kind of engage how many people have worked through the whole solution and see if we can maybe get started a little bit earlier. But so for now I'll just turn my camera and off and my microphone and give you guys 20 minutes. All right, guys, I am back and I think we're ready to move on to section three. Thank you for all the help in the chat fixing all these issues with the mpm Run Dev and the package versions. You never know when a package is gonna update and it's gonna take your stuff and that happened here. So yeah. Thanks for all the help there and hopefully everyone's getting that resolved. If not, feel free to check out part three and you could follow along as we go So part three is where we're going to actually use pothos which we just set up to build our graphql schema. So we're going to actually use it to build out our types and models and queries and apply it to our graphql schema and we'll have a fully functioning graphql server that we can then use from our react client after this section. We are going to be focusing completely on the react client because the server will be complete. So the goal of this like I just said is to set up server that exposes our data in a data set that we set up in the previous lesson. And so as for task one we can build this note type. So we have our note defined in our Christmas schema. So that defines how it's going to look in our database but we now need to Define how we want a note to look through our graphql API. Those are very different things. You may not want to expose everything from your database via your graphql API. So that's why you have to do it separately here and to do that. We're going to use our Builder instance and we're going to define a type and we're going to actually organize this in a way that would be sort of maintainable if the application ever grew which it won't but it's good to follow this practices whenever you can. So the very first thing that I'm going to do is I'm going to go into our source folder here. And create a new folder called models. This is where we're gonna write any of our graphql schema types and models and the very first one that we're going to do is gonna be called an alarm going up. Cool. The very first one we're going to do is going to be called note dot PS. So this is just going to Define our note model and this model. Is going to Define how our graphql schema sort of exposes and defines this data. So in order to actually build up our note though, we need to import our Builder instance. So very top important Builder. And this is gonna be from dot slash Builder. So we have our Builder instance and this comes with a set of functions that we can use to actually build out our graphql schema. So the very first thing we're going to do here is do Builder Dot and we get this setup functions. But because we are using the Prisma plugin we get this Prisma object function. So this is the one we're going to use for creating a object based off of one of our prism models and we get some nice type safety here and this is all because of that Prisma plugin that we set up hot those now knows that within our Christmas schema. We only have a note model and a user model so we can just select this note model here. And then we provide this a configuration object and this is going to be how we Define the fields that we want to expose through our API and how to handle some of these searching functionality and the very first thing that we're going to need to add here is find unique. and what this does this is just sort of a convention that we're going to be doing in pothos and it sort of defines how if we have to do like a nested read in In graphql you run into like the N plus one problem where you might have a bunch of nested queries that all end up building one huge giant query that thinks your database. This is something that helps with that performance. It helps with performance around that this is something that the creator of pathos has sort of let me know to do and it's also documented in their docs, which I've linked to here. So if you're curious about why this is here, feel free to look at that, but for now just know that we have to add this fine unique definition there. But the part that we really need to add right here is our Fields. So Fields is going to be a function that takes in t That's gonna have one argument that I've just named T. That's also a convention that pathos uses and we're going to expose a couple of different fields. We're going to expose the ID the message that created at And the updated so we just want these fields to be available via our API and to actually expose those fields we can use this tea arguments functions. So this has a set of functions that allow you to expose these fields via your schema. So I'll do T dot Expose and this is going to be an ID. Um, and you could pass this ID and then as you see here we get this nice type safety once again based on our Prisma schema because we're using that pop those plug-in so it knows which fields we actually have available. So I'll do expose ID and I'll say we want to expose the ID field from from our database and then he got exposed stream. So I'll be exposed stream. And then it's gonna list out all of our string fields that we can use and we only have one. It's a message. And then we could do our created app. So once again P dot Expose and then this one's just going to be exposed because this is our custom date type. So this doesn't have a built-in function. So what we're going to do here instead is we're going to do Expose and this is going to be the created at and we're gonna have to test it this configuration object. So the type here is going to be date. And that's it. That's how we tell it to use our custom date type. And then we're going to do the same thing for updated app. We just have to update this name here. So updated at There we go. Cool. And so this is now defining our note model how we want to expose it through our graphql API and what this is going to result in is a note type on our graphql schema. And so we'll see that in a little bit. But for now, this is all we need to do on our note type. Um, let's move on to the next section here. I'm going to look at the questions real quick. I see Korean has one I switched to part 3, but still have this error. Um Korean Yeah, just exactly what Stephanie said. If you are still running into that error. Look at the complete Branch copy over the package Json there or copy the package Json that I pasted above and follow those steps. There was an issue with a package that updated and it broke a couple of things. So, okay moving on to the second task building the user type. So we just built our note type. We now need to build the type for our users. So I'm going to create a new file here called user.s. And this file is also going to need the Builder imported at the top. And this Builder is going to run the the same function as before. We're going to run the Prisma object function. And we're going to create the user object. And then we need this find unique function, which I'm just going to paste in so I don't have to take the whole thing again. And then finally we can Define our Fields. So this is going to be the T function. And we can Define the fields. We want to return. So in our case here. We just want to return the ID the name and then the actual notes relation so that we can drill down from the users into the notes and sort of create that relationship here. So to do the ID it'll be the same as before. We'll be exposed ID. And for the name we could do p dot exposed stream and we can see our name populated there. And then this is the one where it's a little bit different we have our notes and we can do T dot relation. So this is how you define a relation. That's set up. And then once again, we get this type safety because the prism plug-in so it knows that notes is the only relation we have. So this is the only one to care about And that there's all we needed to do for our user object. This one was a little bit simpler than before. And now we can move on to the next section. I think I put a space in the name here for some reason. There you go. So now pop open the the notion document again, and we can move on to the next piece. So now at this point, we've defined our graphql types and our models and we need to actually Define the resolver now, so we need to tell our server how we want to actually query for this data once a query is sent to our graphql server for this data. In order to do that though. We need to have access to our Prisma object. That way we can get access to its type safe database client and to do that. We need to add Prisma to the graphql servers context that way it's available everywhere. So to do that we're going to go into our index.ts file. And here we need to import Prisma. from our DB file and within our create server we can then go into our context and we can provide it Charisma. So now Prisma is going to be available throughout our application and we can actually use it in in our resolvers. But currently this isn't done in a types of way. This is now available but none of our codes can actually know that this is available until we Define the type for it. So in order to actually Define that we need to go into our Builder. And once again, we're gonna update this a little bit so that it will know what the shape of the context should be. So in this generic up here, I'm gonna add a context e And this is going to have Prisma. Prismatic light which we imported previously So this is just saying that there's going to be something in in here within the context with the key of Prisma and it's going to be of the type Prisma client. And I think that's all we need to do for that piece. And now we can actually move on to adding the user query. So task four add a user query type within your personal instance. With your prism instance in the context and the types defined you have all the pieces. You need to write a query add a query type for your user data data to user.ts So within our user.ts we can Define that type and to do this we're going to do Builder dot query field. This is the function to add a field. To your query type which we Define in the Builder dot TS we have this root query type here. So we're now we're adding a specific query to it. So we're going to call this query users because this will just fetch all of our users. and then this will follow the same Convention as before where it has a t and then this T is going to do T that Charisma field. So this is a function on the T that actually allows you to define a field within your career type. And what this is going to take in is a type. So we're going to give it this type of user because we are querying for users. And then we need to Define how to actually resolve this query and this is going to take in a bunch of different parameters. The first one is query. root args CTX info so a lot of parameters here and I'll walk through what the important ones are doing. So what we're going to do is we're going to return. And then we need to do CTX Dot and we can see now that we have Prisma here. This is because it's in the Builder we defined our context and we said that there's a Prisma key in it of the type Prisma client. So now we know that within our context we have Prisma. And we're going to look for a user So within Prisma client you can just drill down into the model. You want to look for? And we're going to find many. And what we're going to pass into this instead of actually manually writing our query is we're going to dot dot weary. And this is some more magic with that pathos Prisma plugin it sort of under the hood handles generating this query in a performant way for US based on the graphql requests that comes in and we can simply pass that into the find many function as of these structured object and it will handle this for us. So that's super cool and that actually finishes up our resolver and this query for us. I see avron net got it working great Workshop so far. We'll catch up the rest of the recording avron if you are listing if you'd already left feel free to reach out if you run into any issues and let me know what you what you think about the rest of it good to have you. So now that we've got this piece done, I'm gonna move on to the registering of these queries and types. So we now have all of these types defined but this code doesn't actually get run anywhere. It's not referenced by anything that happens when our server starts up. So we need to actually import these somewhere where we can be sure that this is going to get registered and applied to our Builder before our server actually runs and to do that. We'll go into our schema.ts file. This file here is always going to be run when our server starts up because we use it on create server. So what we need to do is we need to import our different models here that we just defined that way they're available within the Builder before we generate our schema. And before we apply it to our graphql server. So what we're going to do is we're going to Simply import. models note and the user one as well. And I'm actually just order that. So yeah, this just Imports them. We're not actually doing anything with them. The reason we're doing this is because it's going to Simply import that which will trigger this code to be run and the objects will be added to our Builder instance. So we've instantiated those and applied them and at this point this is now applied to our graphql schema. So we've updated our schema to have all of this data available. So if we run our server now. We can. I'll just restart this just in case you can actually see in the playground what we've got. and so now if we look at the playground and I'll book the size up a little bit. If we look over here in the document Explorer we can see we have this query type and we have the new we have a new query here our users and this is going to return a list of users that follows this type. So if we go into our Explorer and we look for users we can add ID name and let's just say we add the message from the note. I'll close this guy and if we run this we should actually get our data back at this point. So this is working now and we have a our graphql server up and running with the API going. And just to sort of recap what we've done so far. We have set up our database schema using Prisma and Prisma sort of the source of truth. It's defining our database schema and the set of types. We're using in our application code and then we're using those types to with the pathos plug-in to sort of give us some type safety as well when we're actually generating our graphql types and models and resolvers and the graphql API itself is going to expose the graphql schema, which is going to allow us to get some nice type safety on the front end which we're gonna do in the next sections. So at this point I am once again going to turn it over to you guys. I'll give you 20 minutes, so I'll be back on the hour and You can go through the Section if you finish it. Feel free to let me know in the chat so I can gauge where we're at, and I hope it goes well for you. All right, everybody. I'm popping back in a little bit early here. The next section that we have is gonna be a pretty quick one. So I think we'll save a little bit of time on there. So I'm gonna go ahead and jump right into that. So I'm popping open the fourth lesson, which is called graphql on the client. This is where we're gonna jump into our reacts front-end code and we're gonna actually run our graphql queries and get some data to to actually render some data onto the screen and the gold this lesson is to actually put our graphql server that we just got done building to use by hooking the client side application up to it. We're gonna make a request to the graphql server and the graphql schema itself is going to allow us to do this in a way where we can Define exactly what fields we want and that gives us the ability to create some nice type safety around it. So to for the setup, once again, if you joined late and you're wanting to get started there is the part 4 Branch you can start from there. If you have issues actually running the projects. Feel free to look up in the Discord chat to the npm Run Dev issues that we've fixed but I'm gonna go ahead and get started here. The very first thing that we're going to need to do is install our graphql client. But before I do that, actually let's go through the client code and see what we actually have to start with. I'm gonna pop this open. I've got a source directory here and within the source, we have a couple of files we have our main file which is sort of the root of the application and this is all going to complain right now because I have not yet installed packages so you can I but this is the root of our application. This is where everything's getting sort of hydrated and rendered onto the screen. And then it's rendering our app components. So our app component simply has some static data in it for now and it's generating a list of users basically and this user display component is just gonna be a component that takes in our user data and displays it in a nice way. So if I actually run this right now, And that pop open Local Host. What we're going to see is just the static data. So we've got this user listed in a box and it has a little link to its note. It has the date here and this little button tab another one. So in the code, what we're going to need to do is we're going to need to actually replace this static data with the data from our graphql API and that's going to be our goal in this lesson. So to do that, we're going to need to query our API using a library that allows us to connect to a graphql API. So we're going to use one called Urkel you are ql and it's one that is super easy to use. It's pretty popular and it's pretty well maintained. So I like to use this one a lot. So let's go ahead and install that as well as the actual graphql package. So I'll do npm. I you are ul and graphql. So those are installed now we need to actually instantiate a client for us so that we can use it to query graphql and we need to provide it to our application and we're going to do that in main.tsx. So what we need to do here is import. the create client function and the provider component you are ql. And so this is just the function that allows us to configure and create a client connection here add. This provider component is just a react provider that allows us to use this client throughout our application. So if we actually use this, I'll do constantly clients equals create clients, and this is going to take in options. And there's a bunch of different options here. There's a bunch of different options here. That we can set but the only one that we need to actually worry about is this URL option. This is going to be the URL that points to our graphql API. So this is http. localhost 4000 / graphql this is the end point where if we go to our server and we run npm run. Yeah. That's where this gets spun up zero zero zero zero is another way of saying Local Host and it's at the graphql endpoint. I see a question from kilowatts is this client running server side? This is going to be not server-side. This is the front end. This is going to be completely a front-end application, but it will be accessing our graphql API. So we've got this client and now we need to provide it to our application. So to do that we're going to go in here and we need to wrap our app component in this provider. So I'll do. provider and we need to give this the value of the actual client that we've started up. So we'll give it value equals. play So to recap what we just did here we have instantiated our graphql client we can now use this to query our graphql API and in order to actually use it within our application. We needed to provide it here. If you aren't familiar with providers, I think in the document. I'm looking at it right now. I have some information about the Urkel docs and it's going to walk you through sort of what's provider does and what the create server options are so you can look at that if you're curious. But now that we've got that let's head back to our to our document here. We've provided or cool to our application and now we need to actually write a graphql query for our data and we're gonna write this in an organized way because in the next section we're going to actually use these queries to generate types based off of the individual queries. We're running that way we can get that type safety between the server side and the front end, but for this section, what we're gonna do is we're just gonna write the query and run it as is without that safety so that we can see sort of why it's important later on. So what we're going to do to organize this is we're going to go into our source directory within our client folder and we're going to create a new folder called. graphql and within that folder we're going to add a file called users.query.ts and this is where we're going to write our graphql query and within that within this file, we're going to actually export the query as well so that we can export the string and use that within our generated client. So to write graphql we're going to import this helper from Urkel. called gql and we need to export cost. And we're going to call this get users. And this is where we're going to write our graphql query. So we're going to write a query called it users. And once again in the document. I have a link to this to graphql syntax documentation. That way if you aren't familiar with how to write a graphql query. By hand, you can go and look at that and it'll walk you through the different ways. You can set up queries and Fields and parameters and all those kind of things. But I've got this users query now that I've defined and we're gonna run the user's query from our graphql API. That's the one that we just got done writing in the previous section. And now we can list out the fields that we want from it. So I'm going to get the ID. I'm gonna get the name and then I want to drill down into each user's notes and for each note. I want to get a message and a created at. So these are all the fields that we're going to need to actually run our application. If we look through the types that we have defined right now. These are manually written our user has a name and notes defined and message and created at and you might already be noticing that it's a little bit different than what we're querying for. We have the ID and users as well, but it's not here and that is a problem. That's actually one reason why type safety between the backend API and your front end is difficult is because you sort of have to manually keep those in sync but in the next section, we're going to set up a tool that allows us to do this automatically, but for now, we'll just keep it this way and accept the fact that it's not the best it can be and it will be shortly. So we've got that query written and I think we can move on to the next section now where we actually run that query. So to run this now that we have our graphql client provided to our application. We can simply go to where we want to run our query which will be in app.tsx. And we can import the client. So I'm going to do import. And there's going to be a function called use Query. And this is from the Urkel Library. And this is going to use our provided client to actually run our query once we use this function. I'm also going to import the users query that we wrote. from graphql users query so this is just importing that that query stream here. And then with those available we can actually get rid of this const. And we're going to replace it with the actual query that we want to run. So I'm going to do results equals and then we're going to use Query. And we're going to pass it the get. Oh, actually we need to pass it an object and this object has a couple of options available and we can use the query option and we're going to pass we get users query. And now this isn't actually going to be typed this is of the type any right now because we haven't we haven't defined what's actually going to get returned from this graphql API. So what we're going to need to do is use a generic in here as a generic parameter. And we're gonna say that this query is going to return users and it's going to be of the user type and it's returning a list of those now keep in mind that this isn't ideal that we have to Define this manually and also this is the manually defined type that we're sort of updating by hand. This isn't based off of the actual query we're running so this will get out of sync if your query ever changes and that is a problem. We'll be fixing later on but for now, that's how it is. This results that it returns is actually an array. and the first index of the array is your actual results and then your data from those results. Are nested in an object. So if we do that, what I'm doing here is I'm pulling out the data key from this results object and I'm storing it in a variable called Data. So now we can see that we're getting our data it's of this type here and it's got a list of users and each user is going to be of the user type. So that looks good. And if we actually open up another terminal, let's see here. I'm going to go into the server directory. And I will run Dev that way we get our server up and running. Was it already running? Let's see. I think it was so I'm going to just close everything. I'll see the into the server and vm1 Dev. I'll see the into the compliant mpm run that. There we go. Cool. So now we've got our server and our client running and we can actually go look at those. Let me make sure I'm not skipping anything. Doesn't look like it. So if we pop this guy open now, we can see that we have three listings and this is all the data that we see did into our database in the very first section of the workshop. So this is our actual data from our actual database being queried via our graphql API. So at this point, let's take a look at what we have as far as type safety. So we have type safety within our database schema. So we have safety there. We Define our schema through our Prisma schema and it gets applied to our database what that does is it generates a set of types that we can use within our servers application code. And those types get used with it pothos so that we can actually have type safety when we're building our graphql schema. So now we've got type safety across all of that. The graphql schema provides a way to safely query your API in a way where you know exactly which Fields you need and which Fields you're using and we're using typescript on the front-end currently to manually Define types that correspond with our types in the back end. So that's where the one missing link is there. We're still manually defining those in the next section. What we're going to do is we're going to actually set up that to where it's automated where it'll generate those types for US based off of the actual queries. We're running against our graphql API, but for now go ahead and walk through these steps this one it was a little bit shorter. So I'll give 10 minutes. I'll be back at at let's see what time it would be. I think it's 720 CET or 820 CET. I'm getting my time zones mixed up, but I'll be back in 10 minutes. And if you have any questions while you're following along with this, feel free to reach out on the Discord. I would love to answer any of those. So see you in a minute. All right, everybody. I am back. I hope all the questions have been answered so far Korean. I see that you were having those issues with the different ports. Like I put in the message, I would recommend just shutting down the servers and then starting the back end server first, which should start it up at localhost 4000 and then the client should be at locals 3,000 when you started out when you open up the client within the code snip that I gave you the clients should connect to localhost 4000. / well, so if you have more issues feel free to let me know. Otherwise, you could start off on the part five branch, which is where we're going to be starting off on this last section. So I'm gonna head over there. Walk down here. And this one's called Bridging the Gap and that's because as I mentioned at the end of the previous section, we still have this Gap in types where our back-end has it set of types, but then our front end has sort of a manually defined set of types that are supposed to match what we have on the back end, but if the back end ever changes or if any of our queries ever changed, we won't really know what happened and you can see that as was shown at the bottom of the fourth section where you remove the created at field and then you don't get any typescript complaints typescript as far as it was aware. You never had it created at field so or yeah, so it just didn't know what was going on and then your UI just spit out the not a number that's how you ended up with the Batman message. So in this section, we're going to be setting up a tool called graphql codegen and what this is going to do is it's going to actually analyze the queries that we're running against our graphql API and it's going to generate types for our client based off of those queries. And this allows you to have type safety because you can't even run a graphql request to a graphql API that's malformed. So it's going to take these requests and so long as they're valid is going to generate types for those This is going to allow us to have these automatically generated types and they're going to be based on exactly what you're querying for. So to do that. Let's start off on task one here. We first need to actually install all of those libraries and to do that. I'm going to copy and paste this. So if you go into your client project, Let's see. I'm gonna copy and paste this install script this install thing here. If you don't want to type out all of this is in the solution drop-down for the first task feel free to copy and paste that one since it's just an install and that's a lot of text to write but what we're essentially doing is we're installing the graphql code gin CLI tool and then these are a couple of plugins for it that we're gonna need to actually generate our generated types for typescript and the query objects for us. So I'm gonna install those here and that should take just a second. See how that's going good. Cool, so that's all installed. And that's all we needed to do for that first task and the next one is actually configuring graphql codegen so that it will generate those types for us and to do that. What you have to do is you have to set up a file where you provide your configuration and it's called codegen.yml. So let's go into our code here. And outside of the source folder. This is going to be in the very root of your client directory. You're going to create a new file called codegen.yml. This is a configuration file where you can just provide different things like where your graphql API even is which files you want to look through to look for your graphql query so you can generate your types and then that assets it's a generate. So we're going to be generating types. We're going to be generating query objects that we're going to use with Urkel. We're going to be generating all of that stuff. So let's define that here. The very first thing that we're going to do is we're going to define a schema. This is going to be the URL location of our graphql schema. So in order to actually run codegen your graphql server needs to be up and running and ours is at http. Local Host 4,000 / graphql, that's where our graphql schema lives so long as your server is up and running. And now we need to tell it where to look in our front end code for these graphql queries. And what we're going to tell it to do is look for any typescript files in our graphql folder because this is where we've put all of our queries. So it's only going to find this one query for now and it's going to generate types that letter application know how to actually run this query in a type Safe Way and how the response should look based off of what we wrote here. so to do that we're going to add a documents here. And what this is going to be is this is going to be a string and we're going to tell it to look in the source graphql. Directory and then we're going to tell it to look for any file with your dot TS extension. And then after that now we can Define what this what this library is actually going to generate for us. So we're going to do generates. And then we're going to drop down to the next line and we're going to say that we want to generate Source grantql generated that TS. So we want to generate all of the assets from this CLI tool into a file called generated.ts within our graphql folder. This is where all of our types are going to end up and all of our query objects. And then after that we need to Define which plugins we want to actually apply to this generated output and we're just going to do all of the plugins that we installed and I'm just going to paste those here because it's a little bit easier. get this over see cool So we're telling it that we are using the typescript plugin and the typescript operations plugin, which helps us generate the query objects and the type document node, which is how we're going to actually provide our query to the use Query hook that we've used. So with that all in place, we should be ready to move on to the next piece, which is actually adding a script where we can run this command. So if we head to package that Json we want to define a way to actually run this command. And to do that we're going to add a new script here. We're just going to call it codegen. And all it's going to do is run the command graphql codegen which has a dash between it so. graphql code gen and with that we can now run this command and it should generate all of our assets for us so long as our servers up and running. So let me make sure it is looks like it's still up. So now I can run npm run. coach in and so this is what it did it parstar configuration file. And then it went really quickly so you couldn't really see but it actually reached out to our graphql API and it said hey does this query look like it's a valid query based on what your schema looks like. It got a response back that said, yes. So now we have that safety where we know our query will actually work. And then finally, it used this query to generate a set of types and objects that Define that query in its responses. So we've got all that available. Now all of the types of the query objects are available to us so we can now start replacing our manually written types and queries with the generated objects. So if we go back into the code. We're going to head over to app.tsx. This is where we've done all of our all of our querying and what we can do is we can actually get rid of this get users query stream because we won't need that anymore. We can also get rid of this user type or actually sorry. No, we still need the user type I believe. Now we don't we can get rid of that. I'll get rid of that. And then we can actually get rid of this generic as well because the response is going to be known automatically. What we need to do though is we need to import the query object that got generated for us and passed into here instead of this query stream that we've removed and the query object is this git users document? It's a it's a Json version of what a normal graphql query string would look like so I'm going to copy this over. And if I go to app.tsx again? users document from perhaps well generated. So we're importing that document and we are getting the results out the exact same way we did before but the difference here is that we don't have to manually type the response to this query anymore. If you look at the results, you should see that the data is of the type get users query. And let's see. Now I was wondering why there's mayor here, but actually this is exactly what we were hoping for. So now these results are automatically typed because we're using this git users document use Query now knows what our typed response should be and exactly what type it is based on this query. So now what we're seeing is this is saying hey the property created at is missing. If you follow through the last section you removed the created at field at the end and typescript never complained. But it broke your UI now typescript is going to complain and say hey something's wrong here. You aren't even querying for created at but you're trying to use it in your application. So what we can do now is if we actually add created that back. And we run MBM run code gen. Now that she goes away. So it knows Hey Now You're querying for that field. The data is actually going to be available. So that's super cool. That's where we get some of that nice side pipe safety there. I'm gonna remove it for now because that's how I've set it up in the workshop. So I'll just run codegen again. And what we're going to actually do is go into our components to the user message. To the message.tsx file here and we're just gonna remove this makes it look a little bit cleaner. We don't really need the dates there. So I'm just gonna get rid of it. But that is super cool though. How you get that? Nice type safety between the front end and back end. And the way this is set up right now. It won't even let you write a query that's incorrect. So you get that Safety Not only with the types, but with actually writing your queries too because code Jen's gonna complain if you write a query that couldn't be accepted by the graphql API. So I've removed that and we're still getting this error because I did revert it back to not having that created at. Type and that's because if we go into the user display component. This is using the manually written type. This is using the user type from our types file, which doesn't have those automatically generated types for us. So we need to fix that. I'm gonna get rid of this. here this and what we're going to do instead is we're going to import the I called get user query from our generated file. So these are the types that we're generated for US based off of our query and you can see the type there. So what we're going to see in there is that we have a couple of different arrays. We have our users array and the notes array as you'd expect. And so what we want to do if we want to save that the note right or actually I guess we'll be the user type first. The user type is going to be of the type user query. and users and we just want to say that a user is going to be of the type. Users and just the first index of it. It doesn't really matter which index you use here, but we'll just say that the first index of it is what we want our user type to be. So as you can see on this type now, it has the ID the name and the notes because that's what we've queried for. And then we're going to need to do something similar to grab the note type. We're going to go into the first user of the array and then we're going to go into its notes property. And we'll just take the type of the first note in that in that array. That way we can get that note type out. And so at this point this should be not complaining anymore because now it knows that a user should be of the generated type based off of our graphql API. And with that we now have our application completely type safe the the back end from the database all the way to this front-end piece. And even the writing of your query strings is completely type safe. You will get some sort of error if you make any mistake with the types or with actually writing your query and that just makes it super easy to use the developer experience here is amazing the the tools like Prisma graphql code gen and pothos all working together give you a superpower as a developer that just make you feel very comfortable writing code without having to worry and stress about breaking things. So with this section, I think I will give you another We'll say 15 minutes to work on this and then I'll pop back on and see how everybody did and then we can wrap it up from there. So I'll be back in 15 minutes and let me know if you have any questions along the way. All right, everybody. It's just about come to the time. So I think we're gonna wrap things up here. I just want to thank everybody for coming along with me on this ride for being so active in the chat. I really appreciate that and all the little hiccups that we run into which are bound to happen in a workshop. You guys powered the room like like Champs and you help me even fix some of the the versioning issues. So I I really appreciate that and I hope you all got a lot out of this the the suite of tools that we used is just super cool to work with I always get really happy working with it because the developer experience is just so nice. So smooth allows for very low stress coating and I really like that a lot. I want to remind you that like I said at the beginning, all of my contact details are here. So if you ever want to reach out to me about anything at all, maybe it's about this Workshop or about Prisma in general. I am a developer Advocate there. Please feel free to shoot me a message and I will gladly get back to you and try to answer any questions or just queries you might have also like I said at the beginning if you do want to host this Workshop yourself, I've giving you the document so you have free you have free use of it. However you want to use it. So if you have a local Meetup if you hang out with friends at a maybe a college group, and they want to learn about all this stuff. Please give this Workshop. It's super fun. I enjoy doing it, and I know you will, too. But again, thank you so much for coming and I hope you all have a great afternoon or evening depending on where you're at. So see you all.
96 min
12 Oct, 2022

Watch more workshops on topic

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career