0

I have a very simple routing code using @koa/router:

import Koa from 'koa';
import Router from '@koa/router';

const app = new Koa();

const router = new Router();

router.use('/api', (ctx, next) => {
  ctx.body = 'catch all with use';
  ctx.status = 201;
  next();
});


app.listen(3000);

However accessing the path http://localhost:3000/api returns 404. So, what is the exact use of use method of the router?

I wish to send all the request starting with /api prefix to a custom middleware which itself could be a @koa/router middleware or any other Koa middleware.

Harshal Patil
  • 17,838
  • 14
  • 60
  • 126

2 Answers2

0

I managed to match everything under /api/:

import Koa from 'koa';
import Router from '@koa/router';

const app = new Koa();
const apiRouter = new Router();

const catchAll = new Router();
catchAll.get('/(.*)', async (ctx, next) => {
    console.log("Here is some middleware");
    console.log('/' + ctx.params[0]);
    await next();
    console.log(ctx.body)
}, async (ctx, next) => {
    ctx.body = 'catch all with URL ' + ctx.url;
    ctx.status = 201;
    await next();
});

apiRouter.use('/api', catchAll.routes());
app.use(apiRouter.routes());
app.listen(3000);

This does not match /api without a trailing slash, though.


I found a simpler way to achieve the same. However, it does not use the use method of the router instance:

import Koa from 'koa';
import Router from '@koa/router';

const app = new Koa();
const apiRouter = new Router();

apiRouter.get('/api/(.*)', async (ctx, next) => {
    console.log("Here is some middleware");
    console.log('/' + ctx.params[0]);
    await next();
    console.log(ctx.body)
}, async (ctx, next) => {
    ctx.body = 'catch all with URL ' + ctx.url;
    ctx.status = 201;
    await next();
});
app.use(apiRouter.routes());
app.listen(3000);

Notice how the second way's '/api/.*' is the first way's '/api' + '/(.*)'.

And apparently, the use of the router instance performs concatenation for the get paths (and similarly for post etc), so, if you used (.*) without leading slash for catchAll.get in the first way above, it would try to just concatenate it to /api(.*), which then would match /api2 and the likes.

qrsngky
  • 2,263
  • 2
  • 13
  • 10
0

There are two things to update in your example

  1. I recommend switching to use the prefix option from Koa/router. Then you do not need the path name in your use middleware
// this has `prefix` as an option now
const router = new Router({ prefix: '/api' });

router.use((ctx, next) => {
  ctx.body = 'catch all with use';
  ctx.status = 201;
  next();
});
  1. You must register the router with the app. the koa app does not know about the apiRouter in your example. you need to add this line before the app.listen:
app.use(apiRouter.routes());
Katherine R
  • 1,107
  • 10
  • 20