Git Product home page Git Product logo

example-async-api's Introduction

Stand With Ukraine


Oat++ Logo

 

oatpp build status Join the chat at https://gitter.im/oatpp-framework/Lobby

Oat++

News

  • ⚠️ Attention! Oat++ main repo is bumping it's version to 1.4.0. While 1.4.0 is IN DEVELOPMENT use 1.3.0-latest tag.

Oat++ is a modern Web Framework for C++. It's fully loaded and contains all necessary components for effective production level development. It's also light and has a small memory footprint.

Start

About

Join Our Community

Quick Overview

Shortcuts:

Build Powerful API And Document It With Swagger-UI

See ApiController for more details.

ENDPOINT_INFO(getUserById) {
  info->summary = "Get one User by userId";

  info->addResponse<Object<UserDto>>(Status::CODE_200, "application/json");
  info->addResponse<Object<StatusDto>>(Status::CODE_404, "application/json");
  info->addResponse<Object<StatusDto>>(Status::CODE_500, "application/json");

  info->pathParams["userId"].description = "User Identifier";
}
ENDPOINT("GET", "users/{userId}", getUserById,
         PATH(Int32, userId))
{
  return createDtoResponse(Status::CODE_200, m_userService.getUserById(userId));
}

Access Databases And Keep Your Data Consistent

See Oat++ ORM for more details.

QUERY(createUser,
      "INSERT INTO users (username, email, role) VALUES (:username, :email, :role);",
      PARAM(oatpp::String, username), 
      PARAM(oatpp::String, email), 
      PARAM(oatpp::Enum<UserRoles>::AsString, role))

Frequently Asked Questions

Q: "Oat++" name?

  • "Oat" is something light, organic, and green. It can be easily cooked and consumed with no effort.
  • "++" gives a hint that it is "something" for C++.

Q: What is the main area of Oat++ application?

Oat++ is used for many different purposes, from building REST APIs that run on embedded devices to building microservices and highly-loaded cloud applications.

But the majority of use cases appears to be in IoT and Robotics.

Q: How portable is Oat++?

Theoretically, Oat++ can be easily ported everywhere where you have threads and network stack. With an additional comparably small effort, it can be ported almost everywhere depending on how much you strip it and what would be the final binary size.

See supported platforms for additional info.

Q: What is the size of a minimal Oat++ application?

About 1Mb, depending on C/C++ std-lib and oatpp version.

Q: Which Oat++ API to choose, Simple or Async?

Always choose Simple API wherever possible. Simple API is more developed and makes the code cleaner.

Async API is designed for small, specific tasks that run at high concurrency levels ex.:

  • Serving file downloads to a large number of concurrent users (1K users and more).
  • Streaming to a large number of clients (1K or more).
  • Websocket Chat servers.

For all other purposes use simple API.

Examples

REST-API

  • REST Service - A complete example of a "CRUD" service (UserService) built with Oat++. REST + Swagger-UI + SQLite.
  • REST Client - Example project of how-to use Retrofit-like client wrapper (ApiClient) and how it works.

WebSocket

  • Can Chat - Feature-complete rooms-based chat for tens of thousands users. Client plus Server.
  • WebSocket - Collection of oatpp WebSocket examples.
  • YUV Websocket Stream - Example project how-to create a YUV image stream from a V4L device (i.E. Webcam) using websockets.

Databases

  • SQLite - A complete example of a "CRUD" service. REST + Swagger-UI + SQLite.
  • PostgreSQL - Example of a production-grade entity service storing information in PostgreSQL. With Swagger-UI and configuration profiles.
  • MongoDB - Example project how to work with MongoDB using oatpp-mongo mondule. Project is a web-service with basic CRUD and Swagger-UI.

IoT

  • Example-IoT-Hue - Example project how-to create an Philips Hue compatible REST-API that is discovered and controllable by Hue compatible Smart-Home devices like Amazon Alexa or Google Echo.

Streaming

  • HTTP Live Streaming Server - Example project on how to build an HLS-streaming server using Oat++ asynchronous API.
  • YUV Websocket Stream - Example project how-to create a YUV image stream from a V4L device (i.E. Webcam) using websockets.

TLS

  • TLS With Libressl - Example project how-to setup secure connection and serve via HTTPS.

Microservices

Asynchronous API

  • Async Service - Example project on how to use asynchronous API to handle a large number of simultaneous connections.

example-async-api's People

Contributors

lganzzzo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

example-async-api's Issues

Correct way to get path-params when using ENDPOINT_ASYNC

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

The docker sample only supports amd64, not arm64

When trying to do docker build, the following errors show.

Sending build context to Docker daemon  125.4kB
Step 1/9 : FROM lganzzzo/alpine-cmake:latest
 ---> da855beef942
Step 2/9 : ADD . /service
 ---> 45872300ffdc
Step 3/9 : WORKDIR /service/utility
 ---> [Warning] The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
 ---> Running in c0f95febd542
Removing intermediate container c0f95febd542
 ---> 52637d5a0fac
Step 4/9 : RUN ./install-oatpp-modules.sh
 ---> [Warning] The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
 ---> Running in a352194e33a0
exec /bin/sh: exec format error
The command '/bin/sh -c ./install-oatpp-modules.sh' returned a non-zero code: 1
Unable to find image 'example-async-api:latest' locally
docker: Error response from daemon: pull access denied for example-async-api, repository does not exist or may require 'docker login': denied: requested access to the resource is denied.
See 'docker run --help'.

Is it possible to support arm64 or another platform too?

How to set application type as application/json when using ENDPOINT_ASYNC?

Hi Leonid,

I'm using ENDPOINT_ASYNC to support APIs in the project, like an example below.

ENDPOINT_ASYNC("POST", "{path-param}/rangedata", getRangeData) {

       ENDPOINT_ASYNC_INIT(getRangeData)
       String pathParam;

       Action act() override {
            pathParam = request->getPathVariable("path-param");
            return request->readBodyToDtoAsync<RangeRequestDto>(controller->getDefaultObjectMapper())
               .callbackTo(&getRangeData::onBodyObtained);
       }

       Action onBodyObtained(const RangeRequestDto::ObjectWrapper& requestDto) {    
               
           OATPP_LOGD("MyApp", "Received clientId value=%s", pathParam->std_str().c_str());
           OATPP_LOGD("MyApp", "Received value for sensorID=%s", requestDto->sensorID->std_str().c_str());

           std::string sensorName = "sensor:";
           sensorName += requestDto->sensorID->std_str();

           /*Get the data from Redis Instance*/
           auto redisConnection = RedisHandler::getInstance();
           std::vector<float>valueList; 
           redisConnection->redisZRANGE(sensorName, 0, std::stoi(requestDto->timeRange->std_str()), valueList);
           auto responseDto = RangeResponseDto::createShared();
           if(valueList.size()>0)
           {
            for(auto i: valueList)
                responseDto->readings->pushBack(i);
           }    
           /* return result */
           return _return(controller->createDtoResponse(Status::CODE_201, responseDto));
      }   

};

Here, valueList is filled with string values, which is temperature reading from a sensor.

The values are then pushed in to the readings list of the DTO.

The DTO for the same is as below,

class RangeResponseDto : public oatpp::data::mapping::type::Object {

DTO_INIT(RangeResponseDto, Object /* Extends */)

DTO_FIELD(List::ObjectWrapper, readings) = List::createShared();

};

I would like to know how to set application type as JSON in the header for this response.

  • Thanks,
    Puneet

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.