
RESTinio adalah pustaka C ++ 14 yang relatif kecil untuk menyematkan server HTTP / WebSocket di aplikasi C ++. Kami telah mencoba membuat RESTinio mudah digunakan, sangat dapat disesuaikan, dengan kinerja yang layak. Dan, tampaknya, sejauh ini ternyata.
Sebelumnya sudah ada artikel tentang RESTinio , namun lebih banyak tentang apa dan bagaimana dilakukan di jeroan ayam itik perpustakaan. Hari ini saya ingin berbicara tentang apa yang muncul di versi baru RESTinio, dan mengapa itu muncul. Dan juga untuk menjelaskan beberapa kata tentang mengapa rilis ini kemungkinan besar akan menjadi pembaruan besar terakhir dalam cabang 0.6. Dan apa yang ingin saya capai saat bekerja di cabang 0.7.
Siapa pun yang tertarik, Anda dipersilakan di bawah kucing.
Fitur utama versi 0.6.13: rantai penangan sinkron
, 2017- RESTinio, HTTP- C++ . , . , RESTinio ExpressJS. express_router RESTinio.
ExpressJS : middleware. - RESTinio .
. RESTinio , - middleware ExpressJS . , middleware RESTinio.
, . .
, 0.6.13 RESTinio . . not_handled
. - accepted
rejected
, .
, , :
- - ;
- HTTP-;
- ( ) , .
:
auto incoming_req_logger(const restinio::request_handle_t & req)
{
... // .
// .
return restinio::request_not_handled();
}
auto mandatory_fields_checker(const restinio::request_handle_t & req)
{
... // .
if(!ok) {
// .
return req->create_response(restinio::status_bad_request())
...
.done(); // accepted.
}
// .
return restinio::request_not_handled();
}
auto permissions_checker(const restinio::request_handle_t & req)
{
... // .
if(!ok) {
// .
return req->create_response(restinio::status_unauthorized())
...
.done(); // accepted.
}
// .
return restinio::request_not_handled();
}
auto actual_processor(const restinio::request_handle_t & req)
{
... // .
return restinio::request_accepted();
}
, .
-, . RESTinio , .
, , fixed_size_chain_t
:
// .
#include <restinio/sync_chain/fixed_size.hpp>
...
struct my_traits : public restinio::default_traits_t {
using request_handler_t = restinio::sync_chain::fixed_size_chain_t<4>;
};
-, :
restinio::run(restinio::on_this_thread<my_traits>()
.port(...)
.address(...)
.request_handler(
// .
incoming_req_logger,
mandatory_fields_checker,
permissions_checker,
actual_processor)
...
);
, , .
?
.
, RESTinio .
, , , RESTinio . RESTinio : , , , , , , -...
, RESTinio , , , , . - RESTinio . , RESTinio . RESTinio, , , : rejected
accepted
.
, . (.. create_response()...done()
) . - , - done()
.
, , accepted
, RESTinio , . - . , - .
RESTinio accepted
, . RESTinio , .
.
RESTinio . , fixed_size_chain_t
— , RESTinio. . RESTinio , RESTinio .
, not_handled
, rejected
, accepted
. ?
. , - .
. .. , - .
- 0.6.13 . .. , . , RESTinio, , - - . , . , , RESTinio.
, - ?
. - . accepted
.
?
, . . 0.6.13 0.6 . , API RESTinio.
. .
, :
- authentification_handler, ;
- permissions_checker, , ;
- admin_access_logger, ;
- actual_processor, .
user_permissions, . permissions_checker- ( ) admin_access_logger ( ).
, , authentification_handler ?
.
/, -:
struct user_permissions {...};
...
// .
struct per_request_data {
user_permissions user_info_;
... // , - .
};
.. extra-data-factory, .. :
struct my_extra_data_factory {
// extra-data-factory data_t.
using data_t = per_request_data;
// .
void make_within(restinio::extra_data_buffer_t<data_t> buf) {
new(buf.get()) data_t{};
}
};
:
struct my_traits : public restinio::default_traits_t {
using extra_data_factory_t = my_extra_data_factory;
};
, , : . restinio::request_handle_t
restinio::generic_request_handle_t<per_request_data>
:
restinio::request_handling_status_t authentification_handler(
const restinio::generic_request_handle_t<per_request_data> & req);
restinio::request_handling_status_t permissions_checker(
const restinio::generic_request_handle_t<per_request_data> & req);
restinio::request_handling_status_t admin_access_logger(
const restinio::generic_request_handle_t<per_request_data> & req);
restinio::request_handling_status_t actual_processor(
const restinio::generic_request_handle_t<per_request_data> & req);
, .
DefaultConstructible , — . stateful-, , . :
// .
struct per_request_data {
std::shared_ptr<log_stream> log_;
per_request_data(std::shared_ptr<log_stream> log)
: log_{std::move(log)}
{}
};
// .
class my_extra_data_factory {
std::shared_ptr<logger> logger_;
public:
using data_t = per_request_data;
my_extra_data_factory(std::shared_ptr<logger> logger)
: logger_{std::move(logger)}
{}
void make_within(restinio::extra_data_buffer_t<data_t> buf) {
new(buf.get()) data_t{
std::make_shared<log_stream>(logger_)
};
}
};
struct my_traits : public restinio::default_traits_t {
using extra_data_factory_t = my_user_data_factory;
};
auto logger = std::make_shared<logger>(...);
// .
restinio::run(restinio::on_thread_pool<my_traits>(16)
.port(...)
.address(...)
// RESTinio.
.extra_data_factory(std::make_shared<my_user_data_factory>(logger))
.request_handler(...)
);
extra_data
generic_request_t
:
restinio::request_handling_status_t authentification_handler(
const restinio::generic_request_handle_t<per_request_data> & req)
{
... // .
if(!ok) {
// .
return req->create_response(...)...done();
}
else {
// .
req->extra_data().user_info_ = user_permissions{...};
return restinio::request_not_handled();
}
}
restinio::request_handling_status_t permissions_checker(
const restinio::generic_request_handle_t<per_request_data> & req)
{
// .
const auto & user_info = req->extra_data().user_info_;
... // .
}
, generic_request_t<Extra_Data>
, 0.6.13, RESTinio : generic_request_t<Extra_Data>
generic_request_handle_t<Extra_Data>
( std::shared_ptr<generic_request_t<Extra_Data>>
).
, , request_t
request_handle_t
generic_request_t<no_extra_data_factory_t::data_t>
generic_request_handle_t<no_extra_data_factory_t::data_t>
, no_extra_data_factory_t
— .
restinio::traits_t
, restinio::default_traits_t
restinio::default_single_thread_traits_t
no_extra_data_factory_t
extra_data_factory_t
. , request_t
request_handle_t
, .
extra-data express-/easy_parser_router
, express_router, ExpressJS, RESTinio. express_router . , extra-data express_router-.
extra-data , express_router-, express_router- extra-data. :
struct my_extra_data_factory { ... };
struct my_traits : public restinio::default_traits_t {
using extra_data_factory_t = my_extra_data_factory;
using request_handler_t = restinio::router::express_router_t<
restinio::router::std_regex_engine_t,
extra_data_factory_t>;
};
express_router request_handle_t
generic_request_handle_t<my_traits::extra_data_factory_t::data_t>
.
struct my_traits : public restinio::default_traits_t {
using extra_data_factory_t = my_extra_data_factory;
using request_handler_t = restinio::router::easy_parser_router_t<
extra_data_factory_t>;
};
RESTinio-0.7?
, 0.6 0.7.
.
-, RESTinio http-parser. , , . , http-parser ( ), RESTinio. , .
-, RESTinio , . , . , - . ?
-, , , , 0.6 . :
- http/1.1, http/2, http/3;
- , RESTinio , ;
- .
, , 0.6 .
- RESTinio?
RESTinio, , RESTinio.
, , .
, RESTinio . :( ;)
, , RESTinio, Issues Discussions GitHub. Google-. , .
2020- . , , . , RESTinio . , RESTinio .
Pengguna kami, yang berani memilih RESTinio untuk tugas mereka, memainkan peran penting dalam hal ini. Dan seseorang juga menemukan waktu / kesempatan untuk umpan balik. Berkat ini, RESTinio dapat menyingkirkan beberapa kekurangan dan menyediakan beberapa fitur.
Jadi saya ingin mengucapkan banyak terima kasih kepada semua orang yang tertarik dengan RESTinio. Perhatian Anda sangat penting bagi kami.
Dan, tentu saja, terima kasih banyak kepada semua orang yang menggunakan RESTinio. Tanpa Anda, proyek ini tidak akan berkembang.
Selamat Tahun Baru!