Advanced GraphQL, v2 Create a GraphQL Server
Transcript from the "Create a GraphQL Server" Lesson
>> So I'm just going to open up this repo, and I'm gonna do a tour of the repo later when we get to the first exercise, so don't worry about a lot of these files in here. If you're following along, you can just do what I do. The only thing that you need to make sure you do is just install your module.
[00:00:12] So do a yarn or NPM, install whatever your flavor is. It's all in the package .JSON over the yarn lock, so you should be good there. Once you do that, if you're following along, what I'm going to do is I'm just gonna create a new file, call it server js.
[00:00:25] And we're just gonna put everything in here for the sake of brevity. So walking through creating a server graph, the first thing we need is we need to create a schema. And a schema is based off of type definitions, and resolvers. So first thing let's create our type definitions.
[00:00:41] And we're going to use a GraphQL tag helper here, which allows us to write type definitions and it will compile them to an AST, something that the server can understand. So we're gonna use our graphql-tag like that. And then we'll just make our type definition. So we'll say typeDefs = the gql tag, and it's gonna use a template string here like this.
[00:01:07] And we'll just make some type definitions. So most all the APIs have users, so sure, we'll make a user, give it an id type. So remember, type keyword followed by name. Then these brackets, this is what's called creating a object type and this is the foundation of creating a server.
[00:01:26] So we have a user type who has an ID field, and that field is expecting to be an ID type and it is non-null or required. I can also make another field like username whose type would be string and that's also non-null or required. And you can imagine you can go on and on.
[00:01:44] So something like created at might be an integer or something like that. And then we might have another type here called settings. And settings might belong to a user. So we can add a relationship like this. That belongs to the user and then you can say something like theme, and that might be a string.
[00:02:06] So we have some type definitions. The next thing we need to do at minimum is create a query type, which is the exact same thing as a type definition up here, but it's special to graphQL. GraphQL looking for a type called query by default, which allows our clients to query for data.
[00:02:23] So we're gonna make a query type here, and we're going to define some fields that a client is able to interact with to actually retrieve some data. So we'll just make one for me, give me myself and that returns a user type. I could also say give me some settings by a user.
[00:02:43] And that's an ID, so we have some arguments there. And that returns settings. Let me give you the same thing for mutations, which are the opposite of queries, which allows you to mutate some type of data source. So if you said mutation and if we wanted to create some settings here, you might have to create an input type.
[00:03:03] Input, NewSettingsInput. So input type is needed if you wanna pass an object as an argument to a field. So I want new settings input and settings takes the user, which is going to be an ID, and then it takes a theme, which is a string. So now I can say cool, settings takes an input variable name and its type is NewSettingsInput is required and it returns Settings.
[00:03:38] That's a very basic graphQL server here, nothing too special, not using E-nums or unions or anything like that. So very basic, just wanted to get a walkthrough on it and kind of get a grasp of everyone's understanding of it and kind of set the tone for the rest of the course.
[00:04:00] So we got our type definitions here. The next thing is we'll have to make some resolvers, which is a map that maps one to one with the fields that we have in our type definition. So normally you start off creating resolvers for your queries followed by your mutations.
[00:04:14] And then you start creating resolvers on the field level for any relationships, like this user here. And then you might create resolvers for special things like converting or transforming your value or even virtualizing, something that doesn't exist in your database, but you want graphQL to expose it. So we'll start off with our query, Resolvers like this.
[00:04:38] And we know we have a me and we have a setting. So we'll just say me, and we'll just return some mock data here that looks exactly like a user. And we know what user has an ID, a username, and I created that. So I'll just return that.
[00:04:52] So it has an ID 1234, or whatever that is, and it has a username, and it created that. So username coder12, and it createdAt an integer, so something like that, so cool. We've got our new query there for settings looks like it takes some argument when we turn settings so we'll just our code step two settings.
[00:05:21] First value is gonna be the root value. We don't have one here. This is the top level resolver. And then we get the user as an argument here, and the second object here, so we'll have a user there. And then what you can do is just return something like this.
[00:05:40] So settings returns a user type and a theme. So I'll just say user and I'll just put the user ID there. So let's just do that, and a theme. I'll just hard code something and call it the Light theme. Cool, and then now we have a settings mutation.
[00:05:58] So we'll do that. And for this one we know that it takes an argument called input, which is a NewSettingsInput type, and that's an object, so no group value there. We do have an argument called input, and we're returning the NewSettings like that over here which has a user and a theme.
[00:06:24] And we know we get a user there. So I'm just going to return the input because it's the same thing. This is not a real database. So I'll just return that. ust got to make that one, there we go. And then now you just probably want to create resolvers for any type that has relationships.
[00:06:41] So settings has a relationship to user. So we'll make a resolver for that. So now I'm going out here and say settings has a user field. And because this is a field of a resolver, the first value would be, in this case, settings. So given the settings, I want to return a user that has an ID of settings.user.
[00:07:00] That's what you would do in a normal database. But I'm just going to return the same user that we have up here. Here we go. And at a minimum that's pretty much all you need to create your re-servers, have your type definitions from there. You just need to initialize your server.
[00:07:19] So I'm gonna say, ApolloServer which is the framework that we're using, like I said before. This comes from a package called Apollo-server. And we can go initialize it. So we can say, server = new ApolloServer, takes an object with some type definitions and a resolvers map like that.
[00:07:45] And then we can say server.listen, which returns a promise. Callback here should be a url property there. And we can say console.log. Server on url or server at url. There we go. Cool! So let's start this. You can just node and followed by the name. In this case, server.js is from that.
[00:08:18] Oops, I spelled require wrong. Server, it's misspelled Apollo. Lot of typos there. There we go. Unknown type settings, did you mean settings or string? So looks like I have unknown type per settings, settings.
>> Line 23.
>> Line 23. There we go, thank you. One too many Ts.
[00:09:03] Gotta love that strict nature, there you go. So now we have a server, a 4000. If you just issue a get request to that in your browser, you get a GraphQI playground like this which is the exploratory documentation that I was talking about. So ignore all this stuff that I have, we'll get to that later.
[00:09:20] But yeah, so now we have that. If we look at the docs, let me make this bigger. If you look at the docs, you'll see here's our queries, here's our mutations. If I do something like asking for me, and I want the ID back. I'll get that, I'll get an ID back.
[00:09:36] And that's basically us walking through a basic GraphQL API. Cool, and like I said, yeah, there's other things here, right? Like we didn't talk about a lot of other things you can do in the type definitions in different strategies for resolvers. But like I said, that's just more of, that's not so much necessary.
[00:10:00] I'm always focused on necessary things here, so we can get involved with more advanced things.