Consider the following code from an express app:
var express = require('express');
var router = express.Router();
var standupCtrl = require('../controllers/standup.server.controller');
/* GET home page. */
router.get('/', function(req, res) {
return standupCtrl.list(req, res);
});
/* POST filter by member name - home page. */
router.post('/', function(req, res) {
return standupCtrl.filterByMember(req, res);
});
// ............ more code here
module.exports = router;
exports.list = function(req, res) {
var query = Standup.find();
query.sort({ createdOn: 'desc'}).limit(12).exec(function(err, results){
res.render('index', {title: 'Standup - List', notes: results});
});
};
exports.filterByMember = function(req, res) {
var query = Standup.find();
var filter = req.body.memberName;
query.sort({ createdOn: 'desc' });
if (filter.length > 0)
{
query.where({ memberName: filter})
}
query.exec(function(err, results) {
res.render('index', { title: 'Standup - List', notes: results });
});
};
I know that when submitting a form you can specify a
method = get/post
For this scenario (where nothing such has been specified) , how does the server know which to trigger (post or get) when user navigates to '/' (e.g. Homepage)?
More generally, My question is:
What events trigger a Post/Get action (if not explicitly specified) ?
(PS: I know typing anything in the address bar of a browser triggers a GET request)
Thanks a lot in advance!
HTTP GET is pretty much the default everywhere if you don't specify otherwise.
Most POSTs are the result of either a form submit or an explicit call via AJAX or as a web service call (like RPC from another server). You CAN handcraft POST requests using programs like curl, but again that would be rare. In every toolkit I've seen, it's GET by default.
And rarely (VERY), you might find some RPC provider (such as an IoT or other embedded device) that only speaks POSTs (to save on code space).
Related
I have a general question on how you handle services and routes in node.js. Would you handle the response directly in the service or would you leave that to the route? Here's what i mean in code
Like this
Route
router.get('/', (req, res, next) ==> {
someService.someMethod(req, res);
});
Service
const someMethod = (req, res) => {
try {
var something = await someOtherMethod(req.body.someParameter);
return res.status(200).send(something.data);
} catch (err) {
return res.status(500).send({msg: err.message});
}
}
Or this
Router
router.get('/', (req, res, next) ==> {
try {
var something = await someService.someMethod(req.body.someParameter);
res.status(200).send(something.data);
} catch (err) {
res.status(500).send({msg: err.message})
}
});
Service
const SomeMethod = (Input) => {
return someOtherMethod(Input);
}
The first way would make the routers much simpler and cleaner especially if the use the service in multiple routes, but on the downside I always need to supply the res and req and I will run into problems if I want to use the service internally. I'm tending to the second method.
How do you design your services?
I would go for router.get('/', RootController)
const RootController = (req, res) => {
// extract what you need from the request
const param = req.body.param;
// calculate what you need in a pure function `businessLogic`
const result = businessLogic(param);
// send the response
return res.send(result);
}
This way you get a separation of concerns - your root controller is responsible only for handling / requests - getting a response for a request. All "business logic" is done in a pure function (you can easily test it without any HTTP request contexts/mocks, it can be reused somewhere else, for example in different controller).
I use the following architecture:
1. Route
2. Controller
3. Services
Your route is the one validating the input, your controller is the one handling all the logics and calling the services and returning the final result to your route.
I have two servers
http://127.0.0.1:7777/
http://127.0.0.1:7778/
I'm trying to link the actions of these two servers.
For example, when I click on server 7778 I create a folder and put an action that detects the file create
var fs = require('fs');
if (fs.existsSync('/home/diegonode/Desktop/ExpressCart-master/New')) {
console.log("hello");
}
but I use an app like this and this command only works when it is included in router get
How can I link the actions of these two servers?
var express = require('express');
var router = express.Router();
var common = require('./common');
// The homepage of the site
router.get('/', function(req, res, next) {
var number_products = req.config.get('application').number_products_index ? req.config.get('application').number_products_index : 8;
req.db.products.find({ product_published: { $in: [ 'true' , 'true2'] }, }).limit(3).exec(function (err, results) {
res.render('index', {
title: 'Shop',
results: results,
session: req.session,
message: clear_session_value(req.session, "message"),
message_type: clear_session_value(req.session, "message_type"),
config: req.config.get('application'),
helpers: req.handlebars.helpers,
page_url: req.config.get('application').base_url,
show_footer: "show_footer"
});
});
});
please help me
I REFER how I can click action (or another type of action) of one server and detect this click in another server
I refer use router get from another server, not from the actual server and get I do a some action
router.get( ('http://127.0.0.1:7778/data '),
I am not really sure what to title this, but I'm new to Node.js. I just found a neat REST API project on GitHub to implement but I'm not sure how I can split all GET and POST etc. to separate files.
I have one singular api.js file where I have
function API_ROUTER(router, connection, md5) {
var self = this;
self.handleRoutes(router, connection, md5);
}
API_ROUTER.prototype.handleRoutes = function(router, connection, md5) {
router.get("/", function(req, res) {
res.json({"Message" : "Hello World !"});
});
};
module.exports = API_ROUTER;
Now how can I create a sibling other.js and use:
var api = require('./api.js');
// Create router.get, router.post etc. here?
but I'm not sure how I can split all GET and POST etc. to separate files.
One way you can organize your routes would be to have a separate object for each route that has the handlers (separated by HTTP methods) and other needed info such as the path:
api/home.js
module.exports = {
path: '/',
handlers: {
'get': function(req, res) {
res.json({"Message" : "Hello World !"});
},
'post': {
// ...
}
// ...
}
}
api/other.js
module.exports = {
path: '/other',
handlers: {
'get': function(req, res) {
res.json({"Message" : "Other !"});
},
// ...
Then you can load all of these inside the handleRoutes method:
API_ROUTER.prototype.handleRoutes = function(router, connection, md5) {
var routes = ['home', 'other'];
routes.forEach(function(name) {
// load the current route object (NOTE: you should use the path module for determining file path in a cross-platform manner)
var routeObject = require('./' + name + '.js');
var apiPath = routeObject.path;
var handlers = routeObject.handlers;
var methods = Object.keys(handlers);
// assign handlers for each method
methods.forEach(function(method) {
router[method](apiPath, handlers[method]);
});
});
};
This will install all your routes with the appropriate information and handlers.
Now you can call this code by instantiating your API_ROUTER with the necessary data:
// initialize the api (and handle the routes internally)
var Api = new require('./api.js')(router, connection, md5);
If you implement a RESTful API, then you should keep in mind that this is just one way how you can provide data, and you might want to change it in future, as of that the API will most of the time only be a translation layer.
Normally you will split your code based on the resources, and the code that is handling the request won't have so much logic, it will just take the request and pass it to you internal API. For that purpose you not really need an additional layer if you already use express.js or a similar library.
In express the app.use([path,] function [, function...]), already provides the functionality you would need to modularize your code. For each resource your will create an own express.Router that itself also might mount another sub module. So for this part you do not really need a library.
When might a library be useful:
if it automatically translates thrown errors to the correct response codes
if it includes a tool to automatically create a documentation to your API
if it fully abstracts the underlaying routing system so that you can hook into express, hapi, ... without the need to change the code.
Here how a setup with express.js could look like
./lib/rest/customer.js
var customerSystem = require('../customer-system');
var express = require('express');
var router = new express.Router();
router.get('/:id', function(req, res, next) {
customerSystem.find({
id: req.params.id
}, function(err, customer) {
if (err) {
res.status( /*correct status code*/ ).send( /*depending on the api return json, xml, ....*/ )
} else {
res.send( /*depending on the api return json, xml, ....*/ )
}
})
});
router.delete('/:id', function(req, res, next) {
customerSystem.delete({
id: req.params.id
}, function(err) {
//...
});
});
router.post('/', function(req, res, next) {
//...
});
//save the customer id for the pass to the sub routers
router.use('/:id', function(req, res, next) {
req.customerId = req.params.id;
next();
});
router.use('/:id/addresses', require('./customer-address') )
module.exports = router;
./lib/rest/customer-address.js
var customerSystem = require('../customer-system');
var express = require('express');
var router = new express.Router();
router.get('/:id', function(req, res, next) {
customerSystem.find({
id: req.customerId
}, function(err, customer) {
// ...
})
});
/* ..... */
//save the address id for the pass to the sub routers
router.use('/:id', function(req, res, next) {
req.addressId = req.params.id;
next();
});
router.use('/:id/addresses', require('./customer-address') )
module.exports = router;
I found Difference between put and patch. I kind of understand teh difference after reading. It's still hazy.
My question is:
Why does Yeoman generator: angular fullstack use
router.put('/:id', controller.update);
AND
router.patch('/:id', controller.update);
In there index.js files of their server.collections?
What's the purpose of having both? Moreover, How would I use one vs the other?
'use strict';
var express = require('express');
var controller = require('./thing.controller');
var router = express.Router();
router.get('/', controller.index);
router.get('/:id', controller.show);
router.post('/', controller.create);
router.put('/:id', controller.update);
router.patch('/:id', controller.update);
router.delete('/:id', controller.destroy);
module.exports = router;
server controller
// Updates an existing thing in the DB.
exports.update = function(req, res) {
if(req.body._id) { delete req.body._id; }
Thing.findById(req.params.id, function (err, thing) {
if (err) { return handleError(res, err); }
if(!thing) { return res.send(404); }
var updated = _.merge(thing, req.body);
updated.save(function (err) {
if (err) { return handleError(res, err); }
return res.json(200, thing);
});
});
};
They are just different http verbs. Reading https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods
PUT
Requests that the enclosed entity be stored under the supplied URI. If the URI refers
to an already existing resource, it is modified; if the URI does not point to an existing
resource, then the server can create the resource with that URI.[15]
PATCH
Applies partial modifications to a resource.[18]
They should'n be the same!
But I see no difference on both methods on angular-fullstack and for me it is wrong!
PUT - update the entire entity, this means you need to send EVERY
single property of the item otherwise they will be erased.
PATCH - partial update, you may send only the fields you want to
change and the others will be kept on the server.
e.g:
Imagine the following entity:
car: {
color: red,
year: 2000
}
Now imagine you send a patch like this:
{color: blue}
The entity is now like this:
car: {
color: blue, // CHANGED
year: 2000
}
But instead if you sent a put the entity should like this:
car: {
color: blue // CHANGED
year: null // May be null, undefined, removed, etc...
}
I have a route like this -
server.get({
url : '/reguser/:useremail',
name : 'pre-register-user'
}, function(req, res, next) {
return next();
}, function sendResult(req, res, next) {
var user = { 'email' : req.params.useremail }
// Create a new user on the DB
res.contentType = 'application/json';
// rest of the processing.
}
Works if it gets called with /prereg/someone%40someemail.com. But if it gets /prereg/someone#someemail.com it does not process at all. I am using Nginx in the front and rewrite in it replaces the %40 with # even though the web-page is sending urlencoded string with %40.
Any way out of this?