GraphQL
Recently I have been working on a node stack project as a full stack JavaScript developer, it’s a great experience because I’m working with talented developers. We use TypeScript on both backend and frontend which is great because I’m coming from a .NET background and couldn’t be happier; Well we have types for our JS code :) But sometimes TypeScript drives me crazy for example when working with existing React libraries there are no type declarations and a lot of TypeScript’s benefits disappear so we have to write our own .d.ts
file but it is worth it :) On the backend we use GraphQL for our APIs, so in this post, I explain my observation about this technology.
What’s GraphQL?
GraphQL is a query language for any kind of API and can fulfil any queries across multiple databases. The main benefit of using it is that you can ask for exactly what you want and you will get the result and nothing else. In this case, clients describe what they want their data and shape of it. The good point is that requests are validated against so-called Schema
, we create this schema on our server, it basically describes the functionality available to our clients, inside this schema, we define our type definitions:
type User {
id: ID!
firstName: String
lastName: String
age: Int
}
type Query {
users: [User]
}
In the schema, we need a top-level type called Query
. The server defines the queries it can accept. So, in this case, we’re saying we need to return a list of users, the result is an array of type User.
Resolvers
Now we need a Resolver
to figure out what we get back when we call users
query. Resolvers are basically some functions that respond to queries and mutations, they are the functions that give us the results from a query.
const root = {
users: () => {
return [
{ id: 1, firstName: "Sirwan", lastName: "Afifi", age: 29 },
{ id: 2, firstName: "User 2", lastName: "lastName2", age: 20 },
{ id: 3, firstName: "User 3", lastName: "lastName3", age: 20 },
{ id: 4, firstName: "User 4", lastName: "lastName4", age: 20 },
{ id: 5, firstName: "User 5", lastName: "lastName5", age: 20 },
{ id: 6, firstName: "User 6", lastName: "lastName6", age: 20 },
{ id: 7, firstName: "User 7", lastName: "lastName7", age: 20 },
{ id: 8, firstName: "User 8", lastName: "lastName8", age: 20 },
];
},
};
Now we can query the users
to get the result, the query gets parsed and executed against a data source on the server and the server sends back the result as JSON:
As you can see we have intellisense for our API. In fact, GraphQL is more like TypeScript for our API, by using it we have awesome static type analyze. In traditional REST we had many requests but with GraphQL we only have one single endpoint.
Mutation types
The query type is responsible for defining what will return when we call the query. With mutation type, we can mutate (change, create) data.
input UserInput {
id: ID!
firstName: String
lastName: String
age: Int
}
type Mutation {
createUser(input: UserInput): User
}
The great point about a mutation is that we mutate something and we also ask for something in the result, that’s why we can specify a return type for a mutation, in this case, it’s User
:
GraphQL is a convenient way for a client to communicate with the server, There is much more to talk about this technology so I will pick up again in my next article.