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

Reuse Endpoints. #51

Closed
c-lgrant opened this issue Mar 19, 2019 · 4 comments
Closed

Reuse Endpoints. #51

c-lgrant opened this issue Mar 19, 2019 · 4 comments
Labels
Question Further information is requested

Comments

@c-lgrant
Copy link

c-lgrant commented Mar 19, 2019

Hello,

Im wondering if the following is possible I want to define multiple end points but have them resolve to the same function for example:

/app/maps/{mapGuid}/start
/app/maps/{mapGuid}/stop

What i want to be able to do is to define one function for both of these then add logic based on the url.

Is this possible ?

Thanks

Conor

@c-lgrant c-lgrant changed the title Multiple reuse of functions. Reuse Endpoints. Mar 19, 2019
@lganzzzo lganzzzo added the Question Further information is requested label Mar 19, 2019
@lganzzzo
Copy link
Member

Hello @c-lgrant !
Thanks you for the question.

You have to create separate method for your business logic processing, and call it from your endpoint mappings.
Example:

  /**
   * Process request 
   */
  std::shared_ptr<OutgoingResponse> handleRequest(String param, String body) {
    OATPP_ASSERT_HTTP(param && body, Status::CODE_404, "param and body should not be null");
    return createResponse(Status::CODE_200, param + body);
  }

  /**
   * Add endpoint mapping
   */
  ENDPOINT("GET", "endpoint1/{param}", endpoint1, PATH(String, param), BODY_STRING(String, body)) {
    return handleRequest(param, body);
  }

  /**
   * Add endpoint mapping
   */
  ENDPOINT("GET", "endpoint2/{param}", endpoint2, PATH(String, param), BODY_STRING(String, body)) {
    return handleRequest(param, body);
  }

Best Regards,
Leonid

@c-lgrant
Copy link
Author

Hello,

So there is no way to made two end points to one function?

In the example above, if the logic was different for each endpoint how could the handleRequest function decide which action to take.

Can you confirm if there is a better way to get the url than performing.

this->m_endpointInfo.find(__FUNCTION__).operator*().second.get()->path 

Thanks

Conor

@lganzzzo
Copy link
Member

Hey @c-lgrant

It would be helpful, if you could describe what you are trying to achieve in a bit more details.

From what I can guess, it can be achieved in many different ways.

From the code snippet that you've posted:

this->m_endpointInfo.find(__FUNCTION__).operator*().second.get()->path

I would not recommend to do it this way, as it will be hard to maintain such code in case of endpoint name changed or path of the endpoint changed.

As a simplest example I can propose next:

  • Variant one:
  static const int ACTION_START = 0;
  static const int ACTION_STOP = 1;

  /**
   * Process request
   */
  std::shared_ptr<OutgoingResponse> handleRequest(String mapGuid, int action) {
    OATPP_ASSERT_HTTP(mapGuid, Status::CODE_404, "mapGuid should not be null");
    switch(action) {
      case ACTION_START:
        // TODO maps.start;
        break;
      case ACTION_STOP:
        // TODO maps.stop;
        break;
      default: throw std::runtime_error("unknown action");
    }
    return createResponse(Status::CODE_200, "OK");
  }

  /**
   * Add endpoint mapping
   */
  ENDPOINT("GET", "/app/maps/{mapGuid}/start", start, PATH(String, mapGuid)) {
    return handleRequest(mapGuid, ACTION_START);
  }

  /**
   * Add endpoint mapping
   */
  ENDPOINT("GET", "/app/maps/{mapGuid}/stop", stop, PATH(String, mapGuid)) {
    return handleRequest(mapGuid, ACTION_STOP);
  }
  • Variant two (better way):
    Move map-related common functionality to Map class.
  /**
   *  Inject map processing component
   */
  OATPP_COMPONENT(std::shared_ptr<Map>, m_map);

  /**
   * Add endpoint mapping
   */
  ENDPOINT("GET", "/app/maps/{mapGuid}/start", start, PATH(String, mapGuid)) {
    m_map->start(mapGuid);
    return createResponse(Status::CODE_200, "started");
  }

  /**
   * Add endpoint mapping
   */
  ENDPOINT("GET", "/app/maps/{mapGuid}/stop", stop, PATH(String, mapGuid)) {
    m_map->stop(mapGuid);
    return createResponse(Status::CODE_200, "stopped");
  }

Best Regards,
Leonid

@lganzzzo
Copy link
Member

You may also consider to do it this way:

  ENDPOINT("GET", "/app/maps/{mapGuid}/{action}", map, 
           PATH(String, mapGuid), 
           PATH(String, action)) {

    OATPP_ASSERT_HTTP(action && (action == "start" || action == "stop"), Status::CODE_400, "Invalid Action");

    // do things based on mapGuid and action

    return createResponse(Status::CODE_200, "OK");
  }

Regards,
Leonid

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

No branches or pull requests

2 participants