New to nodejs world. Trying to create a REST Service with express and I'm stuck trying to debug this issue... I want to call a GET resource that has a route param in router.use('/applications/:appId/messages', messageRoutes);
index.js
import Promise from 'bluebird';
import mongoose from 'mongoose';
import config from './config/env';
import app from './config/express';
// plugin bluebird promise in mongoose
mongoose.Promise = Promise;
// connect to mongo db
mongoose.connect(config.db, { server: { socketOptions: { keepAlive: 1 } } });
mongoose.connection.on('error', () => {
throw new Error(`unable to connect to database: ${config.db}`);
});
const debug = require('debug')('express-mongoose-es6-rest-api:index');
// listen on port config.port
app.listen(config.port, () => {
debug(`server started on port ${config.port} (${config.env})`);
});
export default app;
/config/express.js
import express from 'express';
import bodyParser from 'body-parser';
import routes from '../server/routes';
const app = express();
// parse body params and attache them to req.body
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
[...]
// mount all routes on /api path
app.use('/api', routes);
[...]
export default app;
/server/routes/index.js
import express from 'express';
import userRoutes from './user';
import messageRoutes from './message';
import applicationRoutes from './application';
import authRoutes from './auth';
const router = express.Router(); // eslint-disable-line new-cap
// mount message routes at /messages
router.use('/applications/:appId/messages', messageRoutes);
export default router;
/server/routes/message.js
import express from 'express';
import validate from 'express-validation';
import paramValidation from '../../config/param-validation';
import messageCtrl from '../controllers/message';
const router = express.Router(); // eslint-disable-line new-cap
router.route('/')
/** GET /api/applications/:appId/messages - Get list of messages */
.get(messageCtrl.getByAppId);
export default router;
/server/controllers/message.js
import mg from 'mongoose'
import Message from '../models/message';
import moment from 'moment';
function getByAppId(req, res, next) {
//return res.json(req.message);
console.log(req);
}
export default {getByAppId};
The result of console.log(req) is a printout of the request object but the params array is blank.
baseUrl: '/api/applications/57fcf8129eb1d52f1cb10332/messages',
originalUrl: '/api/applications/57fcf8129eb1d52f1cb10332/messages/',
_parsedUrl:
Url {
protocol: null,
slashes: null,
[...]
params: {},
query: {},
Can anyone offer any guidance? Much appreciated. Not sure why the params are blank. Could it be the :appId variable declaration in express router.use() statement?
Related
I have three files when I try running index.js file DB work well but router does not work and if run server.js DB and router does not work
server
import express from 'express'
import cors from 'cors'
import restaurants from './api/restaurants.route.js'
const app = express()
app.use(cors())
app.use(express.json())
app.use("/api/v1/restaurants", restaurants)
app.use("*", (req, res) => res.status(404).json({error: "Not Found"})) // any router not found in our routers
export default app;
index
import app from './server.js'
import mongodb from 'mongodb'
import dotenv from 'dotenv'
dotenv.config()
const mongoClient = mongodb.MongoClient
const port = process.env.PORT || 8000
mongoClient.connect(
process.env.RESTREVIEWS_DB_URI,
{
useNewUrlParser: true,
useUnifiedTopology: true,
}
).catch((e) => {
console.log(e.stack)
process.exit(1)
}).then(async client => {
app.listen(port, () => {
console.log(`app listen in link http://localhost:${port}/api/v1/restaurants`)
})
})
router
import express from 'express'
const router = express.Router();
router.get('/api/v1/restaurants', (req, res) => {
res.status(200).send("HelloWorld");
})
export default router
I'm trying to implement a dynamic import inside a express.js router
now I have a bellow code
HelloWorldController.js
export const helloWorld = function (req, res) {
res.send('hello world')
}
router.js
export default async function (app) {
app.use('/', await ( async function () {
const helloWorldController = await import('./helloWorldController.js')
const router: express.Router = express.Router()
router
.get('/', helloWorldController.helloWorld)
return router
})
}
server.js
import express from 'express'
import router from './router.js'
const app = express()
router(app)
app.listen(3000, function(){
logger.ready(`Web Server is running on port 3000`)
})
This is the result I'm getting when I run server.js
I have a 404 error
GET / 404 18.761 ms - 25
This is working fine
router.js
import * as helloWorldController './helloWorldController.js'
export default async function (app) {
app.use('/', await ( async function () {
const router: express.Router = express.Router()
router
.get('/', helloWorldController.helloWorld)
return router
})
}
** What am I doing wrong? **
ES6 import syntax is not supported yet in node js,
try this syntax const {express} = require("express")
Can anyone help me use ES import version of the: require('./config/passport')(passport);. I cant get this to work. I don't think you can use both ES import and require at the same time. I get and error that require is undefined.
import express from 'express';
import bodyParser from 'body-parser';
import mongoose from 'mongoose';
import cors from 'cors';
import dotenv from 'dotenv';
import { createRequire } from 'module';
const URL = createRequire(import.meta.url);
import passport from 'passport'
import postRoutes from './routes/posts.js'
import userRoutes from './routes/user.js'
import loginRoutes from './routes/login.js'
const app = express();
dotenv.config();
require('./config/passport')(passport);
app.use(passport.initialize());
app.use(passport.session());
Yes, we can not use require which is commonjs modules with import which is ES6 modules.
Though the solution is really simple. Basically, you have to pass passport as an argument to the function exported from ./config/passport.
All you have to do is just import the function as is and pass passport as an argument.
So here's what you need to do:-
config/passport.js
export default = (passport) => {
/* use passport here */
}
index.js
import passport from "passport";
import passportConfig from "./config/passport";
passportConfig(passport);
Aryaman is correct but I would like to offer a slightly different solution.
I would recommend that you keep passports logic out of the main app.js/ index.js file as much as possible. I create a config folder with the main passport.js and then a strategies folder that has logic for how users will login.
in your main entry point file eg app.js
pull in passport's config passing app.
import express from 'express';
const app = express();
require('./src/config/passport')(app);
Your config file eg:passport.js should look like this
import passport from 'passport';
require('./strategies/local.strategy')(); //Or whatever strategy you are using
const passportConfig = (app) => {
app.use(passport.initialize());
app.use(passport.session());
// stores user to session
passport.serializeUser((user, done) => {
done(null, user);
});
// retrieves user from session
passport.deserializeUser((user, done) => {
done(null, user);
});
};
export default passportConfig;
Example local strategy aka custom strategy
import passport from 'passport';
import { Strategy } from 'passport-local';
import axios from 'axios';
const localStrategy = () => {
passport.use(new Strategy(
{
usernameField: 'userName',
passwordField: 'password',
},
(username, password, done) => {
const loginUrl = `${process.env.base_url}/api/core/security/login`;
const body = {
InstanceName: process.env.instance_name,
Username: username,
UserDomain: process.env.user_domain,
Password: password,
};
axios.post(loginUrl, body)
.then((response) => {
if (response.data.IsSuccessful === true) {
const user = {
token: response.data.RequestedObject.SessionToken,
userId: response.data.UserId,
userName: username,
};
done(null, user);
} else {
// handle failed login
}
})
.catch((error) =>
//Handle the error
}
))
}
export default localStrategy;
I ran into that issue:
I cannot get the access the session object in the request object inside the apollo server context, so I get undefined as output.
Otherwise I can access the session object in the request object inside express routes as normal.
How can I solve that?
import express, { Application, Request, Response } from 'express';
import bodyParser from "body-parser";
import helmet from "helmet";
import xss from 'xss';
import moment from "moment";
import passport from "passport";
import { connect } from "mongoose";
import "reflect-metadata";
import { ApolloServer } from 'apollo-server-express';
import { buildSchema, ResolverData } from "type-graphql";
// Import resolvers
import main_config from './main.config';
import AuthenticationRoutes from './Authentication/Authentication.routes';
import './Authentication/Authentication.strategies';
import {
topicResolver, docsResolver, courseResolver, articleResolver, projectIdeaResolver
} from './Graphql/Topics/Topics.resolvers';
import cookieSession from 'cookie-session';
import expressSession from 'express-session';
// const expGql = require("express-graphql");
const app : Application = express();
// Init cookie cookie-session
app.use(cookieSession({
keys : ["IDFVBHNIOVFFBUE"],
name : 'DBDIUN',
secret : "IDFVBHNIOVFFBUE"
}));
async function runapp (){
// Ïnit passport app and routes
app.use(passport.initialize());
app.use(passport.session())
// Run apollo server
const apollo = new ApolloServer({
schema : await buildSchema({
resolvers : [
topicResolver, docsResolver, courseResolver, articleResolver, projectIdeaResolver
],
globalMiddlewares: [],
}),
context: ({ req, res }) =>{
console.log("context")
console.log(req.session.passport) // cannot get session object then Get undefined
return {
getUser: () => req.user,
logout: () => req.logout(),
}
},
playground : true
})
apollo.applyMiddleware({ app });
// Init body parser and helmet
app.use(helmet());
app.use(bodyParser.json());
app.use('/auth', AuthenticationRoutes)
}
runapp();
Don´t deconstruct req work for me:
context: (req, res) => {
return {
req: req,
res: res,
}
};
how to import the user.json json file into my user.js ? when i type / user the json should be displayed? new version of node I don't understand
index.js
import express from 'express';
import bodyParser from 'body-parser';
import usersRoutes from './routes/users.js';
const app = express();
const PORT = 5000;
app.use(bodyParser.json());
app.use('/users', usersRoutes);
app.get('/', (req, res) => {
res.send('hello');
});
app.listen(PORT, () => console.log(`Server running on port: http://localhost:${PORT}`));
user.js
import express from 'express';
const router = express.Router();
router.get('/', (res, req) => {
res.send();
});
export default router;
import express from 'express';
import userJSON from '../user.json' // < ------- here
const router = express.Router();
router.get('/', (res, req) => {
res.send();
});
export default router;
Depending of the version you are using you either has to use babel or include the --experimental-json-modules flag for the module to work. ** node v.14 does not need anything.
node --experimental-json-modules about.js
import express from 'express';
import userfile from '../user.json' // import the json file
const router = express.Router();
router.get('/', (res, req) => {
res.send(userfile); //this line sends the json
});
export default router;
Instead use the fs module:
const user = require('fs').readFileSync('../user.json', 'utf-8');
You can do it by simply:
import express from 'express';
import user from '../user'; // <---- Don't need even the .json extension.
const router = express.Router();
router.get('/', (res, req) => {
res.send(user);
});
export default router;