6.1 KiB
Oat++ 1.4.0
Previous release - 1.3.0
Feel free to ask questions - Chat on Gitter!
Contents:
- C++ standard 17
- URL Encoder And Decoder
- Introduce async::ConditionVariable
- oatpp::Tree
- Remapper
- oatpp::web::mime::ContentMappers
- New OATPP_LOGx format
- Restructuring
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::* |