Routing-controllers: question: conflicting routes

Created on 17 Jul 2017  路  6Comments  路  Source: typestack/routing-controllers

Hi,
If I build a controller like this:

@JsonController()
export class ItemController {

    @Get("/items/:itemId")
    getItem(@Param("itemId") itemId: number) {
        log.info("/items/:itemId")
        // if (itemId == "all")return this.getAllItems();
        // return new ItemModel({ite_id: itemId}).fetch().then(marshalBookshelf);
        return {message: "/items/:itemId"};
    }

    @Get(new RegExp("/items/all"))
    getAllItems() {
        log.info("/items/all")
        return {message: "/items/all"};
    }

}

and I try to GET "/items/all", I notice that both methods are invoked.
I know that this is not a good way to implement a REST api, in fact I doscourage this, however I'm shifting from a legacy project and I would like to move to routing-controllers. I noticed that by using the native express way to declare routes (like in the legacy project), the route being selected when invoking "/items/all" is only one ("/items/all"), so there are no multiple route handlers being executed.

question

Most helpful comment

Note: please use three backtick (`) to format your multiline code and append the language type after the opening backticks. (This time it's ts)

Routing controllers will match both routes because your items/:itemId route will match alphanumeric characters and all is alpanumeric. What you want is to change it to @Get('items/:itemId([0-9]+)') to explicitly expect numerical id-s.

So it would looks like:

@JsonController()
export class ItemController {

  @Get('items/:itemId([0-9]+)')
  getItem(@Param("itemId") itemId: number) {
      log.info("/items/:itemId")
      return {message: "/items/:itemId"};
  }

  @Get('/items/all')
  getAllItems() {
      log.info("/items/all")
      return {message: "/items/all"};
  }
}

All 6 comments

Note: please use three backtick (`) to format your multiline code and append the language type after the opening backticks. (This time it's ts)

Routing controllers will match both routes because your items/:itemId route will match alphanumeric characters and all is alpanumeric. What you want is to change it to @Get('items/:itemId([0-9]+)') to explicitly expect numerical id-s.

So it would looks like:

@JsonController()
export class ItemController {

  @Get('items/:itemId([0-9]+)')
  getItem(@Param("itemId") itemId: number) {
      log.info("/items/:itemId")
      return {message: "/items/:itemId"};
  }

  @Get('/items/all')
  getAllItems() {
      log.info("/items/all")
      return {message: "/items/all"};
  }
}

Thank you for the solution and the formatting tip, it solved my problem.
I didn't know it was possible to apply regex filters like this.

Can I suggest that @NoNameProvided's comment be added to the docs, until I saw this it wasn't clear to me how to use a regex in routing params.

I have mongodb and this regex will not be helpful for me so what should I do

I have mongodb and this regex will not be helpful for me so what should I do

i use this pattern

@JsonController()
export class ItemController {

    @Get("/items/:itemId([0-9a-fA-F]{24})")
    getItem(@Param("itemId") itemId: number) {
        log.info("/items/:itemId")
        // if (itemId == "all")return this.getAllItems();
        // return new ItemModel({ite_id: itemId}).fetch().then(marshalBookshelf);
        return {message: "/items/:itemId"};
    }

    @Get(new RegExp("/items/all"))
    getAllItems() {
        log.info("/items/all")
        return {message: "/items/all"};
    }

}

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

AnthoniG picture AnthoniG  路  4Comments

szabobar picture szabobar  路  4Comments

AleskiWeb picture AleskiWeb  路  4Comments

dcbartlett picture dcbartlett  路  3Comments

d-bechtel picture d-bechtel  路  6Comments