{"id":19787213,"url":"https://github.com/logandk/restful_mapper","last_synced_at":"2025-07-25T08:09:18.630Z","repository":{"id":7750978,"uuid":"9118431","full_name":"logandk/restful_mapper","owner":"logandk","description":"ORM for consuming RESTful APIs in C++","archived":false,"fork":false,"pushed_at":"2019-02-21T22:01:58.000Z","size":559,"stargazers_count":81,"open_issues_count":4,"forks_count":19,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-04-30T23:34:59.620Z","etag":null,"topics":["cpp","orm","rest","restful"],"latest_commit_sha":null,"homepage":"http://logan.dk/restful_mapper","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/logandk.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-03-30T16:18:14.000Z","updated_at":"2025-03-20T03:18:02.000Z","dependencies_parsed_at":"2022-07-17T14:19:18.431Z","dependency_job_id":null,"html_url":"https://github.com/logandk/restful_mapper","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/logandk/restful_mapper","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/logandk%2Frestful_mapper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/logandk%2Frestful_mapper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/logandk%2Frestful_mapper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/logandk%2Frestful_mapper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/logandk","download_url":"https://codeload.github.com/logandk/restful_mapper/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/logandk%2Frestful_mapper/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266977905,"owners_count":24015486,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-25T02:00:09.625Z","response_time":70,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cpp","orm","rest","restful"],"created_at":"2024-11-12T06:21:48.975Z","updated_at":"2025-07-25T08:09:18.583Z","avatar_url":"https://github.com/logandk.png","language":"C++","readme":"# restful_mapper #\n\nORM for consuming RESTful APIs in C++\n\n[![Build status](https://secure.travis-ci.org/logandk/restful_mapper.png)](http://travis-ci.org/logandk/restful_mapper)\n\n# Introduction #\n\n**restful\\_mapper** connects business objects and Representational State\nTransfer (REST) web services. It implements object-relational mapping for REST\nweb services to provide transparent proxying capabilities between a client\n(using **restful_mapper**) and a RESTful web service (that follows the\nconventions outlined below).\n\nThe ideas and design philosophy are directly adopted from [Active Resource][3].\nHowever, the API and functionality differ in some areas, where it makes sense.\n\n## Design goals ##\n\n* _Simple_: Employ the principle of least surprise -- APIs should be clean and\n  intuitive\n* _Portable_: Support old compilers -- all code is C++03 and C\n* _Robust_: Keep the code base small -- rely on proven and stable libraries to\n  provide core functionality\n* _Internationalized_: Handle timezones and character sets automatically\n\n## RESTful web service conventions ##\n\nRESTful web services come in many different forms, which are not all suitable\nfor an ORM-style mapper such as **restful_mapper**. In order to be compatible\nwith as many web services as possible, **restful_mapper** complies with the\ncurrent best-practice for creating RESTful web services with JSON.\n\nSpecifically, **restful_mapper** is modelled against the [Flask-Restless][4]\nlibrary, which provides full-featured RESTful web services that follow best-\npractice design methods.\n\nThe following basic conventions must be followed by the web service:\n\n* Uses standard `DELETE`, `GET`, `POST` and `PUT` requests for CRUD-operations\n* Collection of objects should use `objects` as the root JSON key\n* Objects in a relationship should be represented as nested JSON structures\n* If authentication is used, it must be HTTP basic authentication\n\nFor exact details on expected request and response formats, see [Format of requests and responses][5].\n\n# Building #\n\n**restful\\_mapper** is built using [CMake][6].\n\n## Dependencies ##\n\nThe following libraries are required to build **restful_mapper**.\n\n* [libcurl][7] - used for comminucating with the web service over HTTP\n* [yajl][8] - used to parse and emit JSON\n* [libiconv][9] - used to convert between character sets\n* [googletest][10] - required for tests only\n\nInvoking the following command will download and build these libraries.\n\n```shell\nmake vendor\n```\n\nOn UNIX platforms, [libcurl][7] and [libiconv][9] are typically present on the\nsystem, and will not be built by the make command. If they are not present,\nthey should be installed using the system package manager.\n\n## Library ##\n\nAfter building the dependencies, invoke the following command to build **restful_mapper**.\n\n```shell\nmake\n```\n\nThis will install **restful_mapper** as a static library in the `lib` folder.\n\n## Tests ##\n\nThe test suite can be built and run using the following command.\n\n```shell\nmake test\n```\n\n# Usage #\n\n## API configuration ##\n\nBefore making any requests to the web service, it must be configured using the\nfollowing methods.\n\nThe root URL of the web service is specified using the `set_url` method:\n\n```c++\nApi::set_url(\"http://localhost:5000/api\");\n```\n\nIf the web service requires authentication, provide the username and password:\n\n```c++\nApi::set_username(\"admin\");\nApi::set_password(\"test\");\n```\n\nIf you are using a proxy server, it can be specified through the `HTTP_PROXY`\nenvironment variable or using the `set_proxy` method:\n\n```c++\nApi::set_proxy(\"http://myproxy\");\n```\n\n## Mapper configuration ##\n\nThis example illustrates a complete object mapping:\n\n```c++\nusing namespace std;\nusing namespace restful_mapper;\n\nclass User;\nclass Alert;\n\nclass Todo : public Model\u003cTodo\u003e\n{\npublic:\n  Primary id;\n  Field\u003cstring\u003e task;\n  Field\u003cint\u003e priority;\n  Field\u003cdouble\u003e time;\n  Field\u003cbool\u003e completed;\n  Field\u003ctime_t\u003e completed_on;\n  Foreign\u003cint\u003e user_id;\n  BelongsTo\u003cUser\u003e user;\n  HasOne\u003cAlert\u003e alert;\n\n  virtual void map_set(Mapper \u0026mapper) const\n  {\n    mapper.set(\"id\", id);\n    mapper.set(\"task\", task);\n    mapper.set(\"priority\", priority);\n    mapper.set(\"time\", time);\n    mapper.set(\"completed\", completed);\n    mapper.set(\"completed_on\", completed_on);\n    mapper.set(\"user_id\", user_id);\n    mapper.set(\"user\", user);\n    mapper.set(\"alert\", alert);\n  }\n\n  virtual void map_get(const Mapper \u0026mapper)\n  {\n    mapper.get(\"id\", id);\n    mapper.get(\"task\", task);\n    mapper.get(\"priority\", priority);\n    mapper.get(\"time\", time);\n    mapper.get(\"completed\", completed);\n    mapper.get(\"completed_on\", completed_on);\n    mapper.get(\"user_id\", user_id);\n    mapper.get(\"user\", user);\n    mapper.get(\"alert\", alert);\n  }\n\n  virtual std::string endpoint() const\n  {\n    return \"/todo\";\n  }\n\n  virtual const Primary \u0026primary() const\n  {\n    return id;\n  }\n};\n\nclass User: public Model\u003cUser\u003e\n{\npublic:\n  Primary id;\n  HasMany\u003cTodo\u003e todos;\n  ...\n};\n```\n\nAn API entity is declared by creating a class that inherits from and follows the\ninterface defined in `restful_mapper::Model`.\n\nEach entity can hold a number of fields and relationships:\n\n* `restful_mapper::Primary` -- maps a primary key (integer)\n* `restful_mapper::Foreign` -- maps a foreign key (integer)\n* `restful_mapper::Field\u003cstring\u003e` -- maps a string literal (represented in locale charset)\n* `restful_mapper::Field\u003cint\u003e` -- maps an integer value\n* `restful_mapper::Field\u003cdouble\u003e` -- maps a floating point value\n* `restful_mapper::Field\u003cbool\u003e` -- maps a boolean value\n* `restful_mapper::Field\u003ctime_t\u003e` -- maps a datetime value (represented in the local timezone)\n* `restful_mapper::HasOne\u003cclass\u003e` -- maps a one-to-one or many-to-one relationship on the referenced side\n* `restful_mapper::BelongsTo\u003cclass\u003e` -- maps a one-to-one or many-to-one relationship on the foreign key side\n* `restful_mapper::HasMany\u003cclass\u003e` -- maps a one-to-many relationship\n\nThe interface specified the following methods, which must be overriden:\n\n* `virtual void restful_mapper::Model::map_set(Mapper \u0026mapper) const`\u003cbr/\u003e\n  Invoked upon saving an object to the web service.\n* `virtual void restful_mapper::Model::map_get(const Mapper \u0026mapper)`\u003cbr/\u003e\n  Invoked upon requesting an object from the web service.\n* `virtual std::string restful_mapper::Model::endpoint() const`\u003cbr/\u003e\n  Specifies the API endpoint for this particular model. Relative to the web service\n  root URL.\n* `virtual const Primary \u0026restful_mapper::Model::primary()` const\u003cbr/\u003e\n  Specifies the primary key of the model.\n\n## Working with objects ##\n\nUsing the models defined above, the following operations are made available by\n**restful_mapper**.\n\n### Requesting data ###\n\n```c++\n// Find a single item by id\nTodo t = Todo::find(2);\n\n// Outputting fields\ncout \u003c\u003c t.task.get();\n\n// Explicit conversions\ncout \u003c\u003c (string) t.task;\n\n// Reload data from server\nt.reload();\n\n// Get all items in collection\nTodo::Collection todos = Todo::find_all();\n\n// Find an item in the collection by id\ntodos.find(4);\n\n// Find all items in collection where task is \"Do something\"\ntodos.find(\"task\", \"Do something\");\n\n// Find the first item in collection that has been completed\ntodos.find_first(\"completed\", true);\n```\n\n### Saving data ###\n\n```c++\n// Create a new item\nTodo new_todo;\nnew_todo.task = \"Use restful_mapper\";\nnew_todo.save();\n\n// Update an existing item\nTodo old_todo = Todo::find(2);\nold_todo.completed = true;\nold_todo.save();\n\n// Deleting an item\nold_todo.destroy();\n\n// Create a clone with no id set (i.e. a new database object)\nTodo todo_clone = old_todo.clone();\ntodo_clone.save();\n```\n\n### Relationships ###\n\n```c++\n// Find an item including related items\nUser u = User::find(1);\n\n// Get a related todo\nu.todos[2].task = \"Do something else\";\n\n// Delete last item\nu.todos.pop_back();\n\n// Add a new related item\nTodo new_todo;\nnew_todo.task = \"Use restful_mapper\";\nu.todos.push_back(new_todo);\n\n// Save user including all changes to related todos - will delete one, update one and add one todo\nu.save();\n\n// Objects in one-to-one and many-to-one relationships are managed pointers\nTodo t = Todo::find(2);\ncout \u003c\u003c t.user-\u003eemail.get();\n```\n\n### Querying ###\n\nSupports the query operations [specified][11] by [Flask-Restless][4].\n\n```c++\n// Query a single item\nQuery q;\nq(\"task\").like(\"Do someth%\");\nq(\"completed\").eq(true);\n\nTodo todo = Todo::find(q);\n\n// Query a collection of items\nQuery q;\nq(\"time\").gt(\"1.45\").lt(\"3.0\");\nq.order_by_asc(q.field(\"priority\"));\n\nTodo::Collection todos = Todo::find_all(q);\n```\n\n### Exceptions ###\n\nSome API errors are caught using custom exceptions.\n\n* Internal [libcurl][7] errors are represented as a `restful_mapper::ApiError`,\n  which has adds a `code()` method to `std::runtime_error`.\n* `restful_mapper::AuthenticationError` is thrown when authentication fails,\n  and has the same properties as `restful_mapper::ApiError`.\n* `restful_mapper::BadRequestError` is thrown when an error occurs on the API\n  side, and has the same properties as `restful_mapper::ApiError`.\n* `restful_mapper::ValidationError` is thrown when one or more validation\n  errors are thrown by the API. It has the same properties as\n  `restful_mapper::ApiError`, but adds an `errors()` method, which returns a\n  `restful_mapper::ValidationError::FieldMap` map with field names as keys and\n  error messages as values. This map may also be accessed directly through the\n  overloaded `operator[]`.\n\n# Contributing #\n\nPull requests on [GitHub][1] are very welcome! Please try to follow these simple rules:\n\n* Please create a topic branch for every separate change you make.\n* Make sure your patches are well tested. All tests must pass on [Travis CI][2].\n* Update this [`README.md`](http://github.com/logandk/restful_mapper/blob/master/README.md) if applicable.\n\n# License #\n\nThis code is copyright 2013 Logan Raarup, and is released under the revised BSD License.\n\nFor more information, see [`LICENSE`](http://github.com/logandk/restful_mapper/blob/master/LICENSE).\n\n\n[1]: http://github.com/logandk/restful_mapper\n[2]: http://travis-ci.org/logandk/restful_mapper\n[3]: https://github.com/rails/activeresource\n[4]: https://github.com/jfinkels/flask-restless\n[5]: https://flask-restless.readthedocs.org/en/latest/requestformat.html\n[6]: http://www.cmake.org\n[7]: http://curl.haxx.se/libcurl\n[8]: http://lloyd.github.io/yajl\n[9]: http://www.gnu.org/software/libiconv\n[10]: https://code.google.com/p/googletest\n[11]: https://flask-restless.readthedocs.org/en/latest/searchformat.html#queryformat\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flogandk%2Frestful_mapper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flogandk%2Frestful_mapper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flogandk%2Frestful_mapper/lists"}