loentar / ngrest

Fast and easy C++ RESTful WebServices framework
Apache License 2.0
465 stars 94 forks source link

Supporting Multiple HTTP Get Handler functions in the service #81

Closed raadiy closed 2 years ago

raadiy commented 2 years ago

Hi Dmitry, It appears that it is not possible to support two HTTP GET handlers, expecting different URLs. At run time, it picks the first one defined inside the class. Is there any way this can be achieved using any option in the "*location" string. Kindly clarify. Thanks in advance.

Example:

//! HTTP Get operation
// *location: /{arg1}?arg2={arg2}&arg3={arg3}
// *method: GET
std::string getHandler(const std::string& arg1,
                       const std::string& arg2,
                       const std::string& arg3,
                       ngrest::MessageContext& context);

//! HTTP Get operation
// *location: /{arg1}?arg2={arg2}
// *method: GET
std::string get2(const std::string& arg1,
                 const std::string& arg2,
                 ngrest::MessageContext& context);

Regards Raajesh

loentar commented 2 years ago

The resource path of the both methods is the same, because of that only the first one gets called. This is expected behavior.

In case you need optional argument, you may use ngrest::Nullable type wrapper like this:


//----- header

#include <ngrest/common/Nullable.h>

//! HTTP Get operation
// *location: /{arg1}?arg2={arg2}&arg3={arg3}
// *method: GET
std::string getHandler(const std::string& arg1,
                       const std::string& arg2,
                       const ngrest::Nullable<std::string>& arg3,
                       ngrest::MessageContext& context);

//----- implementation

std::string test12::getHandler(const std::string& arg1,
                       const std::string& arg2,
                       const ngrest::Nullable<std::string>& arg3,
                       ngrest::MessageContext& context)
{
    return "arg1=" + arg1 
               + ", arg2=" + arg2 
               + ", arg3=" + (arg3.isValid() ? *arg3 : "undefined");
}

arg3.isValid() will return true if arg3 was passed to the request.

Try this with service tester. http://localhost:9098/ngrest/services

raadiy commented 2 years ago

Thank you... will try it.

raadiy commented 2 years ago

Hi, when I test using the ngrest service tester it works (the arg3 has a checkbox that has to be set to accept the value). However, while testing the service as a URL by iteself, I am unable to figure out how to give the complete URL

This works: http://localhost:9098/helloworld/arg1?arg2=2&arg3=3

The following does not work: http://localhost:9098/helloworld/arg1?arg2=2

I see the error: Can't find divider [&arg3=] for path: /helloworld/arg1?arg2=2

Regards Raajesh

loentar commented 2 years ago

Oh, I suppose the only way to get all the query parameters is to parse them manually

// *location: /{location}?{parameters}
// *method: GET
std::string getHandler(const std::string& location,
                       const std::string& parameters,
                       ngrest::MessageContext& context);
raadiy commented 2 years ago

okay, thanks you