Express.js course with TypeScript Lesson 2 - Apollo & WebSockets

Duomly - Jul 13 '20 - - Dev Community

This article was originally published at https://www.blog.duomly.com/apollo-websockets-tutorial-express-js-course-lesson-2/


Intro to Apollo & WebSockets tutorial

Welcome to the second lesson of the Express.js course, where we'll focus on the Apollo & WebSockets tutorial for beginners.

In the previous lesson, we were building a simple GraphQL API with Expres.js.

Here you can find the URL of the Lesson1: How to build GraphQL API tutorial:

https://www.blog.duomly.com/how-to-build-graphql-api-tutorial-express-js-course-lesson-1/

The code that we'll build in the Express.js course should be used as the back-end for the front-end that my friend Anna is building in the React.js course.

By doing both of them, you'll be able to build the complete personal-finance application.

Here is the URL of the React.js course Lesson1: GraphQL tutorial:

https://www.blog.duomly.com/graphql-tutorial-reactjs-course/

Here you can do the whole React.js interactive course:

https://www.duomly.com/course/javascript-course/

In today's lesson, I will teach you how to create the Apollo server to serve real-time subscriptions through WebSockets.

We will create the new schema, and learn what GraphQL mutations are and how to use them.

Let's start!

And if you prefer video, here is the youtube version:

How to install graphql-subscriptions

As the few first steps, we need to spend on installing necessary dependencies, that we'll use today.

Like the first one, we should install the npm package that will let us create GraphQL subscriptions.

Open your terminal in the projects directory and type:

npm i -S graphql-subscriptions
Enter fullscreen mode Exit fullscreen mode

How to install HTTP

The next package that we need to install is "HTTP".

This one is very important because it'll let us create a proper server.

Open the terminal and type:

npm i -S http
Enter fullscreen mode Exit fullscreen mode

What is GraphQL Apollo and how to install apollo server

Apollo server is an open-source GraphQL package that lets us create a GraphQL server on your back-end easily.

The usage of that package is an excellent idea, especially if we would like to use Apollo Client on the front-end because they work together smoothly.

To install that package, we need to install the "apollo-server-express" npm package.

Open your terminal and type:

npm i -S apollo-server-express
Enter fullscreen mode Exit fullscreen mode

How to uninstall express-graphql

We are done with the installation of the new dependencies, but are we sure all we have are necessary?

If not, we definitely should delete them to not mess our package.json file.

One of the packages that we don't need anymore is "express-graphql" so, we need to uninstall it.

Open the terminal and type:

npm uninstall express-graphql
Enter fullscreen mode Exit fullscreen mode

Replace buildSchema with gql in the schema.ts

Congratulations, all of the dependencies are finished.

Now, we can go into the proper coding and its much more fun.

As the first step we should go into the "schema.ts" file and replace the "buildSchema" with "gql".

Dont' forget to delete unnecessary import and import the "gql".

import { gql } from 'apollo-server-express';

const schema = gql`
Enter fullscreen mode Exit fullscreen mode

What is GraphQL mutation and how to add mutation to the schema

GraphQL mutation is a type of GraphQL Query that returns data and should be used when we would like to modify data.

We use GraphQL mutation in cases like creating, updating, or deleting data.

We need to create a new expense, so the GraphQL Mutation is the best idea to use here.

Mutation looks a bit like Query but should have the allowed params that we can put in the braces to ask for the data.

type Mutation {
  newExpense(id: Int, date: String, amount: Int, type: String, category: String): Expense
}
Enter fullscreen mode Exit fullscreen mode

What is GraphQL Subscription and how to add subscription to the schema

GraphQL Subscription is a GraphQL feature that allows us to immediately send info when the subscribed event is fired.

It's a bit similar to the eventListener that we use in Javascript.

GraphQL subscriptions are an excellent idea to put in the WebSockets server that'll real-time send data to the front-end.

We need to create the subscription named "newExpenseCreated" that'll return "Expense" in the schema.ts.

type Subscription {
  newExpenseCreated: Expense
}
Enter fullscreen mode Exit fullscreen mode

Import pubsub in resolvers

The schema looks like it's done, congratulations!

Now, we should move into the resolvers.ts and develop some code there.

We'll need to use pubsub, so, as the first step, we need to import that dependency.

After importing, we need to assign "new PubSub()" to the variable named "pubsub".

import { PubSub } from 'graphql-subscriptions';
const pubsub = new PubSub();
Enter fullscreen mode Exit fullscreen mode

How to add mutation to the resolvers

Now, we need to rebuild resolvers a bit.

As the first step, we should put the expenses into the object named "Query".

In the next step, we should create an object named "Mutation", and create the mutation called "newExpense", that should take "root", and "args", as arguments.

Inside the function, we need to createExpense, publish the event "expense" by pubsub, and return created object.

Query: {
  expenses: () => {
    return getExpenses();
  },
},
Mutation: {
  newExpense: (root, args) => {
    const expense = createExpense(args);
    pubsub.publish('expense', { newExpenseCreated: expense });
    return expense;
  }
},
Enter fullscreen mode Exit fullscreen mode

How to add a subscription to resolvers

Subscription is the next point in the resolvers.ts that we should head to.

Like the previous steps, we should create an object "Subscription", and "newExpenseCreated" object inside.

Next, we should subscribe to the event named "expense".

Use "pubsub.asyncIterator" for that.

Subscription: {
  newExpenseCreated: {
    subscribe: () => pubsub.asyncIterator('expense')  // subscribe to changes in a topic
  }
}
Enter fullscreen mode Exit fullscreen mode

Create createExpense function in resolvers.ts

As the last step in the resolvers.ts, we should create a function that'll return the data for the expense.

Name it "createExpense", and return the objects with the same body, as we defined in the schema.

const createExpense = (args) => {
  return { id: args.id, date: args.date, amount: args.amount, type: args.type, category: args.category };
}
Enter fullscreen mode Exit fullscreen mode

Import dependencies in server.ts

Awesome!

Now, we can go into the server .ts, which will be the last file we need to code.

Here, we should start with the necessary dependencies that we'll import.

Keep express, schema, and resolvers as they're now.

And import "http", and "apollo-server-express" on the top of the server.ts.

Next, you can delete the whole content of the file, excluding the "app" variable.

import * as express from 'express';
import schema from './graphql/schema';
import { createServer } from 'http';
import { ApolloServer } from 'apollo-server-express';
import resolvers from './graphql/resolvers';

var app = express();
Enter fullscreen mode Exit fullscreen mode

How to create apollo server

If we deleted the previous server, we need to create the new one from scratch.

Create the ApolloServer, and assign that to the "apollo" variable.

const apollo = new ApolloServer({
  typeDefs: schema,
  resolvers: resolvers,
  playground: {
    endpoint: `http://localhost:4000/graphql`,
  }
});
Enter fullscreen mode Exit fullscreen mode

How to add apollo middleware

In the next step we need to apply apollo middleware to the node.js express.

It's a small deal because we need to just fire applyMiddleware on the "apollo" variable, and pass our app inside.

apollo.applyMiddleware({ app: app });
Enter fullscreen mode Exit fullscreen mode

How to create a WebSocket server

It's the last step of coding that we need to perform in today's lesson, we are almost on the finish.

We need to create a server, apply subscriptionHandler, and listen for the HTTP and WebSockets.

Let's see how it's done in the example below:

const ws = createServer(app);
apollo.installSubscriptionHandlers(ws);

ws.listen({ port: 4000 }, () =>{
  console.log(`GraphQL API URL: http://localhost:4000/graphql`)
  console.log(`Subscriptions URL: ws://localhost:4000/graphql`)
});
Enter fullscreen mode Exit fullscreen mode

Testing

You've finished code, congratulations!

Now, we can go into testing.

As the first, we need to run the app by:

npm run
Enter fullscreen mode Exit fullscreen mode

Next, we need to open that URL in two browser windows:

http://localhost:4000/graphql
Enter fullscreen mode Exit fullscreen mode

In the first window, we need to start listening for the subscription:

subscription newExpenseCreated {
  newExpenseCreated {
    id,
    amount,
    type
  }
}
Enter fullscreen mode Exit fullscreen mode

In the second one, we need to apply query variables:

{
  "id": 1, "date": "today", "amount": 10, "type": "Outcoming", "category": "Food"
}
Enter fullscreen mode Exit fullscreen mode

And do the proper mutation:

mutation newExpense(
$id: Int
$date: String
$amount: Int
$type: String
$category: String
){
  newExpense(id: $id, date: $date, amount: $amount, type: $type, category: $category) {
    id,
    amount,
    category
  }
}
Enter fullscreen mode Exit fullscreen mode

Conclusion

Now, you've learned how to create Apollo Server with WebSockets and Express.js, congratulations!

That knowledge is very powerful, and you can build a lot of applications with WebSockets and GraphQL.

For example, you can modify that code only a bit and build a real-time chat or real-time notification system.

I hope you'll build a lot of nice projects that will develop your coding portfolio and master your skills.

Let us know in the comments what you've built!

Here is the code for today's lesson:

https://github.com/Duomly/express-js-with-graphql-and-websockets/tree/Express-js-course-Lesson-2

Duomly promo code

Thanks for reading,

Radek from Duomly

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .