Express & Socket.io Route parroting/copying/sharing - node.js

I'm working with expressjs and socket.io in nodejs. I'm looking into assign identical route handlers to requests made in either HTTP or via websockets/socket.io.
For instance:
var responder = function(req, res){
req.params //<-- {id: 'something...'}
}
app.get('/foo/:id', responder);
io.on('/foo/:id', responder);
socket.io doesn't appear to have this type of routing functionality. Does anyone know of a library/module to help with this?

There are several options.
If you'd like to keep using express, check out express.io.
If you don't mind using something a bit different, sails lets you do this sort of thing as well.
(Update: sails now uses express too)
Both have been used in production successfully.
Note that routing is also pretty simple to implement on your own. If you check out how express do it I'm sure you'll be able to figure out a slim implementation that would match you needs.
Good luck! Let me know what you ended up using and how it worked for you.

Related

fastify-swagger is not picking up my dynamic routes

I've been a fan of ExpressJs for a long time but in a Youtube video I stumble upon Fastify and wanted to give it a try
I'm struggling in making the fastify-swagger plugin work as I assume it should work - dynamic setup to pick up the schema from each route, but I'm certainly missing something 😔
here's my test repo that after running, none of my routes appear
my setup for the plugin is the default one
but all I see is
I've read in the read me that because of OpenAPI specs, some properties, like description are mandatory or will not pick up the route, but I've added in one route, and still does not pick up, I've also added tags wondering if that was also mandatory, but nothing...
does anyone know what am I missing? must be a simple thing, but got me puzzled this last few days 😔
I ran into the same issue and ended up solving it by following the first Usage example line-by-line: https://github.com/fastify/fastify-swagger#usage
const fastify = require('fastify')()
(async () => {
// set up swagger
await fastify.register(require('#fastify/swagger'), {
...swagger config
});
// define all your routes
// then call these
await fastify.ready()
fastify.swagger()
})();
Consider the order in which your plugins are loaded, the routes need to be registered before fastify swagger. If fastify swagger comes first, it doesn't detect any route.
I encountered this issue in my project. In my case, I solved it using fastify-plugin. Looking at the source code for fastify-swagger, it seems to rely on a hook listening for onRoute events to detect routes. I'm thinking maybe encapsulation can interfere with the plugin's ability to receive the events.

How does Koa help avoid "monkey patching" and how "Hapi" or "Express" don't do the same?

I have hard times understanding why people preach Koa as solving the "monkey patching" problem (whereas one needs to modify prepackaged code). (see https://www.quora.com/Should-I-learn-Express-js-or-Koa-js-for-node/answer/Yvan-Scher?share=1 or http://blog.onclickinnovations.com/koa-js/).
How is Koa special in that regards? How isn't Hapi or Express the same in that regards?
Having done Koa for 2 years, and some express.js recently, I ran into 1 big example of this.
Say you have a controller that emits a response, and you want to intercept that response and do something with it (e.g.: gzip it, or convert it to some other format).
This works easily natively with koa because you can just do something like this:
function myMw(ctx, next) {
await next();
ctx.response.body = gzip(ctx.response.body);
}
The above is a fictional example, but you get the idea.
With express your code for this looks like absolute garbage. Easy to see in the express gzip middleware:
https://github.com/expressjs/compression/blob/master/index.js
This has to do with the fact that express middlewares provide direct access to the HTTP socket for writing responses (with send()).
I'm suspecting this is where this sentiment comes from. Frankly I don't understand why people still use Express. Mostly habitual and the vast amounts of tutorials I reckon. Express was great, but it's painful today.

I am using loopback to scaffold an application, can I still write my code as an express application instead of using some of their components?

I have used loopback to scaffold out my application but want to use some of their components, their documentation is lacking, can I just enable the functionality I want like I would using just express?
Specifically, I want to implement OAuth2
The loopback object is directly the express object (with all the loopback sweet additions of course). You can obtain this object by requiring the server.js file scaffolded in your application.
So you can do everything express does with it, like routing for instance
var app = require('server.js').
app.get('/', function (req, res) {
res.send('Hello World!');
});
Implementing OAuth2 is absolutely possible (done it myself, without using oauth loopback plugin), nothing preventing it, but it's not exactly straightforward. I would advise to spend some time getting familiar with loopback and building a few small applications first.

How can I test (integration-testing) with supertest a Node.js server with Passport JS using facebook/google... strategies with OAUTH2?

I have a Node Js application and I'm integration-testing my app with supertest/superagent + nockjs.
I have a problem, because I want to test my login rest apis using supertest to REPLY with a FAKE PROFILE RESPONSE + token for example for facebook/google/github and so on. (I'm not interested in LocalStrategy, because it' very simple)
How can I do that?
I'm trying with GitHub, and I wrote this code (not working) absolutely wrong, probably very stupid without any sense...It was an experiment XD.
nock('https://github.com/login/oauth')
.get('/authorize?response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fapi%2Fauth%2Fgithub%2Fcallback&scope=user%3Aemail&client_id=XXXXXXXXXXXXXXXXXXXX')
.reply(302,undefined,
{
location : "http://localhost:3000/api/auth/github/callback?code=ab7f9823f03071209b26"
}
)
.get('http://localhost:3000/api/auth/github/callback?code=ab7f9823f03071209b26')
.reply(200, responseMocked);
PS: probably I made a mistake with url and status, I don't know.
Also, where I should set the connection.sid's cookie ?
How can I fix/rewrite this code to be able to integration-testing my application?
I'm also interested to use passportjs stub/mock, but I want a library supported and well documented.
UPDATE: I fixed the name of the mocked profile object (responseMocked)
Thank you,
Stefano.

Sails.js: best way to package DB and surrounding API models as module

I'm new to Sails, but have used Express, and am considering Sails for my upcoming project. I particularly like that it makes the CRUD API for me and connects Socket.io automatically.
The next application I'm planning to work on has an indeterminate size; if it works well, we want to separate our CRUD/JSON API from our Web/HTTP server and load balance the Web/HTTP server. This would allow us to utilize the CRUD/JSON API in other adjacent applications, like code for statistical analysis, or external data parsers which import data, or other things which have nothing to do with Web/HTTP servicing.
In express I would consider making the API section a module then export the express.router with all the api calls like so
//appAPI.js
var routes = require('express').router();
routes.get('/user/:id', function(request, reply){
// assume db is connected database object
// and request.params.id is as expected
db.getUser(request.params.id, function(u){
reply.json(u);
});
})
module.exports = routes;
//app.js
var app = require('express')(),
api = require('appAPI');
app.use('/api', api);
Then in my application, if I want to separate the Web from the API, I can package up the appAPI.js, and associated model code, and make a small connector to redirect all routes /api/* to the ip address and port of the api server, or other possibilities.
Can I do something like this in Sails? It seems that the automated model creation and the socket.io automation would make this difficult. Alternatively, I might be able to make a module for the API with a whole sails server then embed it in the main Web/HTTP server, which has its own sails objects running, but this seems like it either would not work, break the socket.io connections, or work, but be horribly inefficient as it would have multiple instances of sails running.
Any recommendations would be helpful and I'm willing to consider alternative ways of working this. Thank you all for any help you might provide and have a wonderful day.

Resources