DEV Community

Cover image for ⚡ Add a GraphQL Server to a RESTful Express.js API in 2 Minutes
Khalil Stemmler for Apollo GraphQL

Posted on

⚡ Add a GraphQL Server to a RESTful Express.js API in 2 Minutes

⚡ Add a GraphQL Server to a RESTful Express.js API in 2 Minutes

You can get a lot done in 2 minutes, like microwaving popcorn, sending a text message, eating a cupcake, and hooking up a GraphQL server.

Yup. If you have an old Express.js RESTful API lying around or you're interested in incrementally adopting GraphQL, we only need 2 minutes to hook it up with a fresh new GraphQL Server.

Ready? Set. Go!

Let's say that your server looked something like the following.

import express from 'express';
import { apiRouter } from './router';

const app = express();
const port = process.env.PORT || 5000;

// Existing routes for our Express.js app
app.use('/api/v1', apiRouter);

app.listen(port, () => console.log(`[App]: Listening on port ${port}`))
Enter fullscreen mode Exit fullscreen mode

At the root of your project, npm install apollo-server-express as a dependency.

npm install apollo-server-express --save
Enter fullscreen mode Exit fullscreen mode

Go to where your Express app is defined and import ApolloServer and gql from apollo-server-express.

import { ApolloServer, gql } from 'apollo-server-express'
Enter fullscreen mode Exit fullscreen mode

Next, create an instance of an ApolloServer with the simplest possible GraphQL type definitions and resolvers.

const server = new ApolloServer({
  typeDefs: gql`
    type Query {
      hello: String
    }
  `,
  resolvers: {
    Query: {
      hello: () => 'Hello world!',
    },
  }
})
Enter fullscreen mode Exit fullscreen mode

Lastly, use ApolloServer's applyMiddleware method to pass in our Express.js server.

server.applyMiddleware({ app })
Enter fullscreen mode Exit fullscreen mode

Boom. That's it!

Your code should look something like this.

import express from 'express';
import { v1Router } from './api/v1';
import { ApolloServer, gql } from 'apollo-server-express'

const app = express();
const port = process.env.PORT || 5000;

const server = new ApolloServer({
  typeDefs: gql`
    type Query {
      hello: String
    }
  `,
  resolvers: {
    Query: {
      hello: () => 'Hello world!',
    },
  }
})

server.applyMiddleware({ app })

app.use('/api/v1', v1Router);

app.listen(port, () => {
  console.log(`[App]: Listening on port ${port}`)
})
Enter fullscreen mode Exit fullscreen mode

If you navigate to localhost:5000/graphql, you should be able to see your GraphQL schema in the GraphQL playground.

Alt Text

Note: If you want to change the URL that the GraphQL endpoint sits at from /graphql to something else, you can pass in a path option to server.applyMiddleware() with the URL you want, like path: '/specialUrl'. Check out the docs for full API usage.

How simple was that? Is your popcorn finished? 😉

Summary

Here's what we did.

  1. Install apollo-server-express
  2. Create a new ApolloServer
  3. Connect your GraphQL Server with server.applyMiddleware

I personally really love the fact that Apollo Server is non-intrusive and can be tacked on any project as an alternative way to communicate between services and applications.

Where to go from here

If you're new to Apollo and GraphQL, a great way to learn is to actually build something in real life. For that reason, I highly recommend checking out the Apollo Fullstack Tutorial (you can also learn in TypeScript now 🔥).

I'm Khalil Stemmler, a Developer Advocate at Apollo GraphQL. I teach advanced TypeScript, GraphQL, and Node.js best practices for large-scale applications. Feel free to ping me on Twitter if you need help with anything Apollo, TypeScript, or architecture-related. Cheers 🤠

Top comments (3)

Collapse
 
paul_melero profile image
Paul Melero

But what's in the ./router, my man?

Collapse
 
stemmlerjs profile image
Khalil Stemmler

Scary, secret things... Just kidding.

Usually, my router is where I delegate chunks of the API off to appropriate sub-routers to then get more detailed with how things get done :)

I also usually version my REST APIs (like v1Router).

import express from 'express'
import { userRouter } from '../../../../modules/users/infra/http/routes';
import { memberRouter, commentRouter } from '../../../../modules/forum/infra/http/routes';
import { postRouter } from '../../../../modules/forum/infra/http/routes/post';

const v1Router = express.Router();

v1Router.get('/', (req, res) => {
  return res.json({ message: "Yo! we're up" });
})

v1Router.use('/users', userRouter);
v1Router.use('/members', memberRouter);
v1Router.use('/posts', postRouter);
v1Router.use('/comments', commentRouter);

export { v1Router } // or { router }, like the rest of the code.
Enter fullscreen mode Exit fullscreen mode

You can see this code in the project it's from here, btw.

Collapse
 
paul_melero profile image
Paul Melero

Appreciated ❤️