I'm trying to create a websocket endpoint for router in my express app with express-ws
module but getting an error.
Here is an entry point of the server index.ts
:
import express from 'express';
import expressWs from 'express-ws';
import * as dotenv from 'dotenv';
import cookieParser from 'cookie-parser';
import cors from 'cors';
import mongoose from 'mongoose';
import auth from './routes/auth.route.js';
import data from './routes/data.route.js';
import user from './routes/user.route.js';
import logger from './utils/logger.js';
import errorMiddleware from './middlewares/error.middleware.js';
dotenv.config()
const PORT = process.env.PORT;
const ORIGIN = process.env.DOMAIN_URL;
const app = expressWs(express()).app;
const corsOptions = {
origin: ORIGIN,
credentials: true
}
app.use(express.json());
app.use(cookieParser());
app.use(cors(corsOptions));
app.use('/api/auth', auth);
app.use('/api/data', data);
app.use('/api/user', user);
app.use(errorMiddleware);
async function start() {
try {
await mongoose.connect(process.env.DB_URL)
} catch (err) {
logger.error(`An error occured while connecting to database: ${err}`)
}
app.listen(PORT, () => {
console.log(`Server started on port ${PORT}`);
});
}
start();
And here is data.route.ts
:
import express from 'express';
import dataController from '../controllers/data.controller.js';
import authMiddleware from '../middlewares/auth.middleware.js';
const router = express.Router();
router.use(authMiddleware);
...
router.ws('/ws/tradebars', (ws, req) => {}); // TypeError: router.ws is not a function
export default router;
I had a similar issue.
Problem is you're calling the ws function on router before you've called this line (because of the import):
const app = expressWs(express()).app;
A possible solution is to wrap the ws call in a function that you can export, and call at a later point. For example (data.route.ts):
...
export const mountRouter = () => {
router.ws('/ws/tradebars', (ws, req) => {});
}
export default router;
And then in your index.ts
import data, {mountRouter} from './routes/data.route.js'
const app = expressWs(express()).app;
mountRouter()
app.use('/api/data', data);