1.2.0.md 7.3 KB

Oat++ 1.2.0

Feel free to ask questions - Chat on Gitter

Contents:

Continuous Multipart Streaming

Now it's possible to continuously stream multipart data to the client. For example, you can implement multipart/x-mixed-replace video stream.

Both Simple-APIs and Async-APIs available.

using namespace oatpp::web::mime::multipart;

class MPStream : public Multipart {
public:

  MPStream()
    : Multipart(generateRandomBoundary())
  {}

  std::shared_ptr<Part> readNextPart(async::Action& action /* For Simple-API action is ignored */) override {

    std::this_thread::sleep_for(std::chrono::seconds(1)); // For Simple-API you may sleep just like that

    oatpp::String frameData = "<frame-binary-jpeg-data>" // frame data. One jpeg image.

    auto part = std::make_shared<Part>();
    part->putHeader(Header::CONTENT_TYPE, "image/jpeg");
    part->setDataInfo(std::make_shared<oatpp::data::stream::BufferInputStream>(frameData));

    return part;

  }

  void writeNextPart(const std::shared_ptr<Part>& part, async::Action& action) override {
    throw std::runtime_error("No writes here!!!");
  }

};

ENDPOINT("GET", "multipart-stream", multipartStream) {
  auto multipart = std::make_shared<MPStream>();
  auto body = std::make_shared<oatpp::web::protocol::http::outgoing::MultipartBody>(
    multipart,
    "multipart/x-mixed-replace",
    true /* flush parts */
  );
  return OutgoingResponse::createShared(Status::CODE_200, body);
}

Changes In ConnectionProvider Interface

Both oatpp::network::ServerConnectionProvider and oatpp::network::ClientConnectionProvider are now subclasses of a general oatpp::provider::Provider<data::stream::IOStream> class.

Renamed methods:

  • getConnection() --> get()
  • getConnectionAsync() --> getAsync()
  • invalidateConnection() --> invalidate()

This was done to unify providers' APIs and to have same API for all resource providers and resource pools.
Connection Providers and Connection Pools of the new ORM database adaptors are implemented based on the same functionality.

More info on ConnectionProvider changes see here - Changes in oatpp::network Namespace.

Type Interpretations

To simplify the integration of custom types with oatpp Object-Mapping framework the the "Type Interpretation" feature was introduced.

Let's say you have some struct that is not part of oatpp object-mapping framework.

struct VPoint {
  v_int32 x;
  v_int32 y;
  v_int32 z;
};

To integrate it with oatpp object-mapping you can do the following:

namespace __class {
  class PointClass;
}

/* Declare ObjectWrapper for your type */
/* Mapping-Enabled Point */
typedef oatpp::data::mapping::type::Primitive<VPoint, __class::PointClass> Point;

namespace __class {

  /**
   * Type info
   */
  class PointClass {
  private:

    /**
     * Type interpretation
     */
    class Inter : public oatpp::Type::Interpretation<Point, oatpp::UnorderedFields<oatpp::Int32>>  {
    public:

      oatpp::UnorderedFields<oatpp::Int32> interpret(const Point& value) const override {
          return {{"x", value->x}, {"y", value->y}, {"z", value->z}};
      }

      Point reproduce(const oatpp::UnorderedFields<oatpp::Int32> map) const override {
        return Point({map["x"], map["y"], map["z"]});
      }

    };

  public:

    static const oatpp::ClassId CLASS_ID;

    static oatpp::Type* getType(){
      static Type type(
        CLASS_ID, nullptr, nullptr,
        {
          {"my-types", new Inter()} //<-- Add type interpretation
        }
      );
      return &type;
    }

  };

  const oatpp::ClassId PointClass::CLASS_ID("my-types::Point");

}

Now the "Point" struct can be serialized/deserialized with object mappers.

oatpp::parser::json::mapping::ObjectMapper mapper;

{
  auto config = mapper.getSerializer()->getConfig();
  config->enabledInterpretations = {"my-types"}; // Enable "my-types" for serializer
}

{
  auto config = mapper.getDeserializer()->getConfig();
  config->enabledInterpretations = {"my-types"}; // Enable "my-types" for deserializer
}

Point point ({1, 2, 3}); // Create mapping-enabled Point

auto json = mapper.writeToString(point); // Serialize Point
auto pointClone = mapper.readFromString<Point>(json); // Deserialize Point

ORM

The main feature of the 1.2.0 release is the new ORM Framework.
For details see - Object-Relational Mapping (ORM) framework

ORM Adaptors

Changes in oatpp::network Namespace

Moved and Renamed

  • oatpp::network::server::SimpleTCPConnectionProvider --> oatpp::network::tcp::server::ConnectionProvider
  • oatpp::network::client::SimpleTCPConnectionProvider --> oatpp::network::tcp::client::ConnectionProvider
  • oatpp::network::server::ConnectionHandler --> atpp::network::ConnectionHandler
  • oatpp::network::server::Server --> oatpp::network::Server
  • oatpp::network::Connection --> oatpp::network::tcp::Connection

New Classes

  • oatpp::network::Address

New Constructors for Connection Providers

oatpp::network::tcp::server::ConnectionProvider

oatpp::network::tcp::server::ConnectionProvider::createShared(
  {"localhost", 8000} /* network::Address */
);

oatpp::network::tcp::server::ConnectionProvider::createShared(
  {"localhost", 8000, oatpp::network::Address::IP_4} /* network::Address */
);

oatpp::network::tcp::server::ConnectionProvider::createShared(
  {"localhost", 8000, oatpp::network::Address::IP_4} /* network::Address */,
  true /* use extended connections */
);

oatpp::network::tcp::client::ConnectionProvider

oatpp::network::tcp::client::ConnectionProvider::createShared(
  {"localhost", 8000} /* network::Address */
);

oatpp::network::tcp::client::ConnectionProvider::createShared(
  {"localhost", 8000, oatpp::network::Address::IP_4} /* network::Address */
);

oatpp::network::tcp::client::ConnectionProvider::createShared(
  {"localhost", 8000, oatpp::network::Address::IP_4} /* network::Address */,
  true /* use extended connections */
);

New Modules

  • oatpp-sqlite - SQLite adapter for Oat++ ORM. Full support.
  • oatpp-postgresql - Oat++ ORM adapter for PostgreSQL. Alpha version.
  • oatpp-protobuf - Protobuf integration with oatpp object-mapping framework. Use protobuf objects as regular oatpp DTOs. Serialize/Deserialize protobuf object to/from JSON, BSON and other oatpp supported formats.