Node server without Express routing, how to use path parameters - node.js

I have to develop a web server without Express and I was wondering if there was any way to use the way Express routes for example the /path/:example, so I could access that with /path/test and the query variable example would be "test".
Currently I'm just using basic query parameters, /path?example=test, but I would like to be able to reduce it to the above.
Is that not possible unless it's in Express? I can't use any routing module.

Ok, so I stand by my comment that your client is making an ill-informed decision. Yes, it's possible to do routing w/o Express, but it will require a lot more custom code and doesn't provide extra value. Further, there are a LOT of really good tools in the same ecosystem (e.g. helmet) that make your apps better, easier to build and maintain, and more secure.
That said, if the client is set on this path of madness and you don't want to "fire" your customer, here's the guts of what you have to do:
const http = require('http');
const url = require('url');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
const requestUrl = url.parse(req.url);
const path = requestUrl.pathname;
const parts = path.split('/').slice(1);
// This is really brittle, but assuming you know it's going to be 2 parts remaining after the above..
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end(parts[1]);
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
Now, that's the basics. Obviously, if you want to essentially re-do the routing Express provides, you'll want to add in a lot more logic to handle parsing the string the way you want to and assigning route handlers and all that stuff. Sorry, it's not easy, but that's why so many folks use Express (or Connect, or other routing modules).
Some other things that might make this easier for you... Express is open source, so read their source code and see how they're doing what you need done, then implement it yourself. I'm not saying copy it verbatim (if you do that, you might as well just use their module...), but get inspiration.
For example, there's a utility they use called path-to-regexp that converts the '/path/:example' string into a regex that can be used to test an incoming URL. Reading that source code might help you understand what they're doing better.

Related

Access Previously-Defined Middleware

Is there a way to access or delete middleware in connect or express that you already defined on the same instance? I have noticed that under koa you can do this, but we are not going to use koa yet because it is so new, so I am trying to do the same thing in express. I also noticed that it is possible with connect, with somewhat more complicated output, but connect does not have all the features I want, even with middleware.
var express = require('express');
var connect = require('connect');
var koa = require('koa');
var server1 = express();
var server2 = connect();
var server3 = koa();
server1.use(function express(req, res, next) {
console.log('Hello from express!');
});
server2.use(function connect(req, res, next) {
console.log('Hello from connect!');
});
server3.use(function* koa(next) {
console.log('Hello from koa!');
});
console.log(server1.middleware);
// logs 'undefined'
console.log(server2.middleware);
// logs 'undefined'
console.log(server2.stack);
logs [ { route: '', handle: [Function: connect] } ]
console.log(server3.middleware);
// logs [ [Function: koa] ]
koa's docs say that it added some sugar to its middleware, but never explicitly mentions any sugar, and in particular does not mention this behavior.
So is this possible in express? If it is not possible with the vanilla version, how hard would it be to implement? I would like to avoid modifying the library itself. Also, what are the drawbacks for doing this, in any of the 3 libraries?
EDIT:
My use case is that I am essentially re-engineering gulp-webserver, with some improvements, as that plugin, and all others like it, are blacklisted. gulp is a task runner, that has the concept of "file objects", and it is possible to access their contents and path, so I basically want to serve each file statically when the user goes to a corresponding URL in the browser. The trouble is watching, as I need to ensure that the user gets the new file, and not the old version. If I just add an app.use each time, the server would see the file as it is originally, and never get to the middleware with the new version.
I don't want to restart the server every time a file changes, though I will if I can find no better way, so it seems I need to either modify the original middleware on the fly (not a good idea), delete it, or add it to the beginning instead of the end. Either way, I first need to know where it "lives".
You might be able to find what your looking for in server1._router.stack, but it's not clear what exactly you're trying to do (what do you mean "access"?).
In any case, it's not a good idea to do any of these, since that relies strictly on implementation, and not on specification / API. As a result any and all assumptions made regarding the inner implementation of a library is eventually bound to break. You will eventually have to either rewrite your code (and "reverse engineer" the library again to do so), or lock yourself to a specific library version which will result in stale code, with potential bugs and vulnerabilities and no new features / improvements.

In Node.js is it possible to use parts of Connect with standard node HTTP server?

I have a node.js app which i need to add more complexity to at this point. Connects middleware is perfect for what I want to do and cleaner than "if else" logic BUT i dont want the level of abstraction Connect provides from a server perspective (i want very low level granular control over http headers and http response logic). So my question is can i use Connects middleware next() type functionality within a standard
http.createServer(function (req, res) {}).listen(port)
type block?
hope this makes sense. any simple example code would be great.
thx
Ok, so I guess I was looking at this the wrong way.
I can wrap my existing code inside a Connect server pretty easily and still use the http interface. i.e.
var connect = require('connect');
var http = require('http');
var app = connect()
app.use( function myMiddleWare(req, res, next ){
// my preexisting Node HTTP interface code.
//obviously I can use modules to make this cleaner
next();
});
var server = app.listen(port);

How to host multiple node.js apps on the same subdomain with Heroku?

We have a base domain of http://api.mysite.com. This should serve as the front door for all our APIs. Let's say we have two different APIs accessed with the following url structure:
http://api.mysite.com/launchrockets
http://api.mysite.com/planttrees
These are totally different. With regards running this on Heroku it seems we have two options.
1) Put everything inside one application on Heroku. This feels wrong (very wrong) and could lead to a higher chance of changes in one API inadvertently breaking the other.
2) Have 3 different Heroku apps. The first as a proxy (http://mysite-api-proxy.herokuapp.com) that will look at the incoming request and redirect to http://planttrees.herokuapp.com or http://launchrockets.herokuapp.com using a module like bouncy or http-proxy.
I'm leaning towards option 2 but I am concerned about managing the load on the proxy app. For web frameworks that have a synchronous architecture this approach would be disastrous. Yet with node.js using the cluster module and being asynchronous I think this may scale okay.
I've seen similar questions asked before but most related to synchronous frameworks where option 2 would definitely be a poor choice. This question is specific to node and how it would perform.
Thoughts on best way to architect this?
I implemented simple demo project to achieve multi-app structure.
https://github.com/hitokun-s/node-express-multiapp-demo
With this structure, you can easily set up and maintain each app independently.
I hope this would be a help for you.
Here is a blog post I wrote trying to answer this question. There are many options but you have decide what is right for your app and architecture.
http://www.tehnrd.com/host-multiple-node-js-apps-on-the-same-subdomain-with-heroku/
Similar to #TehNrd, I'm using a proxy. However this approach doesn't require multiple heroku apps, just one:
On your web app:
var express = require('express')
, url = require('url')
, api_app = require('../api/server') //this is your other apps index.js or server.js
, app = express()
, httpProxy = require('http-proxy')
, apiport = parseInt(process.env.PORT)+100 || 5100 //this works!
;
// passes all api requests through the proxy
app.all('/api*', function (req, res, next) {
api_proxy.web(req, res, {
target: 'http://localhost:' + apiport
});
});
On your API server:
var express = require('express');
var app = express();
var port = parseInt(process.env.PORT)+100 || 5100;
...
...
app.listen(port);

What does Express.js do in the MEAN stack?

I have recently have gotten into AngularJS and I love it. For an upcoming project I am looking to use the MEAN stack (MongoDB, Express, Angular, Node). I'm pretty familiar with Angular and I have a modest understanding of the purposes of MongoDB and Node in the stack. However, I don't really understand what the purpose of Express.js is. Is it essential to the MEAN stack? What would you compare it to in a traditional MySQL, PHP, javascript app? What does it do that the other three components can't do?
Also, if someone wants to give their own take on how the four parts of the stack work together, that'd be great.
MongoDB = database
Express.js = back-end web framework
Angular = front-end framework
Node = back-end platform / web framework
Basically, what Express does is that it enables you to easily create web applications by providing a slightly simpler interface for creating your request endpoints, handling cookies, etc. than vanilla Node. You could drop it out of the equation, but then you'd have to do a lot more work in whipping up your web-application. Node itself could do everything express is doing (express is implemented with node), but express just wraps it up in a nicer package.
I would compare Express to some PHP web framework in the stack you describe, something like slim.
You can think of Express as a utility belt for creating web applications with Node.js. It provides functions for pretty much everything you need to do to build a web server. If you were to write the same functionality with vanilla Node.js, you would have to write significantly more code. Here are a couple examples of what Express does:
REST routes are made simple with things like
app.get('/user/:id', function(req, res){ /* req.params('id') is avail */ });
A middleware system that allows you plug in different synchronous functions that do different things with a request or response, ie. authentication or adding properties
app.use(function(req,res,next){ req.timestamp = new Date(); next(); });
Functions for parsing the body of POST requests
Cross site scripting prevention tools
Automatic HTTP header handling
app.get('/', function(req,res){ res.json({object: 'something'}); });
Generally speaking, Sinatra is to Ruby as Express is to Node.js. I know it's not a PHP example, but I don't know much about PHP frameworks.
Express handles things like cookies, parsing the request body, forming the response and handling routes.
It also is the part of the application that listens to a socket to handle incoming requests.
A simple example from express github
var express = require('express');
var app = express();
app.get('/', function(req, res){
res.send('Hello World');
});
app.listen(3000);
Shows the creation of the express server, creating a route app.get('/'... and opening the port to listen for incoming http requests on.
Express allows you to manage http request easily compared to vanilla js.
you need to the following to make a get request
const Http = new XMLHttpRequest();
const url='https://jsonplaceholder.typicode.com/posts';
Http.open("GET", url);
Http.send();
Http.onreadystatechange=(e)=>{
console.log(Http.responseText)
}
In express, you require express and use it and make http requests
const express = require("express")
const app =express();
app.get("url",callback function);
Express in a Node.js based framework which simplifies writing Server-side Code and Logic.
Adds a lot of utility features and offers additional functionality, and in general, makes things easier.
Express is middleware-based : It basically funnels incoming requests through a chain of middlewares (of steps) where we can do something with the request, read some data from it, manipulate it, check if the user is authenticated or basically send back a response immediately.
This middlewares chain allows us to write very structured code
Express is a nodejs Framework build upon the top of Http module with more usable and better functionalities like easy way to handle routes.
eg: Using HTTP
var http = require('http');
//create a server object:
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/html'}); // http header
var url = req.url;
if(url ==='/about'){
res.write('<h1>about us page<h1>'); //write a response
res.end(); //end the response
}else if(url ==='/contact'){
res.write('<h1>contact us page<h1>'); //write a response
res.end(); //end the response
}else{
res.write('<h1>Hello World!<h1>'); //write a response
res.end(); //end the response
}
}).listen(3000, function(){
console.log("server start at port 3000"); //the server object listens on port 3000
});
using Express:
var express = require('express');
var app = express();
app.get('/about',function(req,res)=>{
res.write('<h1>about us page<h1>'); //write a response
res.end();
})

Capture and log the api calls made to the server along with the passed data and the results

I have an api written in node.js that handles calls coming in from websites, desktop applications, iOS applications etc. There are probably 50+ endpoints and each end point can accept anywhere from 1 parameter to possibly 10-20 depending on what is intendeding to be accomplished. These can be GET/POST/PUT/DEL
I want to start load testing my API and simulating users activities.
What I am looking for is suggestions on how you can capture the API call and the parameters that were passed along with it in a logical way.
I use forever to run my app and everything is written to a log file so my initial reaction was to do something like add a piece of middleware to the express routes that would capture the endpoint as well as the req.params and req.body but then I need to put this middleware in all 50+ routes kind of tedious.
Anyone done something like this before and has a good idea on how to capture calls / data with those calls as well as possibly capturing what is returned from my API.
Perhaps some module?
I need to have this in a readable format to provide to other people so they can structure a fake set of calls... so raw log files aren't really helpful unless they are outputted.... "pretty".
Thanks!
You're on the right track – just add your logger middleware via app.use, which runs the middleware on every request (rather than adding it to each route).
In fact, the Express docs give an example of using logger middleware:
var express = require('express');
var app = express();
// simple logger
app.use(function(req, res, next){
console.log('%s %s', req.method, req.url);
next();
});
Connect (on which Express is built) provides logger middleware, so you can just do:
var logFile = fs.createWriteStream('./myLogFile.log', {flags: 'a'});
app.use(express.logger({stream: logFile}));

Resources