Fullstack TypeScript (feat. GraphQL & Node.js) Imported Resolver
Transcript from the "Imported Resolver" Lesson
>> So the next thing we gonna do is we want to break that resolver and those that type deaths variable that holds our Graph QL schema, we wanna get those out of this Apollo server file. I wanna this Apollo server that ts file to be boring, the kind of thing we hardly ever have to touch.
[00:00:18] That's really about wiring up the express middle wire. There's a schema that will end up, altering significantly over time, it'll be a pretty big file by the end of the day. We want that in its own place. And then this resolver thing is gonna get very, very big if we keep it as a single file similar to, in the Redux world.
[00:00:41] If you have all of your reducers and all of your actions in one place that becomes like a 2000 monstrosity very quickly. So that's where we're headed next, getting the schema out, getting the resolvers out and breaking our resolver down into sub objects. So the first thing we need to do in order to get our schema and resolver out or we're gonna deal with the schema first, but we need to take the stuff that's in that GQL tagged template string, right?
[00:01:11] And we're gonna move it into a .graphql file at the root of our project. Why? Well, if we're gonna make this the single source of truth for any types that are going over the network, it doesn't really just belong to server, it belongs to the project as a whole.
[00:01:28] And there's a lot of tooling that works really well on these dot, schema files and not everything can sort of strip these special strings out of a TypeScript code base, so this enables a wider variety of tooling. So let's go ahead and make that move. You can follow the instructions here or you can kind of follow me as I do this.
[00:01:51] But we're gonna go to our Apollo server TS. We're gonna grab everything that's in this string here, the whole thing, cut it. I can get rid of this. And then in the root of the project, I'm going to create a schema, that Graph QL and gives you a few of VS code icons, you'll see it light up as a special file type.
[00:02:20] That's how you know you did it right. And I'm just gonna paste that there, and give it a quick little format. And there we go. So that's what we got. That's part one. And we've broken our Apollo server now, right? We had this typedefs thing, you can see the file tab is red and it's unhappy, this thing's not here anymore.
[00:02:44] So the next thing we'll need to do is import that file into this TypeScript module so that we kind of get back to our working state. And to do that, we're gonna have to use some packages called GraphQL tools that will allow us to perform this import. So we're gonna add these imports to that Apollo server TS module.
[00:03:09] And these three have to do with the importing and then this last one, this is just a constant with the path to that schema.GraphQL file we just created. That's defined within the project. So let's add these imports up top. You can also clean up this unused import here, we're not gonna end up using this, I mean, if you care to do so Great, and now in our top level module scope, we're going to create this loadSchema thing, right?
[00:03:44] So this is gonna load the schema and transform it into the right data structure and uses a GraphQLFileLoader. So there are different ways you could store this information, there JSON formats for GraphQL schemas, but we have a dot schema file. That's that's what this GraphQL file loader is designed to parse.
[00:04:06] So let's put this in top level module scope right below the imports. And you can see we used a lot of those imports just now. And finally, we're gonna use this and this, we're gonna kind of smoosh it all together. So instead of passing typeDefs to Apollo server, we're gonna kind of assemble our resolvers and our schema together and use that to create our Apollo server.
[00:04:52] Delete all the plus signs, delete typeDefs. Make sure you bring resolvers into this object. This is a little, pull a copy pasted the diff incorrectly as I was cleaning it up. So add resolvers to schema, you should have both resolvers and schema passed into it. And if we hit Save, and if we go back to our API tools here.
[00:05:21] I'm gonna reload it just to make sure everything's, fresh. And we run that same query again, everything should work. So now we're at a state where we have this nice schema held up at the top of our project and we're importing it in and things are working exactly as they were before.
[00:05:46] Next, we're gonna do something similar with our resolvers. So we're both going to get it out of the Apollo server TS file, and we're gonna break it up into sub objects. For now, there's only gonna be one sub object, but in the end, we want kind of a central place where, well, let's say, in the end we want each top level collection of resolvers.
[00:06:14] And when we talk about a resolver that's one of these functions here. We want each family of them to be in its own TypeScript module. And then we want one file where everything's sort of brought together in alignment with the way the schema is defined and that's gonna be just sort of the final wire up step where there's not much interesting going on there.
[00:06:36] It's almost like importing stuff, assembling it into the object and reexporting it. So let's go ahead and get started with that. In the source folder of the server sub project, let's create a new module called resolves.ts. And we're gonna begin by going into Apollo server, grabbing this whole resolver thing, getting it out of there.
[00:07:09] Pasting it into this resolver's ts, and then make it the default export. And then in Apollo Server, That's okay, we'll do it the hard way. Import resolvers from resolvers. And now, again, I love coming back up for air very shortly after each of these steps, that way we make sure we don't break things and then write a whole lot of code on top of it.
[00:07:51] Go back to our dev tools here, make that API call, and it works, still works. So we've done this quick little refactor. Now, I wanna break this out into its own thing. So we can close ApolloServer Ts, this file just got boring. There's not much that's gonna evolve here.
[00:08:11] The exception being, we might mess with this a little bit as we need to put more things onto that little, that context object, little caches for certain records. But the rest of it we're not gonna touch for the rest of the day, the rest of the class. So let's make ourselves a folder to contain all of our resolvers.
[00:08:29] And we'll make one called a module within that folder called query. And I kind of like to name these with capital letters so that they kind of match with this convention, that you see in both the GraphQL schema and the way the resolvers are organized. So I'll grab this whole thing and I wanna to make this.
[00:09:01] I wanna make it a variable and then make it the default export. And then here we'll use our nice little enhanced object literal magic. And we can kind of just have an import. If we make it this nice capital Q query, we can very easily just sort of wire it up cuz that is both the key and the value.
[00:09:36] We only have to make it this one that'll work and it'll end up looking very nice and neat. If you like, you could give it a different name if you want. And one more time, let's make sure we still everything's working, great. So nice to have that thing running and to not have to stop and restart our server, right?
[00:09:58] So great. What have we just completed? Well, our schema is in a separate file. And our resolvers are now organized very nicely. And this is gonna get quite big, our resolver area, that's where the bulk of our interesting stuff in this app is gonna happen, at least on server side.