blue-veery-gmbh / spring-rest-2-ts

spring rest 2 ts is typescript generator which produces data model and services in typescript based on Spring MVC annotations. It supports generation for Angular and React
MIT License
64 stars 17 forks source link

/spring-rest2ts-spring : RequestMapping path variable definition syntax is not supported #49

Open ememisya opened 10 months ago

ememisya commented 10 months ago

It appears that the regex support for path variable pattern definition is currently not supported. Having a controller with the following mapping, "/{id:^[0-9]*$}" results in an unchecked exception incorrectly stating that the variable cannot be found.

ememisya commented 10 months ago

A temporary resolution proposed at https://github.com/blue-veery-gmbh/spring-rest-2-ts/pull/50 while awaiting resolution on https://github.com/spring-projects/spring-framework/issues/32093

tomasz-wozniak75 commented 10 months ago

Hi Thanks for the report, I will check today this problem and let you know how we are going to solve it.

ememisya commented 10 months ago

Unfortunately https://github.com/spring-projects/spring-framework/issues/32093 did not go as I had hoped and it appears as though the SpringFramework developer(s) are leaving users with little choice but to duplicate parsing functionality. It also appears that there is one other thing to consider than I have implemented at https://github.com/blue-veery-gmbh/spring-rest-2-ts/pull/50 which you may view at https://docs.spring.io/spring-framework/docs/6.1.3/javadoc-api/org/springframework/web/util/pattern/PathPattern.html and that is the character typed as {variable} which ends up with multiple path segments named as one.

tomasz-wozniak75 commented 10 months ago

I had a look on this and for me this should be an easy fix but I could be wrong. My view is following:

In {} we have parameter name in the URL template, for example id param: /person/{id} and spring sets under id parameter value which is after /person/ prefix. This is what we implemented but we didn't take into consideration that after variable name there could be regex to match part of the URL, from the library perspective we need only variable name, regex is needed by spring to match part of the URL at the backend side. So the only required thing is to cut off regex part to have only var name. This is what your PR is trying to achieve?

https://docs.spring.io/spring-framework/docs/3.2.16.RELEASE/spring-framework-reference/html/mvc.html

` URI Template Patterns with Regular Expressions Sometimes you need more precision in defining URI template variables. Consider the URL "/spring-web/spring-web-3.0.5.jar". How do you break it down into multiple parts?

The @RequestMapping annotation supports the use of regular expressions in URI template variables. The syntax is {varName:regex} where the first part defines the variable name and the second - the regular expression.For example:

@RequestMapping("/spring-web/{symbolicName:[a-z-]+}-{version:\d\.\d\.\d}{extension:\.[a-z]+}") public void handle(@PathVariable String version, @PathVariable String extension) { // ... } }

`

ememisya commented 10 months ago

I had a look on this and for me this should be an easy fix but I could be wrong. My view is following:

In {} we have parameter name in the URL template, for example id param: /person/{id} and spring sets under id parameter value which is after /person/ prefix. This is what we implemented but we didn't take into consideration that after variable name there could be regex to match part of the URL, from the library perspective we need only variable name, regex is needed by spring to match part of the URL at the backend side. So the only required thing is to cut off regex part to have only var name. This is what your PR is trying to achieve?

Yes. To clarify, my hope was to use Spring to parse it and then check for PathElement instance to find out how to deal with it. There is one additional caveat not supported by spring-rest2ts and that is for any expression defined like, /test/{multiple} with an assigning @PathVariable of let's say (long multiple) where /test/1/2/3/4 is given, (long multiple) is not forced to be an array but is consumed in multiple chunks of path segments. My PR only deals with the regex case, however {multiple} should also be handled.

https://github.com/spring-projects/spring-framework/blob/main/spring-web/src/test/java/org/springframework/web/util/pattern/PathPatternParserTests.java

I will go ahead and come up with a solution for the {*multiple} case as well and commit it into the PR in the next few hours.

ememisya commented 10 months ago

Have you considered using something like https://github.com/mozilla/rhino ? Or was the partial implementation on TypeScript for other purposes? Frankly for what I'm trying to do this project works. I'm solely using it to generate Axios APIs from a maven plugin I wrote for my Spring controllers and having 0 dependencies to worry about really helps.

ememisya commented 10 months ago

I've gone ahead and rebased https://github.com/blue-veery-gmbh/spring-rest-2-ts/pull/50 with the mentioned changes which now covers "capture the rest" pattern. Hopefully that helps.