Welcome to this lesson on Integrating Apollo Server with Express! In previous lessons, you learned about setting up a basic GraphQL server, defining types and queries, and querying with arguments. In this lesson, you'll learn how to integrate Apollo Server with Express, a popular web application framework for Node.js.
Express is a minimal and flexible Node.js web application framework. It provides a robust set of features for building web and mobile applications.
Combining Apollo Server with Express allows you to leverage the strengths of both tools, creating a powerful and flexible API server. Express handles routing and middleware, while Apollo Server manages the GraphQL operations.
Type definitions define the shape of your data and the operations that can be performed. For example, you might define a Book
type and a Query
type to specify how to fetch books.
Let's define our schema:
TypeScript1const typeDefs = gql` 2 type Book { 3 id: ID! 4 title: String! 5 author: String! 6 } 7 8 type Query { 9 books: [Book] 10 book(id: ID!): Book 11 } 12`;
Resolvers fetch the data specified in the schema. Let's define the resolvers:
TypeScript1const resolvers = { 2 Query: { 3 books: () => books, 4 book: (_: unknown, args: { id: string }) => books.find(book => book.id === args.id), 5 }, 6};
Let's create a basic Express app:
TypeScript1import express from 'express'; 2const app = express();
Then, we create an Apollo Server instance and pass the type definitions and resolvers:
TypeScript1import { ApolloServer, gql } from 'apollo-server-express'; 2 3const server = new ApolloServer({ typeDefs, resolvers });
Finally, we apply the Apollo middleware to the Express app:
TypeScript1const startApolloServer = async () => { 2 await server.start(); 3 server.applyMiddleware({ app, path: '/graphql' }); 4 5 app.listen({ port: 4000 }, () => { 6 console.log(`🚀 Server ready at http://localhost:4000${server.graphqlPath}`); 7 }); 8}; 9 10startApolloServer();
In the last code block, we asynchronously start the Apollo Server and use applyMiddleware
to connect it to our Express app at the /graphql
endpoint. We then start the Express server on port 4000, logging that the server is ready. Finally, we call startApolloServer()
to initiate the setup.
After we defined our server and started it, let's do some queries.
First, we define our queries:
TypeScript1const queryBooks = ` 2 query { 3 books { 4 id 5 title 6 author 7 } 8 } 9`; 10 11const queryBookById = (id: string) => ` 12 query { 13 book(id: "${id}") { 14 id 15 title 16 author 17 } 18 } 19`;
Here, we define two queries, one for fetching all books and another for fetching a book by its ID.
Next, we use the fetch
API to execute these queries:
TypeScript1import fetch from 'node-fetch'; 2 3const url = 'http://localhost:4000/graphql'; 4 5const fetchData = async (query: string) => { 6 try { 7 const response = await fetch(url, { 8 method: 'POST', 9 headers: { 10 'Content-Type': 'application/json', 11 }, 12 body: JSON.stringify({ query }), 13 }); 14 const data = await response.json(); 15 console.log(JSON.stringify(data, null, 2)); 16 } catch (error) { 17 console.error('Error:', error); 18 } 19}; 20 21const runQueries = async () => { 22 await fetchData(queryBooks); 23 await fetchData(queryBookById('1')); 24}; 25 26// Run the queries 27runQueries();
The fetchData
function sends a POST request to our GraphQL endpoint with the specified query. The runQueries
function executes our defined queries.
Running the previous code should give you output like:
JSON1{ 2 "data": { 3 "books": [ 4 { 5 "id": "1", 6 "title": "The Hobbit", 7 "author": "J.R.R. Tolkien" 8 }, 9 { 10 "id": "2", 11 "title": "Harry Potter", 12 "author": "J.K. Rowling" 13 } 14 ] 15 } 16}
JSON1{ 2 "data": { 3 "book": { 4 "id": "1", 5 "title": "The Hobbit", 6 "author": "J.R.R. Tolkien" 7 } 8 } 9}
Which corresponds with the data we initially defined.
In this lesson, you learned how to integrate Apollo Server with Express, create a GraphQL schema and resolvers, and run your server. You've also seen examples of executing queries to fetch data. Let's go and practice now!