oatpp/example-async-api

Correct way to get path-params when using ENDPOINT_ASYNC

puneetugru opened this issue · 4 comments

Hi Leonid,

I've been using oatpp with Sync APIs for my project.
For one of the REST API, I'm getting path-params as below (in SYNC API),

ENDPOINT("POST", "{path-param1}/{path-param2}/temperature", getTemperature,
           REQUEST(std::shared_ptr<IncomingRequest>, request), // Map request object to endpoint method
           PATH(String, pathParam1, "path-param1"),
           PATH(String, pathParam2, "path-param2"),
           BODY_DTO(DataDto::ObjectWrapper, dataDto)) {
    
        OATPP_LOGD("MyApp", "Received nodeId value=%s", pathParam1->std_str().c_str());
        OATPP_LOGD("MyApp", "Received sensorId value=%s", pathParam2->std_str().c_str());
        OATPP_LOGD("MyApp", "Received value for type=%s", dataDto->type->std_str().c_str());
        OATPP_LOGD("MyApp", "Received value for timestamp=%ld", dataDto->timestamp->getValue());
        OATPP_LOGD("MyApp", "Received value for temperature=%lf", dataDto->temperature->getValue());

        /* return result */
        return createDtoResponse(Status::CODE_202, dataDto);
  }

Now, I would like to convert this into an ASYNC API, along with extraction on path-params.

For that, I added code as below,

ENDPOINT_ASYNC("POST", "{path-param1}/{path-param2}/temperature", getTemperature,
                PATH(String, pathParam1, "path-param1"),
                PATH(String, pathParam2, "path-param2")){

           ENDPOINT_ASYNC_INIT(getTemperature)

           Action act() override {
                return request->readBodyToDtoAsync<dataDto>(controller->getDefaultObjectMapper())
                   .callbackTo(&getTemperature::onBodyObtained);
           }

           Action onBodyObtained(const DataDto::ObjectWrapper& dataDto) {

               OATPP_LOGD("MyApp", "Received nodeId value=%s", pathParam1->std_str().c_str());
               OATPP_LOGD("MyApp", "Received sensorId value=%s", pathParam2->std_str().c_str());
               OATPP_LOGD("MyApp", "Received value for type=%s", dataDto->type->std_str().c_str());
               OATPP_LOGD("MyApp", "Received value for timestamp=%ld", dataDto->timestamp->getValue());
               OATPP_LOGD("MyApp", "Received value for temperature=%lf", dataDto->temperature->getValue());
  
               /* return result */
               return _return(controller->createDtoResponse(Status::CODE_202, dataDto));
          }
  }

But, I'm getting below compilation errors,

error: macro "ENDPOINT_ASYNC" passed 5 arguments, but takes just 3
PATH(String, pathParam2, "path-param2")){

I would like to know how to extract path-params when using ASYNC APIs.

-Thanks,
Puneet

I'm able to get the path parameters below way,

ENDPOINT_ASYNC("POST", "{path-param1}/{path-param2}/temperature", getTemperature) {

           ENDPOINT_ASYNC_INIT(getTemperature)
           String pathParam1;
           String pathParam2;
    
           Action act() override {
                pathParam1 = request->getPathVariable("path-param1");
                pathParam2 = request->getPathVariable("path-param2");
                return request->readBodyToDtoAsync<DataDto>(controller->getDefaultObjectMapper())
                   .callbackTo(&getTemperature::onBodyObtained);
           }

           Action onBodyObtained(const DataDto::ObjectWrapper& dataDto) {   
    
               OATPP_LOGD("MyApp", "Received nodeId value=%s", pathParam1->std_str().c_str());
               OATPP_LOGD("MyApp", "Received sensorId value=%s", pathParam2->std_str().c_str());
               OATPP_LOGD("MyApp", "Received value for type=%s", dataDto->type->std_str().c_str());
               OATPP_LOGD("MyApp", "Received value for timestamp=%ld", dataDto->timestamp->getValue());
               OATPP_LOGD("MyApp", "Received value for temperature=%lf", dataDto->temperature->getValue());

               /* return result */
               return _return(controller->createDtoResponse(Status::CODE_202, dataDto));
          }
   };

But, can you tell me whether this is correct or something needs to be changed further?

  • Thanks,
    Puneet Ugru

Hello @puneetugru ,

Yes you are correct - this is the right way to get path variables when using ENDPOINT_ASYNC.

param = request->getPathVariable("path-param-name");

Best Regards,
Leonid

Hi @lganzzzo,

I found using this way I cannot set the path variable through Swagger, an example is like
image
Do I have any options to change this?

Also, I will receive [ApiController]: Error. Non-async call to async endpoint. when switching to the async endpoint. Do you know what's it about?

Thanks

Hello @ReturnHttp418 ,

If you are using Async API - you have to manually add all swagger params inside the ENDPOINT_INFO block.

Also, I will receive [ApiController]: Error. Non-async call to async endpoint. when switching to the async endpoint. Do you know what's it about?

If you are using Async Endpoints, you have to use AsyncHttpConnectionHandler.