More flexible path matching (such as file extensions and logical or)
Bug report
spring-cloud-version: Finchley.SR2
I has a requirement that route www.example.com/**/*.html to lb://serviceNodeJs, and route www.example.com/** to lb://serviceJava,
so I wrote the following yaml file:
spring:
cloud:
gateway:
routes:
- id: test1
uri: lb://serviceNodeJs
predicates:
- Host=www.example.com
- Path=/**/*.html
- id: test2
uri: lb://serviceJava
predicates:
- Host=www.example.com
- Path=/**
But when I browse http://www.example.com/index.html, it is routed to lb://serviceJava,
my idea is that all the requests with the .html postfix being routed to lb://serviceNodeJs, and all the others being routed to lb://serviceJava, And I have also read the source code PathRoutePredicateFactory, I found that it use a new class PathPattern to test if it matches. If I use AntPathMatcher, it can support my requirement. so can PathPattern changed to meet this requirement?
Maybe we need something like an extension filter? The path filter probably doesnt take into account the file extension.
@spencergibb thoughts?
PathPatternParser was made to be efficient and fast where AnyPathMatcher is not. I don't think I want to change this to use AntPathMatcher because of that.
You could use the JavaDSL to or two path predicates, or with the yaml, create two routes, one for root html, the other non-root html.
I've reached out to the framework team to see if that is correct behavior.
Here are the javadocs for the matcher. https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/util/pattern/PathPattern.html
It's examples use file extensions, but not the two together.
See https://jira.spring.io/browse/SPR-14544 for the reasoning.
I'd prefer not to have a specific suffix filter. Maybe an option to use AntPathMatcher subject to the performance implications.
Similar suggestions have come from @acidelk over gitter - to allow more elastic ways to match paths than what PathPattern allows for, for example to allow any endpoint from a group of defined endpoints to match the predicate like so:
predicates:
- Path=/users/(find|status)
or like so:
predicates:
- Path=/users/find
- Path=/users/status
You can currently repeat predicates, but it means a logical AND
predicates:
- Path=/users/find
- Path=/users/status
What is the good of it? :)
It's good in many other situations. I'm just stating that repeating them is already possible, but it means something else.
Multiple paths were added in 7a5502fd7ae57e254151e38fe619b596b212b7e5.
I think an AntPathRoutePredicateFactory is the way forward here. Being aware that its performance will not match the PathPatternParser one.
Common functionality could be extracted to a base class.
AntPathRoutePredicateFactory, I think is much needed for path predicates with ** within the pattern. Are there any plans to implement the same?
Not currently
I am trying to migrate from zuul for spring cloud gateway - I had configuration similar to this on Zuul which is using ant_path_matcher
api-with-specific-path:
path: /api/v1/**/collection
service-id: service1
api-with-less-restrictive-path:
path: /api/v1/**
service-id: service2
Is there any workaround I can utilize to support such configuration? This is what I was trying
- id: api-with-specific-path
uri: s://service1
predicates:
- Path=/api/v1/**/collection
filters:
- RewritePath=/api/v1//?(?<segment>.*), /v1-api/$\{segment}
I received following error - No more pattern data allowed after {*...} or ** pattern element. I used spring.mvc.pathmatch.matching-strategy=ant_path_matcher but that didn't help.