drogonframework / drogon

Drogon: A C++14/17/20 based HTTP web application framework running on Linux/macOS/Unix/Windows
MIT License
11.44k stars 1.1k forks source link

[FR] Alternative container for parsed request parameters #808

Closed O-Tom closed 4 months ago

O-Tom commented 3 years ago

Is your feature request related to a problem? Please describe. I've got a query string that looks like &target=point&xy=986200,6732900&xy=986000,6732300. Any number of xy parameters can be added to the query, from 1 to N. The HttpRequest class is using an std::unordered_map<std::string, std::string> to store parameters after parsing. This drops duplicates so that only one of the xy definitions is kept.

Describe the solution you'd like I wish the parser would push the parameters and their values in a more transparent container. I think of something like std::vector<std::pair<std::string,std::string>>>. This would preserve duplicates, as well as the original order of parameters.

Describe alternatives you've considered If the query text is held along with decoded parameters, an std::vector<std::pair<std::string_view,std::string_view>>> could be used to serve the same purpose and avoid copies of the query strings. If a map is really mandatory to preserve the performance of the getParameter() method, an std::unordered_multimap could be used to at least save duplicates.

rbugajewski commented 3 years ago

Thanks for your feedback.

As I see this is kind of a special use case, but nonetheless worth to tackle, but maybe in Drogon 2.0, what do you think @an-tao, @marty1885, @interfector18? I think this would require an additional level of abstraction where we would have some kind of generic ParameterBag which would be by itself configurable on a per project basis, but default to the current behavior.

an-tao commented 3 years ago

Why not use json to post the information?

rbugajewski commented 3 years ago

Why not use json to post the information?

Yeah, why not 😜

Maybe there are some legacy systems involved which @O-Tom has no control over?

interfector18 commented 3 years ago

I'm of the opinion getQuery() should be used to and parse the parameters with a custom function.

As there are many different ways people encode the query string in the wild, and we can't support every use case.

O-Tom commented 3 years ago

In this particular case I do parse the query() string, that's not a big deal. It's just that it gets parsed twice, and I would rather use existing functions than re-implementing them.

an-tao commented 3 years ago

Don't worry about parsing twice, the parsing is delayed until users use it.

    virtual const std::unordered_map<std::string, std::string> &parameters()
        const override
    {
        parseParametersOnce();
        return parameters_;
    }
Etienne-P54 commented 3 years ago

Hello,

The easisest way to fix this would be to use a std::unordered_multimap. May be in version 2.0 because it will break the current API. But anyway @O-Tom you should not rely on receiving the query parameters in the order of the URL.