Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Strange partial match behaviour if you break the undocumented uniqueness constraint #9

Open
mark-butterworth-lookinglocal opened this issue Feb 12, 2024 · 5 comments

Comments

@mark-butterworth-lookinglocal

const filteredEntries = Array.from(state.methods.entries()).filter(

These lines of code replace a route if the target endpoint name is a duplicate.

The route then takes on some very strange characteristics.
In my example:

GET /:id endpointFn
POST /:id/query endpointFn

Using middleware to coerce the payload from body to query so the same endpoint can handle body and provide a way around the maximum URL length.
I stumbled onto this requirement when POST /:id wasn't behaving as expected for someone and I told them this is not even a route and should return 404.
It was not..

I have not dug further into the WHY of the code beyond this point as I have simply re-written my code to go around the issue.
But, the replacement appears to introduce partial route matching such that invalid routes are no longer falling through to 404.

I would suggest 2 things:
Firstly, document this restriction in the readme as this library enforces a restriction that it is not making clear to the consumer (for me that is via awilix-express)
Secondly, investigate why partial route-matching is caused by the replacement or undo the decision to replace.

Once I removed the duplicate endpoint in the builder configuration the POST /:id call returned 404 as I would have expected.

@jeffijoe
Copy link
Owner

That does seem like a bug rather than a restriction.

@mark-butterworth-lookinglocal
Copy link
Author

mark-butterworth-lookinglocal commented Feb 12, 2024

I suggested intent of design purely based on the comment on the line above my link

// Filters out the entry we're replacing.

I look forward to multi-line permalink syntax :)
Apologies for not having the time to dig deeper into this myself.
And... thank you for an awesome dependency injection library :)

@jeffijoe
Copy link
Owner

I’m afraid I won’t be able to look into it now as I’m out sick. Any help is appreciated with debugging the root cause :)

@mark-butterworth-lookinglocal
Copy link
Author

mark-butterworth-lookinglocal commented Feb 12, 2024

Throwing console.log(`Register /${method} ${methodCfg.paths}`); into transpiled source from awilix-express/lib/controller.js
Directly above the router[method].apply line of _registerController

https://github.com/jeffijoe/awilix-express/blob/aa2417e4859ea8fe1cac7d3bbc9ed272011fadcb/src/controller.ts#L83

Records the route registration changes in the following way

Different endpoint function name:
Register /get /batch/:id
Register /post /batch/:id/query

Same endpoint function name:
Register /get /batch/:id,/batch/:id/query
Register /post /batch/:id,/batch/:id/query

I hope this helps, sorry to hear you are sick. I'd be happy to help if I had the time.
I think it'd be a fairly small use-case where people would re-use an endpoint function anyway so take your time and recover :)

@jeffijoe
Copy link
Owner

jeffijoe commented Feb 14, 2024

I think I see the problem. Basically, it'll register each verb with each path which is what you are observing.

This is tricky because it's related to how the internal state is stored which was done in a way that allowed using both decorators and a builder pattern.

For example, it allows the following usage:

class Test {
  @route('/save')
  @POST()
  @PUT()
  @PATCH()
  save() {
    /**/
  }
}

It would require a breaking change to the API in order to fix it, because I don't want to be maintaining 2 state representations 😅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants