зеркало из https://github.com/microsoft/CCF.git
113 строки
3.4 KiB
C++
113 строки
3.4 KiB
C++
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
// Licensed under the Apache 2.0 License.
|
|
#pragma once
|
|
|
|
#include "ccf/endpoint_registry.h"
|
|
#include "ccf/serdes.h"
|
|
|
|
#include <llhttp/llhttp.h>
|
|
#include <variant>
|
|
|
|
namespace ccf
|
|
{
|
|
/*
|
|
* For simple app methods which expect a JSON request, potentially msgpack'd,
|
|
* these functions do the common decoding of the input and setting of response
|
|
* fields, to reduce handler complexity and repetition.
|
|
*
|
|
* Rather than:
|
|
* auto foo = [](auto& ctx) {
|
|
* nlohmann::json params;
|
|
* serdes::Pack pack_type;
|
|
* if (<content-type is JSON>)
|
|
* {
|
|
* params = unpack(ctx.rpc_ctx->get_request_body());
|
|
* pack_type = Text;
|
|
* }
|
|
* else
|
|
* {
|
|
* ...
|
|
* }
|
|
* auto result = fn(params);
|
|
* if (is_error(result))
|
|
* {
|
|
* ctx.rpc_ctx->set_response_status(SOME_ERROR);
|
|
* ctx.rpc_ctx->set_response_header(content_type, Text);
|
|
* ctx.rpc_ctx->set_response_body(error_msg(result));
|
|
* }
|
|
* if (pack_type == Text)
|
|
* {
|
|
* ctx.rpc_ctx->set_response_header(content_type, JSON);
|
|
* ctx.rpc_ctx->set_response_body(pack(result, Text));
|
|
* }
|
|
* else
|
|
* {
|
|
* ...
|
|
* }
|
|
* };
|
|
*
|
|
* it is possible to write the shorter, clearer, return-based lambda:
|
|
* auto foo = json_adapter([](auto& ctx, nlohmann::json&& params)
|
|
* {
|
|
* auto result = fn(params);
|
|
* if (is_error(result))
|
|
* {
|
|
* return make_error(SOME_ERROR, error_msg(result));
|
|
* }
|
|
* else
|
|
* {
|
|
* return make_success(result);
|
|
* }
|
|
* });
|
|
*/
|
|
namespace jsonhandler
|
|
{
|
|
using JsonAdapterResponse = std::variant<ErrorDetails, nlohmann::json>;
|
|
|
|
char const* pack_to_content_type(serdes::Pack p);
|
|
|
|
serdes::Pack detect_json_pack(const std::shared_ptr<ccf::RpcContext>& ctx);
|
|
|
|
serdes::Pack get_response_pack(
|
|
const std::shared_ptr<ccf::RpcContext>& ctx,
|
|
serdes::Pack request_pack = serdes::Pack::Text);
|
|
|
|
nlohmann::json get_params_from_body(
|
|
const std::shared_ptr<ccf::RpcContext>& ctx, serdes::Pack pack);
|
|
|
|
std::pair<serdes::Pack, nlohmann::json> get_json_params(
|
|
const std::shared_ptr<ccf::RpcContext>& ctx);
|
|
|
|
void set_response(
|
|
JsonAdapterResponse&& res,
|
|
std::shared_ptr<ccf::RpcContext>& ctx,
|
|
serdes::Pack request_packing);
|
|
}
|
|
|
|
jsonhandler::JsonAdapterResponse make_success();
|
|
jsonhandler::JsonAdapterResponse make_success(
|
|
nlohmann::json&& result_payload);
|
|
jsonhandler::JsonAdapterResponse make_success(
|
|
const nlohmann::json& result_payload);
|
|
|
|
jsonhandler::JsonAdapterResponse make_error(
|
|
http_status status, const std::string& code, const std::string& msg);
|
|
|
|
using HandlerJsonParamsAndForward =
|
|
std::function<jsonhandler::JsonAdapterResponse(
|
|
endpoints::EndpointContext& ctx, nlohmann::json&& params)>;
|
|
endpoints::EndpointFunction json_adapter(
|
|
const HandlerJsonParamsAndForward& f);
|
|
|
|
using ReadOnlyHandlerWithJson =
|
|
std::function<jsonhandler::JsonAdapterResponse(
|
|
endpoints::ReadOnlyEndpointContext& ctx, nlohmann::json&& params)>;
|
|
endpoints::ReadOnlyEndpointFunction json_read_only_adapter(
|
|
const ReadOnlyHandlerWithJson& f);
|
|
|
|
using CommandHandlerWithJson = std::function<jsonhandler::JsonAdapterResponse(
|
|
endpoints::CommandEndpointContext& ctx, nlohmann::json&& params)>;
|
|
endpoints::CommandEndpointFunction json_command_adapter(
|
|
const CommandHandlerWithJson& f);
|
|
}
|