restful_mapper, 在 C++ 中,用于消费rest式api的ORM

分享于 

12分钟阅读

GitHub

  繁體 雙語
ORM for consuming RESTful APIs in C++
  • 源代码名称:restful_mapper
  • 源代码网址:http://www.github.com/logandk/restful_mapper
  • restful_mapper源代码文档
  • restful_mapper源代码下载
  • Git URL:
    git://www.github.com/logandk/restful_mapper.git
    Git Clone代码到本地:
    git clone http://www.github.com/logandk/restful_mapper
    Subversion代码到本地:
    $ svn co --depth empty http://www.github.com/logandk/restful_mapper
    Checked out revision 1.
    $ cd repo
    $ svn up trunk
    
    restful_mapper

    用于在 C+ + 中使用 RESTful api的ORM

    Build status

    简介

    restful_mapper 连接业务对象和具象状态转移( 剩余) Web服务。 为 REST Web服务 实现对象关系映射,为客户端( 使用 restful_mapper ) 和 RESTful web服务( 遵循下面列出的约定) 之间提供透明代理功能。

    本文的思想和设计理念直接从活动资源库中采用。 但是,API和功能在某些方面有所不同,这是有意义。

    的设计目标

    • 简单: 采用最简单的-- api原则应该是干净和直观
    • 可移植: 支持旧编译器--所有代码均为C++03和C
    • 基于java的健壮:保持代码基础的小型--依赖经过验证和稳定的库,从而提供核心功能
    • 国际化: 自动处理时区和字符集

    RESTful web服务约定

    rest式 Web服务 有许多不同的形式,它们并不适合于orm风格的映射器,比如的 为了与尽可能多的Web服务 兼容,遵循当前最佳实践,使用JSON创建 RESTful Web服务。

    具体而言, is针对烧瓶令人不安的库建模,它提供了遵循best-实践设计方法的全功能rest式 Web服务。

    以下基本约定必须跟在web服务后面:

    • 使用标准 DELETEGETPOSTPUT 请求进行crud操作
    • 对象集合应该使用 objects 作为 root JSON键
    • 关系中的对象应该表示为嵌套的JSON结构
    • 如果使用身份验证,则它必须是HTTP基本身份验证

    有关预期请求和响应格式的详细信息,请参阅请求和响应格式的格式。

    建筑

    使用 CMake 构建了 restful_mapper

    依赖项

    需要以下库来构建收费的。

    • - 用于在HTTP上使用web服务的comminucating
    • yajl - 用于解析和发出 JSON
    • libiconv - 用于在字符集之间进行转换
    • googletest - 仅用于测试

    调用以下命令将下载并构建这些库。

    make vendor

    UNIX平台上,系统通常存在,并不会由make命令生成。 如果不存在,则应使用系统包管理器安装它们。

    构建依赖关系后,调用以下命令以构建收费的restful_mapper。

    make

    这将在 lib 文件夹中安装 restful_mapper 作为 static 库。

    测试

    可以使用以下命令构建和运行测试套件。

    make test
    用法

    API配置

    必须使用下列方法配置对web服务的任何请求。

    web服务的root URL使用 set_url 方法指定:

    Api::set_url("http://localhost:5000/api");

    如果web服务需要身份验证,请提供用户名和密码:

    Api::set_username("admin");Api::set_password("test");

    如果使用代理服务器,则可以通过 HTTP_PROXY 环境变量或者使用 set_proxy 方法来指定它:

    Api::set_proxy("http://myproxy");

    映射器配置

    这里示例演示一个完整的对象映射:

    usingnamespacestd;usingnamespacerestful_mapper;classUser;classAlert;classTodo : publicModel<Todo>
    {public: Primary id;
     Field<string> task;
     Field<int> priority;
     Field<double> time;
     Field<bool> completed;
     Field<time_t> completed_on;
     Foreign<int> user_id;
     BelongsTo<User> user;
     HasOne<Alert> alert;
     virtualvoidmap_set(Mapper &mapper) const {
     mapper.set("id", id);
     mapper.set("task", task);
     mapper.set("priority", priority);
     mapper.set("time", time);
     mapper.set("completed", completed);
     mapper.set("completed_on", completed_on);
     mapper.set("user_id", user_id);
     mapper.set("user", user);
     mapper.set("alert", alert);
     }
     virtualvoidmap_get(const Mapper &mapper)
     {
     mapper.get("id", id);
     mapper.get("task", task);
     mapper.get("priority", priority);
     mapper.get("time", time);
     mapper.get("completed", completed);
     mapper.get("completed_on", completed_on);
     mapper.get("user_id", user_id);
     mapper.get("user", user);
     mapper.get("alert", alert);
     }
     virtual std::string endpoint() const {
     return"/todo";
     }
     virtualconst Primary &primary() const {
     return id;
     }
    };classUser: publicModel<User>
    {public: Primary id;
     HasMany<Todo> todos;
    . . .
    };

    通过创建从 restful_mapper::Model 定义的接口继承并遵循接口的类声明了一个API实体。

    每个实体都可以保存多个字段和关系:

    • restful_mapper::Primary --映射主键( 整数)
    • restful_mapper::Foreign --映射外键( 整数)
    • restful_mapper::Field<string> --映射字符串文本( 在语言环境字符集中表示)
    • restful_mapper::Field<int> --映射整数值
    • restful_mapper::Field<double> --映射浮点值
    • restful_mapper::Field<bool> --映射布尔值
    • restful_mapper::Field<time_t> --映射日期时间值( 表示在本地时区中)
    • restful_mapper::HasOne<class> --在引用的边上映射one-to-one或者many-to-one关系
    • restful_mapper::BelongsTo<class> --在外键侧映射one-to-one或者many-to-one关系
    • restful_mapper::HasMany<class> --映射one-to-many关系

    接口指定了以下方法,必须重写这些方法:

    • virtual void restful_mapper::Model::map_set(Mapper &mapper) const
      在将对象保存到web服务时调用。
    • virtual void restful_mapper::Model::map_get(const Mapper &mapper)
      从web服务请求对象时调用。
    • virtual std::string restful_mapper::Model::endpoint() const
      指定这里特定模型的API终结点。 相对于web服务 root URL。
    • virtual const Primary &restful_mapper::Model::primary() const
      指定模型的主键。

    处理对象

    使用上述模型,可以通过 restful_mapper 提供以下操作。

    请求数据

    // Find a single item by idTodo t = Todo::find(2);// Outputting fieldscout <<t.task.get();// Explicit conversionscout <<(string) t.task;// Reload data from servert.reload();// Get all items in collectionTodo::Collection todos = Todo::find_all();// Find an item in the collection by idtodos.find(4);// Find all items in collection where task is"Do something"todos.find("task", "Do something");// Find the first item in collection that has been completedtodos.find_first("completed", true);

    保存数据

    // Create a new itemTodo new_todo;
    new_todo.task = "Use restful_mapper";
    new_todo.save();// Update an existing itemTodo old_todo = Todo::find(2);
    old_todo.completed = true;
    old_todo.save();// Deleting an itemold_todo.destroy();// Create a clone with no id set (i.e. a new database object)Todo todo_clone = old_todo.clone();
    todo_clone.save();

    关系

    // Find an item including related itemsUser u = User::find(1);// Get a related todou.todos[2].task = "Do something else";// Delete last itemu.todos.pop_back();// Add a new related itemTodo new_todo;
    new_todo.task = "Use restful_mapper";
    u.todos.push_back(new_todo);// Save user including all changes to related todos - will delete one, update one and add one todou.save();// Objects in one-to-one and many-to-one relationships are managed pointersTodo t = Todo::find(2);
    cout <<t.user->email.get();

    查询

    支持查询操作的指定的,由烧瓶restless的。

    // Query a single itemQuery q;q("task").like("Do someth%");q("completed").eq(true);
    Todo todo = Todo::find(q);// Query a collection of itemsQuery q;q("time").gt("1.45").lt("3.0");
    q.order_by_asc(q.field("priority"));
    Todo::Collection todos = Todo::find_all(q);

    异常

    某些API错误是使用自定义异常捕获的。

    • 内部 错误表示为 restful_mapper::ApiError,它向 std::runtime_error 添加了 code() 方法。
    • restful_mapper::AuthenticationError 在验证失败时引发,并且具有与 restful_mapper::ApiError 相同的属性。
    • 当API端发生错误时抛出 restful_mapper::BadRequestError,并且具有与 restful_mapper::ApiError 相同的属性。
    • 当API抛出一个或者多个验证错误时,抛出 restful_mapper::ValidationError。 它具有与 restful_mapper::ApiError 相同的属性,但添加了一个 errors() 方法,该方法返回 restful_mapper::ValidationError::FieldMap 以字段名称作为关键字和错误消息作为值的映射。 这个映射也可以通过重载的operator[] 直接访问。

    GitHub上请求请求非常欢迎 ! 请尝试遵循以下简单规则:

    • 请为你所做的每个单独更改创建一个主题分支。
    • 确保你的修补程序经过了良好的测试。 所有测试必须通过 Travis CI。
    • 如果适用,请更新这里 README.md
    许可证

    这里代码是版权 2013 Raarup,并在修订后的BSD许可证下发布。

    有关更多信息,请参见 LICENSE


    API  REST  CONS  restful  ORM  consuming  
    相关文章