oatpp/changelog/1.4.0.md
2024-05-14 06:44:43 +03:00

6.1 KiB

Oat++ 1.4.0

Previous release - 1.3.0

Feel free to ask questions - Chat on Gitter!

Contents:

C++ standard 17

Oat++ 1.4.0 requires C++ 17.

URL Encoder And Decoder

#include "oatpp/encoding/Url.hpp"

...

oatpp::String data = "Hello URL-Encoder!!!";

oatpp::encoding::Url::Config config;
auto encoded = oatpp::encoding::Url::encode(data, config);
auto decoded = oatpp::encoding::Url::decode(encoded);

OATPP_ASSERT(decoded == data)

Note: Oat++ does NOT automatically decode URL and its parameters on endpoint hit.

Async Condition Variable

#include "oatpp/async/ConditionVariable.hpp"

  ...
  
  oatpp::async::Lock* m_lock;
  oatpp::async::ConditionVariable* m_cv;
  
  ...
  
  Action act() override {
    return m_cv->waitFor(m_lock, // async::Lock
                         [this]{return m_resource->counter == 100;}, // condition
                         std::chrono::seconds(5)) // timeout
           .next(finish());
  }
  ...

oatpp::Tree

New mapping-enabled type oatpp::Tree for flexible data access.

ENDPOINT("POST", "users", createUser,
         BODY_DTO(oatpp::Tree, user))
{
  oatpp::String name = user["name"];
  v_uint16 age = user["age"];
  
  auto& subs = user["subscriptions"].getVector();
  for(auto& s : subs) {
    ...
  }
  ...
}

Any node of oatpp::Tree can be mapped to DTO or to any mapping-enabled oatpp type - see Remapper

Remapper

oatpp::data::mapping::Remapper.

Remapper can be user to remap any oatpp type to any oatpp type. UnorderedFields can be mapped to DTOs, DTOs to vectors of values, vector items to other DTOs, DTOs to Trees, etc...

class User : public oatpp::DTO {
  
  DTO_INIT(User, DTO)
  
  DTO_FIELD(String, name);
  DTO_FIELD(UInt32, age);
  
};

...

oatpp::data::mapping::Remapper remapper;

auto user = User::createShared();
user->name = "Jane";
user->age = "25";

auto tree = remapper.remap<oatpp::Tree>(user); // remap to tree
auto fields = remapper.remap<oatpp::Fields<oatpp::Tree>>(user); // remap to Fields 
auto otherDto = remapper.remap<oatpp::Object<OtherDto>>(user); // remap to OtherDto
auto values = remapper.remap<oatpp::Vector<oatpp::Tree>>(user); // remap to Vector

oatpp::String name = values[0];
v_uint32 age = values[1];

oatpp::web::mime::ContentMappers

Now ApiController can be provided with ContentMappers object for automatic DTO mapper selection based on Content-Type/Accept headers.

Create ContentMappers object

  OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::web::mime::ContentMappers>, apiContentMappers)([] {
    auto mappers = std::make_shared<oatpp::web::mime::ContentMappers>();
    mappers->putMapper(std::make_shared<oatpp::json::ObjectMapper>()); // add json mapper
    mappers->putMapper(std::make_shared<oatpp::xml::ObjectMapper>()); // add xml mapper (NOT released yet)
    return mappers;
  }());

Inject ContentMappers in Controller

  UserController(OATPP_COMPONENT(std::shared_ptr<oatpp::web::mime::ContentMappers>, contentMappers))
    : oatpp::web::server::api::ApiController(contentMappers)
  {}

Automatic mapping

  ENDPOINT("POST", "users", createUser,
           BODY_DTO(Object<UserDto>, userDto), // UserDto mapped according to 'Content-Type' header
           REQUEST(std::shared_ptr<IncomingRequest>, request))
  {
    return createDtoResponse(Status::CODE_200, 
                             m_userService.createUser(userDto), 
                             request->getHeaderValues("Accept")); // response DTO mapped according to 'Accept' header
  }

New OATPP_LOGx format

Now oatpp logs are type-safe. Also log formatting changed.

Macro

old logs new logs
OATPP_LOGV OATPP_LOGv
OATPP_LOGD OATPP_LOGd
OATPP_LOGI OATPP_LOGi
OATPP_LOGW OATPP_LOGw
OATPP_LOGE OATPP_LOGe

Formatting

Instead of old formatting "%s", "%d", "%f" use "{}" for any variable type:

OATPP_LOGd("MyController", "User: name={}, age={}", user->name, user->age)

Restructuring

Files

old file new file
oatpp/parser/json/* oatpp/json/*
oatpp/parser/json/mapping/* oatpp/json/*
oatpp/algorithm/CRC.hpp oatpp/utils/CRC32.hpp
oatpp/core/utils/* oatpp/utils/*
oatpp/core/utils/ConversionUtils.hpp oatpp/utils/Conversion.hpp
oatpp/core/macro/* oatpp/macro/*
oatpp/core/async/* oatpp/async/*
oatpp/core/Types.hpp oatpp/Types.hpp
oatpp/core/IODefinitions.hpp oatpp/IODefinitions.hpp
oatpp/core/base/Environment.hpp oatpp/Environment.hpp
oatpp/core/base/* oatpp/base/*
oatpp/core/concurrency/* oatpp/concurrency/*
oatpp/core/provider/* oatpp/provider/*
oatpp/core/data/* oatpp/data/*
oatpp/core/parser/* oatpp/utils/parser/*
oatpp/data/mapping/type/* oatpp/data/type/*

Namespaces

old namespace new namespace
oatpp::parser::json::* oatpp::json::*
oatpp::parser::json::mapping::* oatpp::json::*
oatpp::algorithm::CRC oatpp::utils::CRC32
oatpp::data::mapping::type::* oatpp::data::type::*