Browse Source

Update 1.3.0.md

Leonid Stryzhevskyi 2 years ago
parent
commit
97d7597112
1 changed files with 134 additions and 0 deletions
  1. 134 0
      changelog/1.3.0.md

+ 134 - 0
changelog/1.3.0.md

@@ -9,6 +9,9 @@ Contents:
 - [The New oatpp::String](#the-new-oatppstring)
 - [ConnectionPool::get() Timeout](#connectionpoolget-timeout)
 - [JSON Serializer Escape Flags](#json-serializer-escape-flags)
+- [Headers Stored In unordered_multimap](#headers-stored-in-unordered_multimap)
+- [QueryParameters Stored In unordered_multimap](#queryparameters-stored-in-unordered_multimap)
+- [Polymorphic DTO_FIELD](#polymorphic-dto_field)
 - [ConnectionMonitor](#connectionmonitor)
 - [Request Data Bundle](#request-data-bundle)
 - [ConnectionProviderSwitch](#connectionproviderswitch)
@@ -146,6 +149,137 @@ Output:
 res='"https://oatpp.io/"' # solidus isn't escaped
 ```
 
+## Headers Stored In unordered_multimap
+
+Headers are now stored using [std::unordered_multimap](https://en.cppreference.com/w/cpp/container/unordered_multimap).
+
+Put multiple headers:
+
+```cpp
+auto response = createResponse(Status::CODE_200, "");
+response->putHeader("Set-Cookie", "...");
+response->putHeader("Set-Cookie", "...");
+return response;
+```
+
+Log all "Set-Cookie" headers:
+
+```cpp
+  const auto& map = headers.getAll();
+  auto bucket = map.bucket("Set-Cookie");
+  auto bucketBegin = map.begin(bucket);
+  auto bucketEnd = map.end(bucket);
+
+  for(auto it = bucketBegin; it != bucketEnd; it ++) {
+    oatpp::String value = it->second.toString();
+    OATPP_LOGD("Header", "Set-Cookie: %s", value->c_str());
+  }
+```
+
+## QueryParameters Stored In unordered_multimap
+
+QueryParameters are now stored using [std::unordered_multimap](https://en.cppreference.com/w/cpp/container/unordered_multimap).
+
+Log all entries of "userId" query parameter:
+
+```cpp
+  const auto& map = request->getQueryParameters().getAll();
+  auto bucket = map.bucket("userId");
+  auto bucketBegin = map.begin(bucket);
+  auto bucketEnd = map.end(bucket);
+
+  for(auto it = bucketBegin; it != bucketEnd; it ++) {
+    oatpp::String value = it->second.toString();
+    OATPP_LOGD("QueryParameter", "userId: %s", value->c_str());
+  }
+```
+
+## Polymorphic DTO_FIELD
+
+Now, when used inside of a DTO, we can specify exact types that `oatpp::Any` can store by specifying `DTO_FIELD_TYPE_SELECTOR`:
+
+```cpp
+/* Possible type of a DTO_FIELD */
+class ClassA : public oatpp::DTO {
+
+  DTO_INIT(ClassA, DTO)
+
+  DTO_FIELD(String, value);
+
+};
+
+/* Possible type of a DTO_FIELD */
+class ClassB : public oatpp::DTO {
+
+  DTO_INIT(ClassB, DTO)
+
+  DTO_FIELD(Vector<String>, values);
+
+};
+
+/* enum of possible DTO_FIELD types */
+ENUM(ClassType, v_int32,
+     VALUE(CLASS_TYPE_A, 0),
+     VALUE(CLASS_TYPE_B, 1)
+)
+
+/* our DTO */
+class ResponseDto : public oatpp::DTO {
+
+  DTO_INIT(ResponseDto, DTO)
+
+  /* type control field */
+  DTO_FIELD(Enum<ClassType>::AsString, payloadType);
+  
+  /* polymorphic field */
+  DTO_FIELD(Any, payload);
+
+  /* type selector */
+  DTO_FIELD_TYPE_SELECTOR(payload) {
+    if(!payloadType) return Void::Class::getType();
+    switch (*payloadType) {
+      case ClassType::CLASS_TYPE_A: return Object<ClassA>::Class::getType();
+      case ClassType::CLASS_TYPE_B: return Object<ClassB>::Class::getType();
+    }
+  }
+
+};
+
+...
+
+/* send polymorphic payload to client */
+ENDPOINT("GET", "payload", getPayload) {
+
+  auto payload = ClassB::createShared();
+  payload->values = {"value1", "value2", "value3"};
+
+  auto r = ResponseDto::createShared();
+  r->payloadType = ClassType::CLASS_TYPE_B;
+  r->payload = payload;
+
+  return createDtoResponse(Status::CODE_200, r);
+
+}
+  
+/* receive polymorphic payload from client */
+ENDPOINT("POST", "payload", postPayload,
+         BODY_DTO(oatpp::Object<ResponseDto>, r))
+{
+
+  /* check type-control field and retrieve value of the corresponding type */
+  if(r->payloadType == ClassType::CLASS_TYPE_B) {
+    auto payload = r->payload.retrieve<oatpp::Object<ClassB>>();
+    for(auto& value : *payload->values) {
+      OATPP_LOGD("VALUE", "%s", value->c_str());
+    }
+  }
+
+  return createResponse(Status::CODE_200, "OK");
+
+}
+  
+```
+
 ## ConnectionMonitor
 
 `oatpp::network::monitor::ConnectionMonitor` is a middleman who's able to monitor provided connections and close those ones that not satisfy selected rules.