Building a Real-Time Message Board with Node, Apollo GraphQL, React and TypeScript
Part 01 — Sever and Client App Development
Introduction
In this article, I will take you through the steps of creating a real-time message board Web application. This project demonstrates Full CRUD (Create, Read, Update, Delete) with real-time updates by using GraphQL subscriptions. We will be using Node.js and Apollo Server for the backend, and React with TypeScript and Vite for the frontend. Styling will be handled using SASS.
Technologies Used
- Node: JavaScript run-time for the backend.
- Apollo Server: GraphQL server, used to consume queries, mutations, and subscriptions.
- React: JavaScript library for declarative UIs
- TypeScript: Java Script with Type Safety
- Vite: Next-generation front-end tooling for faster builds.
- SASS: CSS preprocessor for more flexible and maintainable styles
Project Setup
Backend Setup
Step 1: Initialize the Server
Create a directory for your server and initialize a Node.js project
mkdir server
cd server
npm init -y
Step 2: Install Dependencies
Install the required dependencies
npm install @apollo/server graphql ws subscriptions-transport-ws express
npm install --save-dev typescript @types/node @types/ws @types/expres
Step 3: Configure TypeScript
Create a tsconfig.json
file in the server directory
{
"compilerOptions": {
"target": "ES2019",
"module": "commonjs",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"outDir": "./dist"
},
"include": ["./**/*.ts"]
}
Step 4: Create the Server
Create a src
directory and add a server.ts
file
The code created a GraphQL server using Apollo Server and Express, that can be used by the client for subscription, and for real-time updates. It describes a schema that has types, queries, mutations, and subscriptions related to the messages. It saves messages with an in-memory array and subscription events with a PubSub instance.
The server executes the merged type definitions and resolvers into a schema and connects it with an Express application. Conticule uses WebSocket to manage subscriptions, so if you subscribe to it you will receive real-time changes in the client.
Also, middleware interfaces were added for CORS to parse JSON request bodies and listen on port 4000 for a streaming solution to persist and update messages in memory and in real-time.
2. Frontend Setup
Step 1: Initialize the Client
Create a directory for your client and initialize a Vite project with React and TypeScript
mkdir client
cd client
npm create vite@latest --template react-ts
npm install
Step 2: Install Dependencies
Install the required dependencies for Apollo Client and SASS.
npm install @apollo/client graphql subscriptions-transport-ws
npm install sass
Step 3: Configure Apollo Client
Create a src/apolloClient.ts
file to set up Apollo Client.
This example is a final setup that will include configuring an Apollo Client for a React application and making it able to connect to a GraphQL server with HTTP and WebSocket protocols. This puts an HttpLink for regular queries/mutations by way of HTTP, in addition to a WebSocketLink for real-time subscriptions.
The split function was written such that operations are directed to the correct link based on the type of operation. These links are used to initialize an ApolloClient along with an in-memory cache for effective data management.
Then the API client and ApolloProvider are configured for the application to provide a simple and clean integration of the GraphQL into the application and to receive real-time updates as well.
Step 4: Create the Messages Component
Create a src/Messages.tsx
file to handle displaying, adding, updating, and deleting messages.
The purpose of this React component, Messages, is to use Apollo Client for GraphQL queries, modifications, and subscriptions in order to manage a list of messages. It maintains the state up to current with real-time updates while retrieving existing messages, adding new ones, updating old ones, and deleting messages.
The component communicates with the backend using GraphQL operations: ADD_MESSAGE, DELETE_MESSAGE, UPDATE_MESSAGE, and GET_MESSAGES for retrieving messages, adding new messages, and updating messages. The MESSAGE_ADDED, MESSAGE_UPDATED, and MESSAGE_DELETED subscriptions make sure that the UI updates automatically whenever changes are made to the server.
The component offers handlers for adding, editing, and removing messages in addition to maintaining the local state for error and message input.
Step 5: Create the App Component
Update src/App.tsx
to use Apollo Provider and include the Messages component.
The Main App component of a React application is defined by this code. It passes it to a specified Apollo Client instance and wraps the entire application using the ApolloProvider. This configuration guarantees that Messages and other child components can communicate with the GraphQL server.
Rendering inside the main application layout, the Messages component manages the real-time fetching, displaying, and updating of messages. All across the component tree, the ApolloProvider makes the Apollo Client accessible, allowing for smooth GraphQL queries, modifications, and subscriptions.
Step 6: Style the Component
Create a src/Messages.module.scss
file to style the Messages
component. I used the SCSS module to style it.
.container {
max-width: 800px;
margin: 0 auto;
padding: 20px;
.error-text{
background-color: #dc3545;
color: #ffffff;
padding: 10px;
border-radius: 5px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
display: flex;
margin-top: 10px;
justify-content: space-between;
.close{
background-color: #ffffff;
color: #dc3545;
border: none;
border-radius: 5px;
}
}
}
.header {
text-align: center;
margin-bottom: 20px;
}
.messageList {
list-style: none;
padding: 0;
li {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
margin-bottom: 10px;
background-color: #444444;
border-radius: 5px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
color: #ffffff;
}
button {
margin-left: 10px;
padding: 5px 10px;
border: none;
border-radius: 3px;
background-color: #007bff;
color: white;
cursor: pointer;
&:hover {
background-color: #0056b3;
}
&:first-of-type {
background-color: #28a745;
&:hover {
background-color: #218838;
}
}
&:last-of-type {
background-color: #dc3545;
&:hover {
background-color: #c82333;
}
}
}
}
.inputGroup {
display: flex;
margin-top: 20px;
input {
flex: 1;
padding: 10px;
border: 1px solid #ddd;
border-radius: 3px;
margin-right: 10px;
}
button {
padding: 10px 20px;
border: none;
border-radius: 3px;
background-color: #007bff;
color: white;
cursor: pointer;
&:hover {
background-color: #0056b3;
}
}
}
Optimized Component Structure and Best Practices
To make the main ideas of this project easier for you to understand, I have simplified my explanations. However, it’s critical to leverage appropriate component structures, custom hooks, and TypeScript types to increase reusability and maintainability.
Enhancing the Basic App
Key Enhancements
Custom Hooks
Encapsulated all GraphQL operations into a custom hook (useMessages
). This ensures proper cache management and cleaner code.
Component Division
- Messages: Manages state and data flow.
- MessageList: Displays messages and handles updates/deletions.
- MessageInput: Manages input for adding messages.
Replacing Prompt with Modal
Replaced the edit message prompt with a reusable Modal
component for a better user experience.
Reusable Components:
Developed reusable components (Button
, Alert
, Modal
) and used them consistently across the app to ensure uniform styling and behavior
Real-time update indicator with toast
Source Code
I have shared the improved version with the above improvements on my Github. Please follow react-ts-graphql-real-time-message-board
If you want to get the same code we practiced above, please use the “basic” branch of the same repository.
Conclusion
This blog article describes how we used Node.js, Apollo Server, React, TypeScript, Vite, and SASS to create a real-time message board application. We went over how to use Apollo Client to create a React client, how to set up a GraphQL server with subscriptions, and how to use SASS to style the components. This project demonstrates how cutting-edge web technologies can be used to produce a responsive, real-time application.
To continue with Part 2 of this article, please follow Real-Time Message Board Testing with GraphQL Playground