seanpmaxwell/overnight

Parameter path isn't recognized when there is another path

Closed this issue · 2 comments

Here is my controller

@Controller('api/authors/')
export class AuthorController {

    @Get(':id')
    async private get(req: Request, res: Response) {
       //Logic
    }

    @Get('random')
    async private get(req: Request, res: Response) {
       //Logic
    }

    @Get('')
    async private getAll(req: Request, res: Response) {
       //Logic
    }

}

The controller should work as follows:

  1. /api/authors/authorId, e.g. /api/authors/3 should return author with the specified id
  2. /api/authors should return all authors
  3. /api/authors/random should return a random author

When, in Postman, I make a request to either /api/authors or /api/authors/random it works fine. But when I try to make a request to /api/authors/3 it says:

Cannot GET /api/authors/3

However If I remove the code associated with @Get(random) it is back to normal, /api/authors/3 works fine again.

Hello,

With express, the expected behavior here is a little different than you have stated.

  • /api/authors/3 should hit the method labeled @Get(':id')
  • /api/authors/random should also hit the method labeled @Get(':id')

A request to /api/authors/random matches both /api/authors/:id (where id is "random") and /api/authors/random. Since /api/authors/:id is declared first, it takes priority. If you switch the order that the two methods are declared, then a request to /api/authors/random will match /api/authors/random rather than /api/authors/:id.

Relevant stackoverflow question here. See the more upvoted answer, not the accepted one.

Some assumptions I'm making about the provided code:

  • The keywords async and private need to be switched.
  • The first two methods need to have different names (both are currently get)

There is a gist here with the code I am using to test. It looks like it's working as expected.

Hello, thanks for such a fast response. I changed the names of these methods and swapped them in code:

@Controller('api/authors/')
export class AuthorController {

    @Get('random')
    async private getRandom(req: Request, res: Response) {
    }

    @Get(':id')
    async private get(req: Request, res: Response) {
    }

    @Get('')
    async private getAll(req: Request, res: Response) {
    }

}

And everything seems to be working just fine!