Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
    oat++
    @oatpp_io_twitter
    Hello @MJLHThomassen-Sorama ,
    response->putHeader("Custom-Timestamp", "1234");
    response->putHeader("Custom-Timestamp", oatpp::utils::conversion::int64ToStr(1234)); // #include "oatpp/core/utils/ConversionUtils.hpp"
    MJLHThomassen-Sorama
    @MJLHThomassen-Sorama
    thanks!
    kapilpipaliya
    @kapilpipaliya
    error: non-constant condition for static assertion when i use arangodb::velocypack::Slice. i think its not copyable.
    oat++
    @oatpp_io_twitter

    Hello @kapilpipaliya ,

    Not sure I understand the question, and how it relates to oatpp.
    Please specify.

    Thanks

    DF-Dave
    @DF-Dave

    Hello, i have a problem/question with your DTO component of oat++. I try to generate an packet with different types of objects but I can't assign inherited classes. I show you my problem with a little example

    ...

    class Param : public oatpp::data::mapping::type::Object
    {
    DTO_INIT(Param , Object)
    };

    class RealParam : public Param
    {
    DTO_INIT(RealParam, Param)

    DTO_FIELD(Int32, magic);

    };

    class Packet : public oatpp::data::mapping::type::Object
    {
    DTO_INIT(Packet, Object)

    DTO_FIELD(List<Param::ObjectWrapper>::ObjectWrapper, params) 
        = List<Param::ObjectWrapper>::createShared();

    };

    ...

    When I try to add an instance (ObjectWrapper) of type RealParam to the list of Packet, I only get an error message from the compiler that there is no known conversion from RealParam::ObjectWrapper to Param::ObjectWrapper. Is there a way to explicitly cast the object or am I still making a mistake somewhere?

    oat++
    @oatpp_io_twitter

    Hello @DF-Dave ,

    It is possible to cast ObjectWrapper using oatpp::data::mapping::type::static_wrapper_cast, and it will compile:

    class Param : public oatpp::data::mapping::type::Object {
    
      DTO_INIT(Param , Object);
    
    };
    
    class RealParam : public Param {
    
      DTO_INIT(RealParam, Param)
    
      DTO_FIELD(Int32, magic);
    
    };
    
    class Packet : public oatpp::data::mapping::type::Object {
    
      DTO_INIT(Packet, Object)
    
      DTO_FIELD(List<Param::ObjectWrapper>::ObjectWrapper, params) = List<Param::ObjectWrapper>::createShared();
    
    };
    
    ...
    
    auto packet = Packet::createShared();
    auto realParam = RealParam::createShared();
    realParam->magic = 10;
    
    Param::ObjectWrapper param = oatpp::data::mapping::type::static_wrapper_cast<Param>(realParam);
    
    packet->params->pushBack(param);

    But the output will miss the magic int32 number:

    {
      "params": [
        {}
      ]
    }
    The point here is that you can't serialize things that you won't be able to deserialize
    Because if you serialize a child class as a parent, you won't have any info during the deserialization about what child class it was originally
    So it is a restriction. And it is an expected behavior here.
    So here DTO_FIELD(List<Param::ObjectWrapper>::ObjectWrapper, params) in the Param inside <> brackets is the actual model of the object that should be serialized. Serializer won't know about other fields present in the child.
    oat++
    @oatpp_io_twitter

    Hope I answered your question.
    Please let me know if you have more questions.

    Regards,
    Leonid

    DF-Dave
    @DF-Dave
    Thank you for your answer but I see the problem. But then I have another question can I use templates within the CODEGEN_MACROS so I can put a template at the packet and specify it's list type variable?
    oat++
    @oatpp_io_twitter

    Not sure if I understand correctly...

    The point is that the template parameter in the list should define the exact type of the object that you want to serialize.

    You can just do like this:

    class Param : public oatpp::data::mapping::type::Object {
    
      DTO_INIT(Param , Object);
    
    };
    
    class RealParam : public Param {
    
      DTO_INIT(RealParam, Param)
    
      DTO_FIELD(Int32, magic);
    
    };
    
    class Packet : public oatpp::data::mapping::type::Object {
    
      DTO_INIT(Packet, Object)
    
      DTO_FIELD(List<RealParam::ObjectWrapper>::ObjectWrapper, params) = List<RealParam::ObjectWrapper>::createShared();
    
    };

    Then, your serializer will serialize all the fields taking into account the base class inheritance.

    Or you mean if it's possible to templatize the DTO object?
    DF-Dave
    @DF-Dave
    yeah I mean to templatize the DTO object
    oat++
    @oatpp_io_twitter
    Let me try...
    oat++
    @oatpp_io_twitter
    Ok, I did it, but it looks pretty ugly. I had to introduce a bunch of typedefs:
    template<class T>
    class Param : public oatpp::data::mapping::type::Object {
    
      DTO_INIT(Param , Object);
    
      DTO_FIELD(T, templateParam);
    
    };
    
    template<class T>
    class Packet : public oatpp::data::mapping::type::Object {
    
      DTO_INIT(Packet, Object)
    
      typedef List<typename Param<T>::ObjectWrapper> ListOfParams;
      typedef typename ListOfParams::ObjectWrapper ListOfParams_ObjectWrapper;
    
      DTO_FIELD(ListOfParams_ObjectWrapper, params) = ListOfParams::createShared();
    
    };
    
    ...
    
      auto packet = Packet<oatpp::String>::createShared();
    
      auto param = Param<oatpp::String>::createShared();
      param->templateParam = "Hello";
    
      packet->params->pushBack(param);
    The output:
    {
      "params": [
        {
          "templateParam": "Hello"
        }
      ]
    }
    at least it's possible:)
    DF-Dave
    @DF-Dave
    ok thank you that helped me a lot :)
    oat++
    @oatpp_io_twitter
    You are welcome! Just ping me,- I'll be happy to help
    oat++
    @oatpp_io_twitter

    @/all ,
    Update :bell:

    The new release with all the November changes is finally shipped 0.19.11.

    Changelog

    oatpp

    • ApiClient. Introduce retries and RetryPolicy.
    • oatpp::network::virtual_::Interface. Introduce ListenerLock to acquire an interface for listening (analog to bind on a port).
    • oatpp::parser::json::mapping::Serializer. Remove extra space char.
    • oatpp::parser::json::mapping::Serializer. Introduce Beautifier and Beautifier config.
    • Introduce v_buff_size for buffer sizes, as an integer capable of storing a pointer.
    • Introduce oatpp::data::stream::Context to store aditional data about the stream.
    • oatpp::network::server::SimpleTCPConnectionProvider. Add feature to obtain peer IP and port available through the connection stream context.

    oatpp-libressl

    • Better portability.
    • Windows compatibility.
    • Support TLS over custom transport.
    • Require LibreSSL minimum version 3.0.0.

    oatpp-mbedtls

    • Fix acceptor-thread blocking by handshake. TLS Handshake is moved to the stream context initialization.

    Relevant documentation:


    Cheers :tada:
    Leonid

    BossZou
    @BossZou
    How I use NON-BLOCKING I/O in my server? I found examples of async used SimpleTCPConnectionProvider and it seems to be BLOCKING I/O. How I make server NON-BLOCKING?
    oat++
    @oatpp_io_twitter

    Hello @BossZou ,

    example-async-api - is exactly what you need.
    No matter what ConnectionProvider is used - when you use AsyncHttpConnectionHandler, it will put accepted connection in the NON-BLOCKING mode and then pass it to the processing coroutine.

    Also, you should be careful not to put any blocking code inside the processing coroutine.

    Regards,
    Leonid

    Amit Kumar
    @theamitk_twitter
    Hello
    oat++
    @oatpp_io_twitter
    Hello @theamitk_twitter , welcome to Oat++ dev community!
    oat++
    @oatpp_io_twitter

    Hey @/all ,
    Update :bell:

    The new BIG stabilization release is now available 0.19.12

    Features and Bug-Fixes

    • Introduce oatpp::data::buffer::Processor and oatpp::data::buffer::ProcessingPipeline for stream chunk-by-chunk processing.
    • Fix server stop() when using oatpp::network::server:: SimpleTCPConnectionProvider. Now server can be properly stopped without additional workarounds.
    • Fix tests inconsistency.
    • Fix a bunch of IO bugs (mostly for Windows).

    Architecture Changes

    • Move IODefinitions.hpp to the root. Move v_io_size, v_io_handle and IOError to the oatpp namespace.
    • Upgrade streams interfaces (to provide nesting and pipelining of any complexity):
      • InputStream now extends ReadCallback
      • OutputStream now extends WriteCallback
      • read/write methods now extended with additional parameter async::Action&.
      • suggestInputStreamAsyncAction / suggestOutputStreamAsyncAction removed.

    Changes Exposed to End-User

    • Rename oatpp::data::v_io_size to oatpp::v_io_size.
    • Rename oatpp::data::v_io_handle to oatpp::v_io_handle.
    • Rename oatpp::data::IOError to oatpp::IOError.
    • Use writeSimple instead of write for ConsistentOutputStreams - ChunkedBuffer and BufferOutputStream.
    • Server stop(). Now additional call to client::ConnectionProvider::getConnection() method is not needed in order to unblock accept and stop the server.

    You are highly recommended to update your applications to the new Oat++ version.


    Note: this is the last "pre" release - next is going to be version 1.0.0. As it took longer than expected to deliver 0.19.12, the 1.0.0 is shifted to the end of Jan - mid-Feb.

    Cheers :tada:
    Leonid

    rrajpaul
    @rrajpaul
    Is possible to do an example for mongodb?
    If I want to contribute to the project how do I go about it.
    oat++
    @oatpp_io_twitter

    Hello @rrajpaul , and welcome to the oatpp devs community!

    Is possible to do an example for mongodb?

    MongoDB example is a very good idea, as oatpp and MongoDB is the perfect match.

    If I want to contribute to the project how do I go about it.

    The best way to contribute is to add things that you need and things that others might need too.

    You could possibly start contributing by adding the MongoDB example.
    There is a beautiful module created by @bhorn - oatpp-mongocxxmapper, for mapping oatpp DTOs to/from mongo objects.
    It should be pretty straight forward - just take the oatpp-starter + oatpp-mongocxxmapper and put things together. You would probably need to update the module too.

    Please let me know if have more questions.

    Regards,
    Leonid

    rrajpaul
    @rrajpaul
    Thanks for the suggestion, I was unaware of oatpp-mongocxxmapper. I will give it a go as I am really trying to improve my c++ skills. I have built web api using MS >net Core 2.1/2.2 and it is very easy with some experience but not at all easy in c++

    Again thanks for your help

    Ryan

    oat++
    @oatpp_io_twitter
    Cool, just try to make it work, and if you stuck - ping me, I'll be happy to help.
    Thomas Denoréaz
    @ThmX
    Hi everybody! Say I have a small question concerning the custom mapping: is there a way to use an enum for a field? If yes, is there an example out there? If not, do you have any pointers such that I can create an example and maybe add it to the documentation?
    oat++
    @oatpp_io_twitter
    Hello @ThmX ,
    Unums are not in the set of default available mapping-enabled types.
    So yes, you'll have to implement a custom ObjectMapper to support your enum type ...
    Thomas Denoréaz
    @ThmX
    Thanks for the fast answer! I'll do that then :) Is there any example of how to implement a custom ObjectMapper? The documentation told me to come here :'D
    oat++
    @oatpp_io_twitter
    The basic approach for creating custom ObjectMapper is:

    Create a type metadata

    #include "oatpp/core/Types.hpp"
    
    namespace myapp {
    
      typedef oatpp::data::mapping::type::Type Type;
    
      namespace __class {
    
          class MyEnum {
          public:
            constexpr static const char* const CLASS_NAME = "myapp::MyEnum";
    
            static Type* getType(){
              static Type type(CLASS_NAME, nullptr);
              return &type;
            }
    
          };
    
      }
    
    }

    Is there any example of how to implement a custom ObjectMapper? The documentation told me to come here :'D

    Yep, you are in the right place - just give me a few minutes to prepare code-snippets :)

    oat++
    @oatpp_io_twitter

    Declare the ObjectWrapper for your type:

    enum MyEnumType : int {
      a = 1,
      b = 2
    };
    
    typedef oatpp::data::mapping::type::ObjectWrapper<MyEnumType, __class::MyEnum> MyMappingEnabledEnum;
    Thomas Denoréaz
    @ThmX
    Hmm forgot to add: the use case is to use it with oatpp-swagger, would that work or should I also write some kind of "swagger spec generator" for this type?
    oat++
    @oatpp_io_twitter

    Reference your type in the Serializer/Deserializer

    void Serializer::writeField(oatpp::data::stream::OutputStream* stream, const AbstractObjectWrapper& polymorph) {
    
      const Type* type = polymorph.valueType;
    
      if(type->name == myapp::__class::MyEnum::CLASS_NAME) {
        // TODO serialize enum to stream
      }  else {
        throw std::runtime_error("Unknown data type");
      }
    
    }

    Hmm forgot to add: the use case is to use it with oatpp-swagger, would that work or should I also write some kind of "swagger spec generator" for this type?

    You'll have to add your custom functionality to swagger

    Thomas Denoréaz
    @ThmX
    Great! Thanks a lot!! :)
    oat++
    @oatpp_io_twitter
    You are welcome!
    And here is where types are referenced in swagger https://github.com/oatpp/oatpp-swagger/blob/master/src/oatpp-swagger/oas3/Generator.cpp#L73
    Please let me know if you have more questions
    oat++
    @oatpp_io_twitter

    Hey @/all ,
    Update :bell:

    The new oatpp/oatpp#182 was merged to master - providing support for Content-Encoding and Accept-Encoding headers.

    Also oatpp-zlib module is now available.

    The API

    In order to add encoders/decoders available for your server, all you need to do is to update AppComponents file. No changes need to be done to user-endpoints code.

    AppComponents.hpp

    #include "oatpp-zlib/EncoderProvider.hpp"
    
    ...
    
      OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::network::server::ConnectionHandler>, serverConnectionHandler)([] {
    
        OATPP_COMPONENT(std::shared_ptr<oatpp::web::server::HttpRouter>, router); // get Router component
    
        /* Create HttpProcessor::Components */
        auto components = std::make_shared<oatpp::web::server::HttpProcessor::Components>(router);
    
        /* Add content encoders */
        auto encoders = std::make_shared<oatpp::web::protocol::http::encoding::ProviderCollection>();
    
        encoders->add(std::make_shared<oatpp::zlib::DeflateEncoderProvider>());
        encoders->add(std::make_shared<oatpp::zlib::GzipEncoderProvider>());
    
        components->contentEncodingProviders = encoders;
    
        /* Add content decoders */
        auto decoders = std::make_shared<oatpp::web::protocol::http::encoding::ProviderCollection>();
    
        decoders->add(std::make_shared<oatpp::zlib::DeflateDecoderProvider>());
        decoders->add(std::make_shared<oatpp::zlib::GzipDecoderProvider>());
    
        components->bodyDecoder = std::make_shared<oatpp::web::protocol::http::incoming::SimpleBodyDecoder>(decoders);
    
        /* return HttpConnectionHandler */
        return std::make_shared<oatpp::web::server::HttpConnectionHandler>(components);
    
      }());
    
    ...

    Refs:


    Cheers :tada:
    Leonid

    Benedikt-Alexander Mokroß
    @bhorn
    Hey @rrajpaul have you tried the mapper? I haven't touched it in a while since Leonid and I decided to implement a more generic bson mapper (which then should be compatible with mongodb, too).