Using express middleware in koa - node.js

I have existing code which implements an express middleware. How can I use this middleware in a Koa application?
When I try to call app.use(expressMiddleware) in order to use the middleware in my Koa app, Koa complains that a generator function is required:
AssertionError: app.use() requires a generator function
So I guess that some kind of adapter or trick is needed here... ideas?

Also, you can try koa-connect: https://github.com/vkurchatkin/koa-connect
It looks quite straightforward:
var koa = require('koa');
var c2k = require('koa-connect');
var app = koa();
function middleware (req, res, next) {
console.log('connect');
next();
}
app.use(c2k(middleware));
app.use(function * () {
this.body = 'koa';
});
app.listen(3000);

koa is incompatible with express middleware. (see this blog post for a detailed explaination, especially the part 'Better written middleware').
You could rewrite you middleware for koa. The koa wiki has a special guide for writing middleware.
The req and res that you would receive in an express middleware are not directly available in koa middleware. But you have access to the koa request and the koa response objects via this.request and this.response.

I have create koa2-connect on npm for koa2. https://github.com/cyrilluce/koa2-connect
npm i koa2-connect -S
// usage same as koa-connect
Because koa-connect's author haven't publish next version( npm i koa-connect#next didn't work ), and it is not compatible with webpack-dev-middleware and webpack-hot-middleware.

Related

How to use Express middleware after Apollo-Server v2 middleware?

I'm having this weird requirement(because I got nothing on the internet on how to use it. So, I guess it's only me) while using Express and Apollo Server.
I want to use an Express middleware after using the Apollo Server middleware but I can't.
Example:
const { ApolloServer } = require('apollo-server-express');
const express = require('express')
const app = express();
const server = new ApolloServer({typedefs, resolvers})
app.use(...); // Middleware-1
app.use(...); // Middleware-2
app.use(server.getMiddleware()); // Apollo server middleware
app.use(...); // Middleware-3
app.listen({ port: 4000 }, () =>
console.log(`🚀 Server ready at http://localhost:4000${server.graphqlPath}`)
);
In the above code, the Middleware-3 is never being called. I've searched a lot about that but I got nothing.
Is there any way to invoke Middleware-3 after Apollo Server Middleware?
Thank you.
Edit:1
I forgot to mention that I don't want to modify the response from the ApolloServer. I already have some Express middlewares which I don't want to refactor/modify/write completely new ones to be able to use along with Apollo. So, is there any hacky way to follow the app.use() order even after ApolloServer middleware?
You can try to assign
res.end2 = res.end
res.end = ()=>{}
in any middleware called before ApolloMidleware and then call res.end2 to the send response
Apollo Server calls res.end after sending the execution results of your GraphQL request. This finalizes the response, so no other middleware will be called afterward.
If you need to format the response, you can utilize the formatResponse or formatErrors options, but you cannot use Express middleware.

Express: how can I get the app from the router?

I know I can get the Express app from inside an individual route with:
req.app
However I need to start a single instance of a module inside routes/index.js, i.e.:
var myModule = require('my-module')(propertyOfApp)
How can I get the express app from the router?
It really depends on your own implementation, but what I suggested in the comments should be working:
// index.js
module.exports = function(app) {
// can use app here
// somehow create your router and do the magic, configure it as you wish
router.get('/path', function (req, res, next) {});
return router;
}
// app.js
// actually call the function that is returned by require,
// and when executed, the function will return your configured router
app.use(require('./index')(app));
p.s.
Of course this is just a sample - you can configure your router with path, and all kind of properties you wish. Cheers! :)

Node.js Express middleware: app.param vs app.use

In the chain of calls inside Express middleware, do the app.param methods always get called before app.use?
I tested with this program changing the order of app.use vs app.param with express 4.10.2. The param always runs first, which makes sense because the route handler expects to be able to do req.params.foo and in order for that to work the param handlers need to have run.
var express = require('express');
var app = express();
app.use("/:file", function (req, res) {
console.log("#bug route", req.params.file);
res.send();
});
app.param("file", function (req, res, next, val) {
console.log("#bug param", val);
next();
});
app.listen(3003);
Run this and test with curl localhost:3003/foo and you get the output:
#bug param foo
#bug route foo
You can test it through logging, but I'm reasonably certain that in 4.0, everything is called in the order it's declared when you set up your app.

how to bypass/avoid crsf on API post?

In a node application with ExpressJS we have CRSF middleware enabled.
This works great, however we have some routes starting with /api and accepting POST request which fail (forbidden) because there is no CRSF token of course.
How can we bypass/avoid CRSF for /api posts?
You can conditionally pass inside of middleware, so one option is to look to a pattern like this:
function yourMiddleware(req, res, next) {
if ( null !== req.path.match(/^\/api/) ) {
next();
}
//your CRSF behavior here
}
What about registering those routes before the CSRF middleware? Like:
var express = require('express');
var app = express();
app.use(express.bodyParser());
app.use(express.cookieParser('your-secret'));
app.use(express.session());
app.use('/api', require('path to your module that does not need csrf'));
app.use(express.csrf());
app.use('/othermount', require('path to your module that needs csrf'));
Edit: Expanded code example to clarify what I was thinking.

Mount Koajs app on top of Express

From koajs.com:
app.callback()
Return a callback function suitable for the http.createServer() method to handle a request. You may also use this callback function to mount your koa app in a Connect/Express app.
Now I have an Express app that already starts its own http server. How can I mount a koa app on top of this existing server, so that it shares the same port?
Would I include the koa app as an Express middlware? Do I still use app.callback() for that?
expressapp.use(koaapp.callback()) is fine. but remember, koaapp.callback() does not have a next, so there's no passing errors to the express app or skipping the koaapp once you use it.
it's better to keep them completely separate since their APIs are incompatible
var koaapp = koa()
var expressapp = express()
http.createServer(req, res) {
if (true) koaapp(req, res);
else expressapp(req, res);
})
Since you need a server instance in order to mount a middleware on a specific /prefix, it would be something like
var http = require('http');
var expressApp = require('express');
var koaApp = require('koa');
// ...
expressApp.use('/prefix', http.createServer(koaApp.callback()));

Resources