qbit icon indicating copy to clipboard operation
qbit copied to clipboard

Support for @PathVariable in the middle of request path

Open metanil opened this issue 9 years ago • 3 comments

Currently,

@RequestMapping(value = "/abc/{id}/def", method = RequestMethod.PUT)
void methodA(@PathVariable("id") int id) {}

is not supported if you define more than one /abc/*** URI base.

Only trailing PathVariable is currently supported like:

@RequestMapping(value = "/abc/def/{id}", method = RequestMethod.PUT)
void methodA(@PathVariable("id") int id) {}

@RequestMapping(value = "/abc/efg/{id}", method = RequestMethod.PUT)
void methodB(@PathVariable("id") int id) {}

This is ok because /abc/def/ is unique and /abc/efg is unique.

UPDATE In the middle are supported btw. Just unique bases are supported.

This does not work:

@RequestMapping(value = "/abc/{id}/foo", method = RequestMethod.PUT)
void methodA(@PathVariable("id") int id) {}


@RequestMapping(value = "/abc/{id}/bar", method = RequestMethod.PUT)
void methodB(@PathVariable("id") int id) {}

This does...

@RequestMapping(value = "/abc/foo/{id}", method = RequestMethod.PUT)
void methodA(@PathVariable("id") int id) {}


@RequestMapping(value = "/abc/bar/{id}", method = RequestMethod.PUT)
void methodB(@PathVariable("id") int id) {}

The start of the URI has to be unique. Path vars can be anywhere in the middle as long as the roots are all unique.

Basically this will work fine


@RequestMapping(value = "/abc/{id}/def", method = RequestMethod.PUT)
void methodA(@PathVariable("id") int id) {}

_AS LONG AS YOU DON'T HAVE THIS TOO_:

@RequestMapping(value = "/abc/{id}/foo", method = RequestMethod.PUT)
void methodB(@PathVariable("id") int id) {}

metanil avatar Oct 09 '15 01:10 metanil

UPDATE In the middle are supported btw. Just unique bases are supported.

This does not work:

@RequestMapping(value = "/abc/{id}/foo", method = RequestMethod.PUT)
void methodA(@PathVariable("id") int id) {}


@RequestMapping(value = "/abc/{id}/bar", method = RequestMethod.PUT)
void methodA(@PathVariable("id") int id) {}

This does...

@RequestMapping(value = "/abc/foo/{id}", method = RequestMethod.PUT)
void methodA(@PathVariable("id") int id) {}


@RequestMapping(value = "/abc/bar/{id}", method = RequestMethod.PUT)
void methodA(@PathVariable("id") int id) {}

The start of the URI has to be unique. Path vars can be anywhere in the middle as long as the roots are all unique.

RichardHightower avatar Oct 09 '15 04:10 RichardHightower

Basically this will work


@RequestMapping(value = "/abc/{id}/def", method = RequestMethod.PUT)
void methodA(@PathVariable("id") int id) {}

as long as you did not also define this

@RequestMapping(value = "/abc/{id}/foo", method = RequestMethod.PUT)
void methodB(@PathVariable("id") int id) {}

RichardHightower avatar Oct 09 '15 04:10 RichardHightower

You don’t have to use request params.

(caps are for emphasis not yelling)

This will WORK:

/tools/dimensions/{toolId}
/tools/query/{toolId}

As long as you don’t have the same root URI, you can still use path variables.

I use them all of the time.

This works:

/book/author/{authorid}/isbn/{isbn}

The above is fine.

You just can’t have both of these (NO WORKY):

/book/author/{authorid}/isbn/{isbn}
/book/author/{authorid}

The reason is I only use the root to determine uniqueness of the URI. Mostly for speed. But I could handle the other, but then I need to build a pre-parsed meta-data tree so I don’t have to parse the string each time to determine uniqueness. (Just more work.)

But you can have:

/book/author/{authorId}
/book/isbn/{isbn}
/book/isbn-author/{authorId}/{isbn}

as long as the ROOT is UNIQUE.

This is a limitation of the implementation, which has less limitations this my first version which I wrote in an hour after one of my best friends said why don’t you add path variable support and REST support (before that QBit just did WebSocket calls). I said it would be easy. Then I wrote the first version in an hour. It worked for about 80% of the cases. The second version took days. It gets me to around the 95% of cases. But yeah.. I need some improvement to get to this level of non-unique roots. I have not figure out a way to do it that is not so CPU intensive. I basically want to pre-parse everything up front, and then have very little logic or parsing done at runtime. It can be done, but it makes the logic a lot more complicated (it just takes time and unit tests).

RichardHightower avatar Oct 09 '15 17:10 RichardHightower