pistache(C++ REST 工具) 使用

项目不完善,使用需谨慎

相关资料
github
homepage / document

目前因为资料还是不是很多,所以最好的学习资料应该就是在github项目主页上挂着的各种实例了~

这里我将代码克隆了下来,用tree命令打印了一下目录:

host@lab:~/scode/pistache$ tree -d -L 2
.
├── build
│   ├── CMakeFiles
│   ├── examples
│   ├── googletest-release-1.7.0
│   ├── src
│   └── tests
├── examples   # 官方实例的目录
├── googletest-release-1.7.0
│   ├── build-aux
│   ├── cmake
│   ├── codegear
│   ├── include
│   ├── m4
│   ├── make
│   ├── msvc
│   ├── samples
│   ├── scripts
│   ├── src
│   ├── test
│   └── xcode
├── include
│   └── serializer
├── src
│   ├── client
│   ├── common
│   └── server
└── tests

这里贴出一个实例,顺便注释一下,给大家一个参考:

#include "http.h"
#include "router.h"
#include "endpoint.h"
#include <algorithm>

using namespace std;
using namespace Net;

void printCookies(const Net::Http::Request &req){
  auto cookies = req.cookies();  # 获取cookies
  std::cout << "Cookies: [" << std::endl;
  const std::string indent(4, ' ');  # ' ' * 4 = '    '
  for(const auto &c: cookies){
    std::cout << indent << c.name << " = " << c.value << std::endl;
  }
  std::cout << "]" << std::endl;
}

namespace Generic{

void handleReady(const Rest::Request &, Http::ResponseWriter response){
  response.send(Http::Code::Ok, "1");
}
}

class StatsEndpoint{
public:
  StatsEndpoint(Net::Address addr)
      : httpEndpoint(std::make_shared<Net::Http::Endpoint>(addr)){}

  void init(size_t thr = 2){
    auto opts = Net::Http::Endpoint::options()
        .threads(thr)
        .flags(Net::Tcp::Options::InstallSignalHandler);
    httpEndpoint->init(opts);
    setupRoutes();
  }

  void start(){
    httpEndpoint->setHandler(router.handler());
    httpEndpoint->serve();
  }

  void shutdown(){
    httpEndpoint->shutdown();
  }

private:
  void setupRoutes(){
    using namespace Net::Rest;

    Routes::Post(router, "/record/:name/:value?",
                 Routes::bind(&StatsEndpoint::doRecordMetric, this));  # bind

    Routes::Get(router,
                "/value/:name", Routes::bind(&StatsEndpoint::doGetMetric, this));

    Routes::Get(router,
                "/ready", Routes::bind(&Generic::handleReady));

    Routes::Get(router,
                "/auth", Routes::bind(&StatsEndpoint::doAuth, this));

  }

  void doRecordMetric(const Rest::Request &request, Net::Http::ResponseWriter response){
    auto name = request.param(":name").as<std::string>();

    Guard guard(metricsLock); // 加锁

    auto it = std::find_if(metrics.begin(),
                           metrics.end(),
                           [&](const Metric &metric){
      return metric.name() == name;
    });

    int val = 1;
    if(request.hasParam(":value")){
      auto value = request.param(":value");
      val = value.as<int>();
    }

    if(it == std::end(metrics)){
      metrics.push_back(Metric(std::move(name), val));
      response.send(Http::Code::Created, std::to_string(val));
    }else{
      auto &metric = *it;
      metric.incr(val);
      response.send(Http::Code::Ok, std::to_string(metric.value()));
    }

  }

  void doGetMetric(const Rest::Request &request, Net::Http::ResponseWriter response){
    auto name = request.param(":name").as<std::string>();

    Guard guard(metricsLock);
    auto it = std::find_if(metrics.begin(), metrics.end(), [&](const Metric &metric){
      return metric.name() == name;
    });

    if(it == std::end(metrics)){
      response.send(Http::Code::Not_Found, "Metric does not exist");
    }else{
      const auto &metric = *it;
      response.send(Http::Code::Ok, std::to_string(metric.value()));
    }

  }

  void doAuth(const Rest::Request &request, Net::Http::ResponseWriter response){
    printCookies(request);
    response.cookies()
        .add(Http::Cookie("lang", "en-US"));
    response.send(Http::Code::Ok);
  }

  class Metric{
  public:
    Metric(std::string name, int initialValue = 1)
        : name_(std::move(name)), value_(initialValue){}

    int incr(int n = 1){
      int old = value_;
      value_ += n;
      return old;
    }

    int value() const{
      return value_;
    }

    std::string name() const{
      return name_;
    }

  private:
    std::string name_;
    int value_;
  };

  typedef std::mutex Lock;
  typedef std::lock_guard<Lock> Guard;
  Lock metricsLock;
  std::vector<Metric> metrics;

  std::shared_ptr<Net::Http::Endpoint> httpEndpoint;
  Rest::Router router;
};

int main(int argc, char *argv[]){
  Net::Port port(9080);

  int thr = 2;

  if(argc >= 2){
    port = std::stol(argv[1]);

    if(argc == 3)
      thr = std::stol(argv[2]);
  }

  Net::Address addr(Net::Ipv4::any(), port);

  cout << "Cores = " << hardware_concurrency() << endl;
  cout << "Using " << thr << " threads" << endl;

  StatsEndpoint stats(addr);

  stats.init(thr);
  stats.start();

  stats.shutdown();
}
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值