How to set up custom koa.js server in next.js - node.js

I have set up custom koa.js server and every time I make a request to api for example
/api/login
It always ends up in being 404 not found.
I have tried looking for a solution but, could not really find it.
Below is my server.js file
import '#babel/polyfill';
import dotenv from 'dotenv';
import 'isomorphic-fetch';
import next from 'next';
import Koa from 'koa';
import Router from 'koa-router';
import UserRouter from './routes/user';
import cors from '#koa/cors';
dotenv.config();
const compression = require('compression');
const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();
app.prepare().then(() => {
const server = new Koa();
const router = new Router();
server.use(
cors({
origin: '*',
})
);
router.get('*', async (ctx) => {
await handle(ctx.req, ctx.res);
ctx.respond = false;
});
server.use(UserRouter.routes()).use(UserRouter.allowedMethods());
server.use(router.allowedMethods());
server.use(router.routes());
server.listen(port, (err) => {
if (err) throw err;
console.log(`Server ready on ${port}`);
});
});

Related

Socket.IO giving constant polling 404 error (Socket.IO new user)

Im using a Express server and trying to implement Socket.io for the first time, and I keep getting this whenever I open it:
GET /socket.io/?EIO=4&transport=polling&t=OKgNATB 404 0.526 ms - 149
GET /socket.io/?EIO=4&transport=polling&t=OKgNBww 404 0.332 ms - 149
GET /socket.io/?EIO=4&transport=polling&t=OKgNDOV 404 0.411 ms - 149
app.ts:
import express from 'express';
import morgan from 'morgan';
import favicon from 'serve-favicon';
import path from 'path';
import cors from 'cors';
import { errorManager } from './middlewares/errors_middleware.js';
import { ordersRouter } from './routers/OrdersRouter.js';
import { usersRouter } from './routers/UsersRouter.js';
import { createServer } from 'http';
import { Server } from 'socket.io';
export const app = express();
const httpServer = createServer(app);
const io = new Server(httpServer, {
cors: {
origin: '*',
},
});
io.on('connection', (socket) => {
console.log('HELLO');
});
app.use(favicon(path.join('.', 'public', 'favicon.ico')));
app.use(cors());
app.use(morgan('dev'));
app.use(express.json());
app.get('/', (_req, res, next) => {
res.send('H');
next();
});
Routers
app.use('/orders', ordersRouter);
app.use('/users', usersRouter);
app.use(errorManager);
index.ts:
import http from 'http';
import createDebug from 'debug';
import { app } from './app.js';
import { dbConnect } from './dbconnect/dbconnect.js';
const debug = createDebug('StoryLine:INDEX');
const port = 3300;
const server = http.createServer(app);
server.on('listening', () => {
const addr = server.address();
if (addr === null) return;
let bind: string;
if (typeof addr === 'string') {
bind = 'pipe ' + addr;
else {
bind =
addr.address === '::'
? `http://localhost:${addr?.port}`
: `port ${addr?.port}`;
}
debug(`SERVER: Listening on: ${bind}`);
});
server.on('error', (error: Error, response: http.ServerResponse) => {
response.write(error.message);
response.end();
});
dbConnect()
.then((mongoose) => {
debug(
'Database connection -> SUCCESSFUL: ',
mongoose.connection.db.databaseName
);
server.listen(port);
})
.catch((error) => {
debug('Database connection -> COULD NOT CONNECT');
server.emit(error);
});
I simply want to get a console.log telling me that a user is connecting. I have tried following the Socket.io docs for express but its not working for me.

Why is my post route not running properly in Express app?

I am trying to add a route to '/signup' in my express application. But, every time I am sending a post request to the server it is resolving in "No response". Whereas the '/' route is working. Where have I gone wrong with the code?
index.js
import dotenv from "dotenv";
import cors from "cors";
import morgan from "morgan";
import dbConnect from "./config/dbConnect.js";
import { authRoute } from "./routes/auth.js";
dotenv.config();
const port = process.env.PORT;
const DATABASE_URI = process.env.DATABASE_URI;
const app = express();
dbConnect();
app.get("/", (req, res) => {
res.sendStatus(200);
});
app.use(express.json());
app.use(cors());
app.use(morgan("combined"));
app.use("/api/v1", authRoute);
app.listen(port, () => {
console.log(`Server running at ${port}...`);
});
auth.js
import { Router } from "express";
const router = Router();
router.post("signup", (req, res) => {
const password = req.body.password;
console.log(password);
});
export { router as authRoute };
dbConnect.js
import mongoose from "mongoose";
import dotenv from "dotenv";
dotenv.config();
const DATABASE_URI = process.env.DATABASE_URI;
const dbConnect = () => {
mongoose.set("strictQuery", false);
mongoose
.connect(DATABASE_URI)
.then(() => {
console.log("connected");
})
.catch((error) => {
console.error(error);
});
};
export default dbConnect;
router.post("signup", (req, res) => {
const password = req.body.password;
console.log(password);
});
The client doesn't get a response because you haven't written any code to send a response.
You completely ignore the object passed to res.
You don't call res.json or res.render or res.send or any of the other methods that would send a response.
Seems like the problem was with my VSCode extension RapidApi client, tried using insomnia and it worked out fine. Sorry for the trouble!

cookie is null when using reactjs as frontend and nodejs as backend

ReactJS code
import axios from 'axios';
import {useEffect,useState} from 'react';
import ReactDOM from "react-dom/client";
import React from "react";
const App = () => {
const [res,setRes] = useState(null)
useEffect(() => {
document.cookie='hello=3';
axios.post('http://localhost:4000/hello').then(res1 => {
setRes(res1.data)
})
},[])
return (
<div>
{res}
</div>
);
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<App />
);
Nodejs code
import express from 'express';
import cors from 'cors';
import bodyParser from 'body-parser'
import cookieParser from 'cookie-parser'
const PORT = 4000;
const app = express();
// cors
app.use(cors());
app.use(bodyParser.urlencoded({extended: false}));
app.use(cookieParser())
app.post('/hello', (req, res) => {
console.log(req.cookies)
res.send('This is from server!')
})
app.listen(PORT, () => {
console.log('listening on port', PORT); // eslint-disable-line no-console
});
On the line of console.log(req.cookies) in node.js it gives
[Object: null prototype] {}
what is the issue?
You are sending request to a different domain. If you want to send cookies with that request you would have to add withCredentials property in request options.
axios.get(
'http://localhost:4000/hello',
{ withCredentials: true }
);

Socket io connected at first, but after shutting down VS code it doesn't connect anymore?

I'm trying to make a comment section using socket io in my mern stack app. When I was first developing it it works just fine but after shutting VS code down for a rest I couldn't get it to connect anymore : (((
Here's my server.js
require ('dotenv').config()
const express = require('express')
const mongoose = require('mongoose')
const cors = require('cors')
const cookieParser = require('cookie-parser')
const fileUpload = require('express-fileupload')
const { file } = require('googleapis/build/src/apis/file')
const res = require('express/lib/response')
const path = require('path')
const Comments = require('./models/comment')
const app= express()
app.use(express.json())
app.use(cors())
app.use(cookieParser())
app.use(fileUpload({
useTempFiles: true
}))
const http= require('http').createServer(app)
const io= require('socket.io')(http)
//this doesn't give back anything
io.on("connect_error", (err) => {
console.log(`connect_error due to ${err.message}`);
});
// Socket io
let users = []
io.on('connect', socket => {
console.log(socket.id + ' connected.')
// code for comments
socket.on('disconnect', () => {
console.log(socket.id + ' disconnected.')
//socketCleanup();
socket.socket.reconnect();
users = users.filter(user => user.id!== socket.id)
})
})
and here's my GlobalState.js
import React, {createContext, useState, useEffect} from 'react'
import BooksAPI from './api/BooksAPI'
import GenresAPI from './api/GenresAPI'
import UserAPI from './api/UserAPI'
import axios from 'axios'
import io from 'socket.io-client'
export const GlobalState = createContext()
export const DataProvider = ({children})=>{
const[socket, setSocket] = useState(null)
useEffect(() =>{
const socket = io()
setSocket(socket)
return ()=> socket.close()
},[])
const state={
socket
}
return (
<GlobalState.Provider value={state}>
{children}
</GlobalState.Provider>
)
}
I can't find any solution on the internet that works and I don't even know why it's not connecting : ((( please help.

Translating server code to ES6 using socket.io

We are complete newbies to socket.io and express. And we have followed along this tutorial to learn socket.io https://www.valentinog.com/blog/socket-react/
And now we want to translate this line of code (older style):
const index = require("./routes/index").default
to ES6, below:
import router from './routes/index'
app.use('/', router)
But it does not work for us. We get this error in the terminal.
Full server.js code here
import express from 'express'
const app = express()
import { createServer } from 'http'
const server = createServer(app)
import { Server } from "socket.io"
const io = new Server(server)
import cors from 'cors'
import router from './routes/index'
const port = process.env.PORT || 4001
app.use('/', router)
app.use(index)
app.use(cors())
app.use(express.json())
let interval
io.on("connection", (socket) => {
console.log("New client connected")
if (interval) {
clearInterval(interval)
}
interval = setInterval(() => getApiAndEmit(socket), 1000)
socket.on("disconnect", () => {
console.log("Client disconnected")
clearInterval(interval)
})
})
const getApiAndEmit = socket => {
const response = new Date()
socket.emit("FromAPI", response)
}
app.listen(port, () => {
// eslint-disable-next-line
console.log(`Server running on http://localhost:${port}`)
})
I was able to use socket.io on my project like so:
const app = express()
const http = require('http').createServer(app)
const socketIo = require('socket.io')(http)
In other words I used require and did not use router. This might work for you unless there is a specific reason you need to do otherwise.

Resources