GraphQL - Example
GraphQL - Basic Server Example
Section titled “GraphQL - Basic Server Example”In this chapter, we will build a minimal but functional GraphQL API using modern tools. This API will return a simple greeting message, ‘Hello GraphQL World!’, and we’ll access it using the Apollo Sandbox (an in-browser GraphQL IDE).
Example Goal
Section titled “Example Goal”Create a standalone GraphQL server using Node.js, Express, and Apollo Server 4 that responds to a simple greeting query.
Core Concepts Used
Section titled “Core Concepts Used”- Node.js: JavaScript runtime environment.
- Express: Minimalist web application framework for Node.js.
- @apollo/server: The core library for building a GraphQL server.
- graphql: The JavaScript reference implementation for GraphQL.
- Schema Definition Language (SDL): To define our API’s structure.
- Resolvers: Functions that provide the data for our schema fields.
Step 1: Project Setup and Dependencies
Section titled “Step 1: Project Setup and Dependencies”Create a new project folder (e.g., hello-graphql-server) and initialize it:
mkdir hello-graphql-servercd hello-graphql-servernpm init -yInstall the necessary dependencies:
npm install @apollo/server graphql express cors body-parserThis installs Apollo Server 4, GraphQL.js, Express, and middleware for CORS and JSON body parsing.
Step 2: Define the Schema
Section titled “Step 2: Define the Schema”Define your GraphQL schema. For simplicity, we’ll define it directly as a string in our server file. In larger projects, you’d typically put this in a separate .graphql file.
// In server.js (or a separate schema.js file)const typeDefs = `#graphql # This "Query" type defines all the available entry points for reading data. type Query { # This query takes no arguments and returns a String greeting: String }`;This schema defines a single query field named greeting that returns a non-nullable String.
Step 3: Create Resolvers
Section titled “Step 3: Create Resolvers”Resolvers are functions that provide the actual data for the fields in your schema. The structure of the resolvers object should mirror the schema structure.
// In server.js (or a separate resolvers.js file)const resolvers = { // Resolvers for the Query type Query: { // Resolver function for the 'greeting' field greeting: () => { // This function simply returns the string we want return 'Hello GraphQL World!'; }, },};This resolver object provides a function for the greeting field within the Query type.
Step 4: Set up Apollo Server with Express
Section titled “Step 4: Set up Apollo Server with Express”Create a server.js file (if you haven’t already) and combine the schema, resolvers, and server setup:
import { ApolloServer } from '@apollo/server';import { expressMiddleware } from '@apollo/server/express4';import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer';import express from 'express';import http from 'http';import cors from 'cors';import bodyParser from 'body-parser';
// Define Schema (as shown in Step 2)const typeDefs = `#graphql type Query { greeting: String }`;
// Define Resolvers (as shown in Step 3)const resolvers = { Query: { greeting: () => 'Hello GraphQL World!', },};
// Required logic for integrating with Expressconst app = express();// Our httpServer handles incoming requests to our Express app.// Below, we drain the httpServer when the application is shut down.const httpServer = http.createServer(app);
// Same ApolloServer initialization as before, plus the drain plugin// for our httpServer.const server = new ApolloServer({ typeDefs, resolvers, plugins: [ApolloServerPluginDrainHttpServer({ httpServer })],});
// Ensure we wait for our server to startawait server.start();
// Set up our Express middleware to handle CORS, body parsing,// and our expressMiddleware function.app.use( '/graphql', // Endpoint path for GraphQL requests cors(), // Enable Cross-Origin Resource Sharing bodyParser.json(), // Parse JSON bodies // expressMiddleware accepts the same arguments: an Apollo Server instance and optional configuration options expressMiddleware(server, { context: async ({ req }) => ({ token: req.headers.token }), // Example context }),);
const PORT = process.env.PORT || 9000;
// Modified server startupawait new Promise((resolve) => httpServer.listen({ port: PORT }, resolve));
console.log(`🚀 Server ready at http://localhost:${PORT}/graphql`);This code initializes Express, creates an HTTP server, sets up Apollo Server with the schema and resolvers, applies necessary middleware (CORS, JSON parsing), and integrates Apollo Server with Express using expressMiddleware at the /graphql path.
Step 5: Start the Application
Section titled “Step 5: Start the Application”Add a start script to your package.json (if you haven’t already):
"scripts": { "start": "node server.js" // Requires Node.js v14.13.1+ for top-level await or wrap in async function}Run the server from your terminal:
npm startYou should see the message: 🚀 Server ready at http://localhost:9000/graphql
Step 6: Test the GraphQL API
Section titled “Step 6: Test the GraphQL API”Open your web browser and navigate to http://localhost:9000/graphql.
This will open the Apollo Sandbox, a tool similar to GraphiQL, allowing you to interact with your API.
In the left-hand panel (Operation panel), enter the following GraphQL query:
query MyFirstQuery { greeting}Click the ‘Run’ or ‘Execute Query’ button (often looks like a play icon).
In the right-hand panel (Response panel), you should see the result from your server:
{ "data": { "greeting": "Hello GraphQL World!" }}Congratulations! You’ve successfully built and tested a basic GraphQL server.