Express GraphQL + MongoDB

Resolve queries and mutations with MongoDB.

Notes

1MONGODB_URI=mongodb://localhost:27017/wtf-mongodb
2
1require("dotenv").config();
2
3const express = require("express");
4const { graphqlHTTP } = require("express-graphql");
5const { makeExecutableSchema } = require("@graphql-tools/schema");
6const { MongoClient, ObjectId } = require("mongodb");
7
1const connectToDatabase = async () => {
2 const client = new MongoClient(process.env.MONGODB_URI, {
3 useNewUrlParser: true,
4 });
5
6 let cachedConnection;
7
8 if (cachedConnection) return cachedConnection;
9
10 try {
11 const connection = await client.connect();
12
13 cachedConnection = connection;
14
15 return connection;
16 } catch (error) {
17 console.error(error);
18 }
19};
20
1const typeDefs = `
2 type Query {
3 users(limit: Int, skip: Int): [User]
4 user(id: ID!): User
5 }
6
7 type Mutation {
8 userCreate(input: UserInput!): UserCreatePayload
9 userUpdate(input: UserInput!): UserUpdatePayload
10 userDelete(input: UserDeleteInput!): UserDeletePayload
11 }
12
13 type User {
14 id: ID!
15 name: String!
16 bio: String
17 }
18
19 input UserInput {
20 id: ID
21 name: String
22 bio: String
23 }
24
25 input UserDeleteInput {
26 id: ID!
27 }
28
29 type UserCreatePayload {
30 user: User
31 }
32
33 type UserUpdatePayload {
34 user: User
35 }
36
37 type UserDeletePayload {
38 deletedUserId: ID
39 }
40`;
41
1const resolvers = {
2 Query: {
3 users: async (parent, { skip, limit }, context, info) => {
4 const data = await context.mongo
5 .db("wtf-mongodb")
6 .collection("users")
7 .find()
8 .skip(parseInt(skip, 10) || 0)
9 .limit(parseInt(limit, 10) || 0)
10 .map(({ _id, ...user }) => ({ ...user, id: _id }))
11 .toArray();
12
13 return data;
14 },
15 user: async (parent, { id }, context, info) => {
16 const { _id, ...user } = await context.mongo
17 .db("wtf-mongodb")
18 .collection("users")
19 .findOne({
20 _id: ObjectId(id),
21 });
22
23 return {
24 id,
25 ...user,
26 };
27 },
28 },
29 Mutation: {
30 userCreate: async (parent, { input }, context, info) => {
31 const { insertedId } = await context.mongo
32 .db("wtf-mongodb")
33 .collection("users")
34 .insertOne(input);
35
36 return {
37 user: {
38 id: insertedId,
39 ...input,
40 },
41 };
42 },
43 userUpdate: async (parent, { input }, context, info) => {
44 const { id, ...user } = input;
45
46 const { _id, ...existingUser } = await context.mongo
47 .db("wtf-mongodb")
48 .collection("users")
49 .findOne({
50 _id: ObjectId(id),
51 });
52
53 await context.mongo.db("wtf-mongodb").collection("users").updateOne(
54 {
55 _id,
56 },
57 {
58 $set: user,
59 }
60 );
61
62 return {
63 user: {
64 id,
65 ...existingUser,
66 ...user,
67 },
68 };
69 },
70 userDelete: async (parent, { input }, context, info) => {
71 const { id } = input;
72
73 await context.mongo
74 .db("wtf-mongodb")
75 .collection("users")
76 .deleteOne({
77 _id: ObjectId(id),
78 });
79
80 return {
81 deletedUserId: id,
82 };
83 },
84 },
85};
86
1const schema = makeExecutableSchema({ typeDefs, resolvers });
2
3const app = express();
4
5app.use(
6 "/graphql",
7 graphqlHTTP(async () => {
8 const mongo = await connectToDatabase();
9
10 return {
11 schema,
12 graphiql: true,
13 context: {
14 mongo,
15 },
16 };
17 })
18);
19
20app.listen(process.env.PORT || 4000, () => {
21 console.log(`Server started `);
22});
23