I am trying to do my first API Rest and I am following some tutorials. I am requesting all the articles in a MongoDB database.
This is the code of the main:
var express = require("express"),
app = express(),
http = require("http"),
bodyParser = require("body-parser"),
methodOverride = require("method-override"),
server = http.createServer(app),
mongoose = require('mongoose');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(methodOverride());
// Import Models and controllers
var models = require('./models/article')(app, mongoose);
var articleCtrl = require('./controllers/articleController');
// Example Route
var router = express.Router();
router.get('/', function(req, res) {
res.send("Hello world!");
});
articles.route('/articles/:id')
.get(articleCtrl.findById);
articles.route('/articles')
.get(articleCtrl.findAllarticles)
.post(articleCtrl.addarticle);
app.use('/api', articles);
app.use(router);
mongoose.connect('mongodb://localhost/ustcg', { useNewUrlParser: true ,useUnifiedTopology: true}, function(err, res) {
if(err) {
console.log('ERROR: connecting to Database. ' + err);
}
app.listen(3000, function() {
console.log("Node server running on http://localhost:3000");
});
});
The code of the controller is here:
// Import article and mongoose
var mongoose = require('mongoose');
var Article = mongoose.model('Article');
//GET - Return a article with specified ID
exports.findById = function(req, res) {
Article.findById(req.params.id, function(err, Article) {
if(err) return res.send(500, err.message);
console.log('GET /article/' + req.params.id);
res.status(200).jsonp(Article);
});
};
//GET - Return all articles in the DB
exports.findAllarticles = function(req, res) {
Article.find(function(err, Article) {
if(err) res.send(500, err.message);
console.log('GET /article')
res.status(200).jsonp(Article);
});
};
//POST - Insert a new article in the DB
exports.addarticle = function(req, res) {
console.log('POST');
console.log(req.body);
var Article = new Article({
title: req.body.title,
paragraphs: req.body.paragraphs
});
Article.save(function(err, Article) {
if(err) return res.send(500, err.message);
res.status(200).jsonp(Article);
});
};
The model:
//We create the model
exports = module.exports = function(app, mongoose) {
var ArticleSchema = new mongoose.Schema({
title: { type: String },
paragraphs: { type: Array },
});
mongoose.model('Article', ArticleSchema);
};
When I tried to request the following http request it send me 404 error. I can not see any logs on the console so it is not entering the methods in order to see the exception is happening so I am stucked with this...
If someone could help me it would be nice.
what is articles variable in your main file.
I tried your code in my machine and struggled with articles variable and you have extra imports which are not required.
Try following code it works fine
var express = require("express");
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
var articleCtrl = require('./sample.controller');
var router = express.Router();
router.get('/', function(req, res) {
res.send("Hello world!");
});
router.get('/articles/:id', articleCtrl.findById);
router.post('/articles', articleCtrl.addarticle);
router.get('/articles', articleCtrl.findAllarticles)
// app.use('/api', router);
app.use(router);
app.listen(3000, function() {
console.log("Node server running on http://localhost:3000");
});
if you uncomment app.use('/api', router); then you can also use routes as localhost:3000/api/articles
Related
I am trying to wrap my head around defining and using an API in Express, using Mongoose to hook up with MongoDB. So far I am saving objects just fine form input on the front end. However, I seem to be lost when it comes down to retrieving and displaying the data I've saved.
Here is some code:
db.js:
const mongoose = require('mongoose');
//mongoose setup
mongoose.connect(mongooseUrl, { useNewUrlParser: true });
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
console.log('mongoose connected to ' + mongooseUrl);
});
module.exports = db;
app.js:
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
// import routers
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var apiRouter = require('./routes/api');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/api', apiRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
/routes/api.js:
var express = require('express');
var mongoose = require('mongoose');
var db = require('../config/db.js');
var Kitten = require('../models/kitten.js');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('api', {
title: 'Test API',
content: 'you\'re in the right place',
buttontext: 'send POST request'
});
});
router.post('/newKitten', function(req, res, next) {
var kitty = new Kitten({
name: req.body.name,
color: req.body.color
});
console.log("new kitty: " + kitty.name + " color: " + kitty.color );
kitty.save().then(console.log(kitty + " was saved to the database"));
res.send('new: ' + kitty);
});
router.get('/kittens', function (req, res, next) {
var kittens = Kitten.find({}, 'name color');
res.render('kittens', {title: 'Kittens', list_kittens: kittens });
});
module.exports = router;
models/kitten.js
const mongoose = require('mongoose');
var Schema = mongoose.Schema;
var kittenSchema = new Schema({
name: String,
color: String
});
var Kitten = mongoose.model("Kitten", kittenSchema);
module.exports = Kitten;
views/kitten.hbs:
<h1>{{title}}</h1>
<ul>
{{#each list_kittens as |kitten|}}
<li>name: {{kitten.name}}, color: {{kitten.color}}</li>
{{/each}}
</ul>
Now with all that laid out, when I visit http://localhost:3000/api/kittens this is what I see:
The kittens are stored in MongoDB, proof:
I have no idea why this is not rendering the kittens I have saved in my MongoDB database... The data is there, but I seem to be confused about how mongoose is supposed to be querying the data. Any and all help is appreciated. I've been stuck on this for a few days.
Model.find returns a promise. You have to add a function then to get the kittens and render them:
Kitten.find(...)
.then(kittens => {
res.render(...)
})
EDIT
Based on #Francisco Mateo comment, Kitten.find returns a Query you can execute with exec. Here is the code:
Kitten.find(...).exec()
.then(kittens => {
res.render(...)
})
In routes/api.js
var express = require('express');
var mongoose = require('mongoose');
var db = require('../config/db.js');
var Kitten = require('../models/kitten.js');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('api', {
title: 'Test API',
content: 'you\'re in the right place',
buttontext: 'send POST request'
});
});
router.post('/newKitten', function(req, res, next) {
var kitty = new Kitten({
name: req.body.name,
color: req.body.color
});
console.log("new kitty: " + kitty.name + " color: " + kitty.color );
kitty.save().then(console.log(kitty + " was saved to the database"));
res.send('new: ' + kitty);
});
router.get('/kittens', async function (req, res, next) { **//Change here**
var kittens = await Kitten.find({}, 'name color'); **//change here**
res.render('kittens', {title: 'Kittens', list_kittens: kittens });
});
module.exports = router;
The Kitten.find({}, 'name color') is returning a promise , so you have to wait until the data is returned.
I am making an app where the app is going to send the POST request data to the nodeJS server. The JSON format of the content looks like: {"encrypteddata": "someencryptedvalueofthetext"}. This data will be saved in a MongoDB.
I created two file one is app.js and another is /models/encdata.js. Content of both the file is given below.
app.js
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
app.use(bodyParser.json());
ENCDATA = require('./models/encdata');
mongoose.connect('mongodb://localhost/encdata', { useMongoClient: true }); // the url access the database
var db = mongoose.connection;
app.get('/', function(req, res){
res.send('Visit /api/encdata');
app.get('/api/encdata', function(req, res){
ENCDATA.getENCDATA(function(err, encdata){
if(err){
throw err;
}
res.json(encdata);
});
});
app.post('/api/encdata', function(req, res){
var encdata = req.body;
ENCDATA.addENCDATA(encdata, function(err, encdata){
if(err){
throw err;
}
res.json(encdata);
});
});
});
app.listen(3000);
console.log('Running on port 3000');
encdata.js
var mongoose = require('mongoose');
var encdataencryptSchema = mongoose.Schema({
encrypteddata: {
type: String,
required: true
}
});
var ENCDATA = module.exports = mongoose.model('encdata', encdataencryptSchema);
module.exports.getENCDATA = function(callback, limit){
ENCDATA.find(callback).limit(limit);
}
module.exports.addENCDATA = function(encdata, callback){
ENCDATA.create(encdata, callback);
}
And data in MongoDB is:
{"encrypteddata": "someencryptedvalueofthetext"}
But when I make a GET request to the url localhost:3000/api/encdata it shows [] (an empty array although I have data). Even the POST request is not working and I am not able to save any data.
I rewrote your code by changing the name of the variable and it worked for me. The app.js file looks something like this:
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var http = require('http');
app.use(bodyParser.json());
AES = require('./models/aes');
mongoose.connect('mongodb://localhost/aes', { useMongoClient: true }); // the url access the database
var db = mongoose.connection;
app.get('/', function(req, res){
res.send('Visit /api/aes');
app.get('/api/aes', function(req, res){
AES.getAES(function(err, aes){
if(err){
throw err;
}
res.json(aes);
});
});
app.post('/api/aes', function(req, res){
var aes = req.body;
AES.addAES(aes, function(err, aes){
if(err){
throw err;
}
res.json(aes);
});
});
});
app.listen(3000);
console.log('Running on port 3000');
In the encdata.js you can change the variable to AES. Name the mongodb collection and database as aes.
I'm trying to build a RESTful webservice following this tutorial:
https://www.codementor.io/olatundegaruba/nodejs-restful-apis-in-10-minutes-q0sgsfhbd
It's not working returning me a CANNOT GET/ reports error...
I'm trying to learn node.js and I can't find the error anywhere and everything I tried didn't work.
Also, when I call the server, it reaches to index.js which prints a "HEY". Wasn't this supposed to reach server.js first?
Here is my code:
Server.js
var express = require('express'),
app = express(),
port = process.env.PORT || 3000,
mongoose = require('mongoose'),
Report = require('./api/models/reportModel.js'),
bodyParser = require('body-parser');
mongoose.Promise = global.Promise;
mongoose.connect('mongodb://localhost/server');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
var routes = require('./api/routes/reportRoute.js');
routes(app);
app.listen(port);
console.log('Report RESTful API server started on: ' + port);
reportRoute.js
'use strict';
module.exports = function(app) {
var reports = require('../controllers/reportController.js');
// report Routes
app.route('/reports')
.get(reports.list_all_reports)
.post(reports.create_a_report);
app.route('/reports/:reportId').get(reports.read_a_report)
.put(reports.update_a_report)
.delete(reports.delete_a_report);
};
reportController.js
'use strict';
var mongoose = require('mongoose'),
Report = mongoose.model('Reports');
exports.list_all_reports = function(req, res) {
Report.find({}, function(err, report) {
if (err)
res.send(err);
res.json(report);
});
};
exports.create_a_report = function(req, res) {
var new_report = new Report(req.body);
new_report.save(function(err, report) {
if (err)
res.send(err);
res.json(report);
});
};
exports.read_a_report = function(req, res) {
Report.findById(req.params.reportId, function(err, report) {
if (err)
res.send(err);
res.json(report);
});
};
exports.update_a_report = function(req, report) {
Report.findOneAndUpdate({_id: req.params.taskId}, req.body, { new: true }, function(err, report) {
if (err)
res.send(err);
res.json(report);
});
};
exports.delete_a_report = function(req, res) {
Report.remove({
_id: req.params.reportId
}, function(err, report) {
if (err)
res.send(err);
res.json({ message: 'Report successfully deleted' });
});
};
Thank you for your help...
EDIT:
index.js
const express = require('express');
const app = express();
var route = require('./api/routes/reportRoute');
app.get('/', function(req, res) {
res.send('HEY!');
})
app.listen(3000, function(){console.log('Server running on port 3000')});
You haven't posted your reportController.js but this problem will occur if the function list_all_reports does not set a response body. For example, adding
res.json({hello: "world"});
to the handler function should make it work.
I have a couple of simple routes that I have misconfigured and not sure why.
app.js:
//app setup
var http = require('http');
var bodyParser = require('body-parser');
var express = require('express');
var routes = require('./routes');
var agent = require('./routes/agent');
var config = require('./config');
var app = express();
app.server = http.createServer(app);
app.use(bodyParser.json({
limit : config.bodyLimit
}));
app.use(bodyParser.urlencoded({
extended : true
}));
app.use('/v1', routes);
app.use('/v1/agent', agent);
app.server.listen(config.port);
console.log('API listening on port ' + app.server.address().port);
module.exports = app;
This returns responses on the /v1/ route (index.js):
'use strict';
var express = require('express');
var router = express.Router();
router.get('/', function (req, res) {
res.status(403).json({
message: 'Invalid request.'
});
});
module.exports = router;
in the agent route, I have a POST handler that is being handled correctly at /v1/agent/login. But while a GET routed at /v1/agent/ works, a GET routed to /v1/agent/123 returns a 404:
'use strict';
var agentController = require('../controller/agent.js');
var express = require('express');
var router = express.Router();
function handleError(objError, res) {
res.status(500).json({ errorMessage : objError.message });
}
router.get('/', function (req, res) {
res.status(200).json({
message: 'OK' // works fine
});
});
router.get('/:id'), function (req, res) {
var agentNum = req.params.id;
res.send(req.params); // 404 here
try {
//res.status(200).json({ message: 'hello agent.'});
} catch (err) {
// handleError(err, res);
}
};
router.post('/login', function (req, res) {
var agentNum, password;
// works fine
});
router.post('/pwr', function (req, res) {
//also works fine
});
module.exports = router;
My understanding is that the app.use method should redirect the route and any GET requests appended to that route to the one I specified (agent), so why is it that the one with params fails while the root one succeeds?
Thank you
You're not passing the callback correctly.
router.get('/:id')
router.get('/:id', function(req, res) {
var agentNum = req.params.id;
res.send(req.params); // 404 here
try {
//res.status(200).json({ message: 'hello agent.'});
} catch (err) {
// handleError(err, res);
}
});
I am learning node and express to create an api for an angular app I will be creating.
When I try and post something the req.body seems to be blank.
This is my server.js file
'use strict';
var express = require('express'),
app = express(),
mongoose = require('mongoose'),
router = require('./api'),
bodyParser = require('body-parser');
mongoose.connect('mongodb://localhost/my_db');
app.use(bodyParser.json());
app.use('/api', router);
app.get('/', function(req, res) {
res.render(__dirname + '/index.jade');
});
app.listen(3001, function() {
console.log('Listening on port 3001');
});
and this is my api/index.js file:
'use strict';
var express = require('express'),
Todo = require('../models/todo'),
router = express.Router();
router.get('/todos', function(req, res) {
Todo.find({}, function(err, todos) {
if(err) {
return console.log(err);
}
res.json({todos: todos});
});
});
router.post('/todos', function(req, res) {
var todo = req.body;
res.json({todo: todo});
});
module.exports = router;
when I use postman to post this to http://localhost:3001/api/todos:
{
'name': 'Walk the Dog',
'completed': false
}
my response is:
{
"todo": {}
}
I can't see why this would be blank, any help is appreciated.
UPDATE
Turns out I was posting text in postman instead of JSON.
use this in your server.js file
app.use(bodyParser.urlencoded({extended:true}));
app.use(bodyParser.json());