Skip to content

GraphQL in Node.js

GraphQL in Node.js

GraphQL is an open-source data query and manipulation language for APIs, and a runtime for fulfilling those queries with existing data. Developed by Facebook, it provides an efficient, powerful, and flexible alternative to REST.

In a Node.js ecosystem, GraphQL is typically implemented using libraries like apollo-server or express-graphql.

Why GraphQL over REST?

  • No Over-fetching or Under-fetching: Clients can request exactly the data they need, no more, no less.
  • Strongly Typed Schema: The API is defined by a strict schema, serving as a contract between the client and the server.
  • Single Endpoint: Unlike REST, which usually has multiple endpoints for different resources, GraphQL typically exposes a single endpoint (e.g., /graphql).
  • Real-time Updates: With GraphQL Subscriptions, clients can receive real-time updates over WebSockets.

Core Concepts

1. Schema

The schema defines the types of data that can be queried or mutated. It’s written in the GraphQL Schema Definition Language (SDL).

type User {
id: ID!
name: String!
email: String!
}
type Query {
getUser(id: ID!): User
getAllUsers: [User!]!
}
type Mutation {
createUser(name: String!, email: String!): User!
}

2. Queries

Queries are used by the client to request data. They are similar to GET requests in REST.

query {
getUser(id: "1") {
name
email
}
}

3. Mutations

Mutations are used to create, update, or delete data. They are akin to POST, PUT, or DELETE in REST.

mutation {
createUser(name: "John Doe", email: "john@example.com") {
id
name
}
}

4. Resolvers

Resolvers are Node.js functions responsible for fetching the data for specific fields in the schema. When a query is made, GraphQL calls the corresponding resolvers.

const resolvers = {
Query: {
getUser: (parent, args, context) => {
return database.findUserById(args.id);
},
getAllUsers: () => {
return database.getAllUsers();
}
},
Mutation: {
createUser: (parent, args) => {
return database.insertUser(args.name, args.email);
}
}
};

Basic Setup with Apollo Server

Apollo Server is one of the most popular GraphQL server implementations for Node.js.

1. Installation

Terminal window
npm install apollo-server graphql

2. Creating the Server

const { ApolloServer, gql } = require('apollo-server');
// 1. Define Schema (Type Definitions)
const typeDefs = gql`
type Book {
title: String
author: String
}
type Query {
books: [Book]
}
`;
// 2. Sample Data
const books = [
{ title: 'The Awakening', author: 'Kate Chopin' },
{ title: 'City of Glass', author: 'Paul Auster' },
];
// 3. Define Resolvers
const resolvers = {
Query: {
books: () => books,
},
};
// 4. Initialize Server
const server = new ApolloServer({ typeDefs, resolvers });
// 5. Start Server
server.listen().then(({ url }) => {
console.log(`πŸš€ Server ready at ${url}`);
});

Integration with Express

If you already have an Express application, you can easily integrate Apollo Server using apollo-server-express.

Terminal window
npm install apollo-server-express express graphql
const express = require('express');
const { ApolloServer, gql } = require('apollo-server-express');
async function startServer() {
const app = express();
const typeDefs = gql`
type Query {
hello: String
}
`;
const resolvers = {
Query: {
hello: () => 'Hello world!',
},
};
const server = new ApolloServer({ typeDefs, resolvers });
await server.start();
// Apply middleware
server.applyMiddleware({ app });
app.listen({ port: 4000 }, () =>
console.log(`πŸš€ Server ready at http://localhost:4000${server.graphqlPath}`)
);
}
startServer();

Best Practices

  1. Pagination: Use Cursor-based pagination for large datasets instead of offset/limit.
  2. Dataloader: Use dataloader to batch and cache database requests, preventing the N+1 query problem.
  3. Security: Implement rate limiting, depth limiting, and query complexity analysis to protect against malicious queries.
  4. Authentication: Pass authentication tokens via HTTP headers and handle authorization within your resolvers or context functions.

Conclusion

GraphQL offers a highly efficient and strongly typed method to build APIs in Node.js. By adopting GraphQL, Node.js applications can provide clients exactly the data they need, enhancing performance and developer experience.