Signed-off-by: Ferry Huberts <ferry.huberts@pelagic.nl>
6.5 KiB
Oat++ 1.2.5
Previous release - 1.2.0
Feel free to ask questions - Chat on Gitter!
Contents:
- Introduce ResponseInterceptor
- Enable Global CORS
- Headers Multimap
- Better Router API
- ORM Clean Section
- ORM PostgreSQL - Arrays Support
- Swagger-UI Example Values
- New Modules
Introduce ResponseInterceptor
Declare Response Interceptor
#include "oatpp/web/server/interceptor/ResponseInterceptor.hpp"
class MyResponseInterceptor : public ResponseInterceptor {
public:
std::shared_ptr<OutgoingResponse> intercept(const std::shared_ptr<IncomingRequest>& request,
const std::shared_ptr<OutgoingResponse>& response) override
{
// TODO modify response or create a new one
return response; // return modified response
// returning nullptr will result in an error
}
};
Register global request interceptor
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::network::ConnectionHandler>, serverConnectionHandler)([] {
OATPP_COMPONENT(std::shared_ptr<oatpp::web::server::HttpRouter>, router);
auto connectionHandler = oatpp::web::server::HttpConnectionHandler::createShared(router);
/* Add MyResponseInterceptor */
connectionHandler->addResponseInterceptor(std::make_shared<MyResponseInterceptor>());
return connectionHandler;
}());
Enable Global CORS
To enable global CORS for all endpoints:
- Add Request Interceptor -
oatpp::web::server::interceptor::AllowOptionsGlobal
toConnectionHandler
. - Add Response Interceptor -
atpp::web::server::interceptor::AllowCorsGlobal
toConnectionHandler
.
#include "oatpp/web/server/interceptor/AllowCorsGlobal.hpp"
...
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::network::ConnectionHandler>, serverConnectionHandler)([] {
OATPP_COMPONENT(std::shared_ptr<oatpp::web::server::HttpRouter>, router); // get Router component
auto connectionHandler = oatpp::web::server::HttpConnectionHandler::createShared(router);
/* Add CORS-enabling interceptors */
connectionHandler->addRequestInterceptor(std::make_shared<oatpp::web::server::interceptor::AllowOptionsGlobal>());
connectionHandler->addResponseInterceptor(std::make_shared<oatpp::web::server::interceptor::AllowCorsGlobal>());
return connectionHandler;
}());
Headers Multimap
Now headers are stored using std::multimap and can store multiple entries with the same key.
Put multiple headers:
auto response = createResponse(Status::CODE_200, "");
response->putHeader("Set-Cookie", "...");
response->putHeader("Set-Cookie", "...");
return response;
Log all "Set-Cookie" headers:
const auto& map = headers.getAll();
auto itlow = map.lower_bound("Set-Cookie");
auto itup = map.upper_bound("Set-Cookie");
for(auto it = itlow; it != itup; it ++) {
oatpp::String value = it->second.toString();
OATPP_LOGD("Header", "Set-Cookie: %s", value->c_str())
}
Better Router API
Now Router class is a template and can store any value-types and not only RequestHandler
s.
Example use-case - check if endpoint should require authorization:
Add Routs
oatpp::web::server::HttpRouterTemplate<bool> authEndpoints;
authEndpoint.route("POST", "login", false); // DO NOT require auth for /login path
authEndpoint.route("POST", "auth", false); // DO NOT require auth for /auth path
authEndpoint.route("GET", "*", true); // require auth for all GET
authEndpoint.route("POST", "*", true); // require auth for all POST
authEndpoint.route("OPTIONS", "*", false); // DO NOT require auth for OPTIONS
Check Auth
auto r = authEndpoints.getRoute(request->getStartingLine().method, request->getStartingLine().path);
if(r && r.getEndpoint() == true) {
// check auth
}
ORM Clean Section
For modules:
Now it's possible to declare a "clean section" - a section that is untouched by DSL processor.
Clean section begins with <!!
and ends with !!>
.
Note: <!!
and !!>
char sequences are ignored inside string.
Example
Such query:
QUERY(selectUserName,
"SELECT <!! name::varchar !!> FROM users WHERE userId=:userId",
PARAM(String, userId))
Will be processed as follows:
SELECT name::varchar FROM users WHERE userId="<user-id-value>"
Note: unlike the :userId
the :varchar
char-sequence wasn't interpreted as a template parameter (unlike the :userId
).
ORM PostgreSQL - Arrays Support
oatpp-postgresql now supports arrays.
More about PostgreSQL arrays - read here
Swagger-UI Example Values
Now it's possible to add example-values to RequestBody
, Response
, and Parameters
(Path, Headers, Queries)
Add Consumes Examples
ENDPOINT_INFO(myEndpoint) {
info->addConsumes<Object<MyDto>>("application/json")
.addExample("example_1", MyDto::createShared(... /* params here */ ))
.addExample("example_2", MyDto::createShared(... /* params here */ ))
.addExample("example_3", MyDto::createShared(... /* params here */ ));
}
Add Response Examples
ENDPOINT_INFO(myEndpoint) {
info->addResponse<Object<MyDto>>(Status::CODE_200, "application/json")
.addExample("Successful Response_1", MyDto::createShared(... /* params */ ));
info->addResponse<Object<ErrorDto>>(Status::CODE_404, "application/json")
.addExample("Error - Not found", ErrorDto::createShared(404, "Not Found"));
info->addResponse<Object<ErrorDto>>(Status::CODE_500, "application/json")
.addExample("Error - DB Connection", ErrorDto::createShared(500, "Can't connect to DB"))
.addExample("Error - Unknown", ErrorDto::createShared(500, "Unknown Error"));
}
Add Parameter Examples
ENDPOINT_INFO(myEndpoint) {
info->pathParams["userRole"]
.addExample("Admin", oatpp::Enum<UserRole>(UserRole::ADMIN))
.addExample("Guest", oatpp::Enum<UserRole>(UserRole::GUEST));
}
New Modules
- oatpp-openssl - TLS adaptor for OpenSSL (Recommended to use).