micronaut-projects / micronaut-core

Micronaut Application Framework
http://micronaut.io
Apache License 2.0
6.09k stars 1.07k forks source link

Problem to bind multi-value URL path to Collection in Micronaut Koltin microservice #1727

Open C06A opened 5 years ago

C06A commented 5 years ago

I think the binding of URL to the micronaut controller action parameters should be reversal to the expanding URI Template to URL. This means that placeholder {/stack*} should be binded to the Collection by sequence of values separated by slashes "/". Someone suggested to use template /{+stack} to bind it to String and then parse it "by hands". I think it is bed as expanding the same template will not escape special characters which opens opportunity for injection hacker's attack. It also doesn't allow this parameter to be optional.

Micronaut extends URI Templats with matching patterns, but doesn't work well with complex patterns, so I think it should be used ONLY to be able to distinct different actions and not for validation. Actual validation should be done based on the parameter type.

Pattern in the template can be easily combine with "*" marking Collection of values if template will follow the "*" char. For example {/stack:*[-0-9\.eE]+} doesn't define the actual Number's pattern, but would be enough to distinguish from other similar templates {/stack*} not limited to Numbers.

Task List

Steps to Reproduce

  1. Create the Micronaut microservice with Koltin
  2. Create Controller with GET method binded to URL "/repeat/{value}{/stack*}" and parameters (value: BigDecimal, stack: Collection)
  3. Try to request on URL "http://localhost:8080/repeat/1/2/3/4"

Expected Behaviour

Server should find the Controller's action and return whatever it creates

Actual Behaviour

Returns "Page Not Found" exception

Environment Information

(see project in GIThub below)

Example Application

https://github.com/C06A/Micronaut_Collection_binding_problem

C06A commented 5 years ago

... any news/issues about this?..

mscaldas2012 commented 2 years ago

Hi, been trying to implement this in micronaut... has anyone solved this problem?

graemerocher commented 2 years ago

It is doable already but you have to use /repeat/{value}{+path} and then bind path to a parameter that you can parse yourself. See https://docs.micronaut.io/latest/guide/#routing and the section on "Reserved Character Matching"

C06A commented 2 years ago

"parse yourself" kind of defeat the promise of binding parameters by the framework. Also, the multi-value syntax of the URI-Template is valid and should be handled by framework.

@graemerocher, your suggestion is a workaround and not something I would call "support". I addressed it in my edited original request.