ORM for consuming RESTful APIs in C++

Overview

restful_mapper

ORM for consuming RESTful APIs in C++

Build status

Introduction

restful_mapper connects business objects and Representational State Transfer (REST) web services. It implements object-relational mapping for REST web services to provide transparent proxying capabilities between a client (using restful_mapper) and a RESTful web service (that follows the conventions outlined below).

The ideas and design philosophy are directly adopted from Active Resource. However, the API and functionality differ in some areas, where it makes sense.

Design goals

  • Simple: Employ the principle of least surprise -- APIs should be clean and intuitive
  • Portable: Support old compilers -- all code is C++03 and C
  • Robust: Keep the code base small -- rely on proven and stable libraries to provide core functionality
  • Internationalized: Handle timezones and character sets automatically

RESTful web service conventions

RESTful web services come in many different forms, which are not all suitable for an ORM-style mapper such as restful_mapper. In order to be compatible with as many web services as possible, restful_mapper complies with the current best-practice for creating RESTful web services with JSON.

Specifically, restful_mapper is modelled against the Flask-Restless library, which provides full-featured RESTful web services that follow best- practice design methods.

The following basic conventions must be followed by the web service:

  • Uses standard DELETE, GET, POST and PUT requests for CRUD-operations
  • Collection of objects should use objects as the root JSON key
  • Objects in a relationship should be represented as nested JSON structures
  • If authentication is used, it must be HTTP basic authentication

For exact details on expected request and response formats, see Format of requests and responses.

Building

restful_mapper is built using CMake.

Dependencies

The following libraries are required to build restful_mapper.

  • libcurl - used for comminucating with the web service over HTTP
  • yajl - used to parse and emit JSON
  • libiconv - used to convert between character sets
  • googletest - required for tests only

Invoking the following command will download and build these libraries.

make vendor

On UNIX platforms, libcurl and libiconv are typically present on the system, and will not be built by the make command. If they are not present, they should be installed using the system package manager.

Library

After building the dependencies, invoke the following command to build restful_mapper.

make

This will install restful_mapper as a static library in the lib folder.

Tests

The test suite can be built and run using the following command.

make test

Usage

API configuration

Before making any requests to the web service, it must be configured using the following methods.

The root URL of the web service is specified using the set_url method:

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

If the web service requires authentication, provide the username and password:

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

If you are using a proxy server, it can be specified through the HTTP_PROXY environment variable or using the set_proxy method:

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

Mapper configuration

This example illustrates a complete object mapping:

using namespace std;
using namespace restful_mapper;

class User;
class Alert;

class Todo : public Model<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;

  virtual void map_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);
  }

  virtual void map_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";
  }

  virtual const Primary &primary() const
  {
    return id;
  }
};

class User: public Model<User>
{
public:
  Primary id;
  HasMany<Todo> todos;
  ...
};

An API entity is declared by creating a class that inherits from and follows the interface defined in restful_mapper::Model.

Each entity can hold a number of fields and relationships:

  • restful_mapper::Primary -- maps a primary key (integer)
  • restful_mapper::Foreign -- maps a foreign key (integer)
  • restful_mapper::Field<string> -- maps a string literal (represented in locale charset)
  • restful_mapper::Field<int> -- maps an integer value
  • restful_mapper::Field<double> -- maps a floating point value
  • restful_mapper::Field<bool> -- maps a boolean value
  • restful_mapper::Field<time_t> -- maps a datetime value (represented in the local timezone)
  • restful_mapper::HasOne<class> -- maps a one-to-one or many-to-one relationship on the referenced side
  • restful_mapper::BelongsTo<class> -- maps a one-to-one or many-to-one relationship on the foreign key side
  • restful_mapper::HasMany<class> -- maps a one-to-many relationship

The interface specified the following methods, which must be overriden:

  • virtual void restful_mapper::Model::map_set(Mapper &mapper) const
    Invoked upon saving an object to the web service.
  • virtual void restful_mapper::Model::map_get(const Mapper &mapper)
    Invoked upon requesting an object from the web service.
  • virtual std::string restful_mapper::Model::endpoint() const
    Specifies the API endpoint for this particular model. Relative to the web service root URL.
  • virtual const Primary &restful_mapper::Model::primary() const
    Specifies the primary key of the model.

Working with objects

Using the models defined above, the following operations are made available by restful_mapper.

Requesting data

// Find a single item by id
Todo t = Todo::find(2);

// Outputting fields
cout << t.task.get();

// Explicit conversions
cout << (string) t.task;

// Reload data from server
t.reload();

// Get all items in collection
Todo::Collection todos = Todo::find_all();

// Find an item in the collection by id
todos.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 completed
todos.find_first("completed", true);

Saving data

// Create a new item
Todo new_todo;
new_todo.task = "Use restful_mapper";
new_todo.save();

// Update an existing item
Todo old_todo = Todo::find(2);
old_todo.completed = true;
old_todo.save();

// Deleting an item
old_todo.destroy();

// Create a clone with no id set (i.e. a new database object)
Todo todo_clone = old_todo.clone();
todo_clone.save();

Relationships

// Find an item including related items
User u = User::find(1);

// Get a related todo
u.todos[2].task = "Do something else";

// Delete last item
u.todos.pop_back();

// Add a new related item
Todo 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 todo
u.save();

// Objects in one-to-one and many-to-one relationships are managed pointers
Todo t = Todo::find(2);
cout << t.user->email.get();

Querying

Supports the query operations specified by Flask-Restless.

// Query a single item
Query q;
q("task").like("Do someth%");
q("completed").eq(true);

Todo todo = Todo::find(q);

// Query a collection of items
Query q;
q("time").gt("1.45").lt("3.0");
q.order_by_asc(q.field("priority"));

Todo::Collection todos = Todo::find_all(q);

Exceptions

Some API errors are caught using custom exceptions.

  • Internal libcurl errors are represented as a restful_mapper::ApiError, which has adds a code() method to std::runtime_error.
  • restful_mapper::AuthenticationError is thrown when authentication fails, and has the same properties as restful_mapper::ApiError.
  • restful_mapper::BadRequestError is thrown when an error occurs on the API side, and has the same properties as restful_mapper::ApiError.
  • restful_mapper::ValidationError is thrown when one or more validation errors are thrown by the API. It has the same properties as restful_mapper::ApiError, but adds an errors() method, which returns a restful_mapper::ValidationError::FieldMap map with field names as keys and error messages as values. This map may also be accessed directly through the overloaded operator[].

Contributing

Pull requests on GitHub are very welcome! Please try to follow these simple rules:

  • Please create a topic branch for every separate change you make.
  • Make sure your patches are well tested. All tests must pass on Travis CI.
  • Update this README.md if applicable.

License

This code is copyright 2013 Logan Raarup, and is released under the revised BSD License.

For more information, see LICENSE.

Owner
Logan Raarup
Contact me for Python/C++/Ruby/Elixir/JS consulting.
Logan Raarup
Corvusoft's Restbed framework brings asynchronous RESTful functionality to C++14 applications.

Restbed Restbed is a comprehensive and consistent programming model for building applications that require seamless and secure communication over HTTP

Corvusoft 1.4k Mar 8, 2021
Fast and easy C++ RESTful WebServices framework

ngrest ngrest is a simple C++ REST framework. It has small footprint, fast and very easy in use. ngrest allow you to deploy C++ RESTful webservices un

Dmitry 425 Jun 26, 2022
A WiFi-enabled microcontroller capable of communicating with web-based service APIs for fast prototyping applications.

A WiFi-enabled microcontroller capable of communicating with web-based service APIs for fast prototyping applications.

Mark Hofmeister 2 Mar 9, 2022
❤️ SQLite ORM light header only library for modern C++

SQLite ORM SQLite ORM light header only library for modern C++ Status Branch Travis Appveyor master dev Advantages No raw string queries Intuitive syn

Yevgeniy Zakharov 1.6k Jun 27, 2022
C++ ORM for SQLite

Hiberlite ORM C++ object-relational mapping with API inspired by the awesome Boost.Serialization - that means almost no API to learn. Usage Just compi

Paul Korzhyk 625 Jun 24, 2022
A project to create a simple ORM.

cpp-ORM Current build status : An ORM project. You can simply create persistent objects using databases. The object representation: Each object have t

Maxime Barbier 5 Dec 14, 2020
Corvusoft's Restbed framework brings asynchronous RESTful functionality to C++14 applications.

Restbed Restbed is a comprehensive and consistent programming model for building applications that require seamless and secure communication over HTTP

Corvusoft 1.7k Jun 21, 2022
Corvusoft's Restbed framework brings asynchronous RESTful functionality to C++14 applications.

Restbed Restbed is a comprehensive and consistent programming model for building applications that require seamless and secure communication over HTTP

Corvusoft 1.7k Jun 24, 2022
A C++11 RESTful web server library

Served Overview Served is a C++ library for building high performance RESTful web servers. Served builds upon Boost.ASIO to provide a simple API for d

Meltwater 687 Jun 10, 2022
Corvusoft's Restbed framework brings asynchronous RESTful functionality to C++14 applications.

Restbed Restbed is a comprehensive and consistent programming model for building applications that require seamless and secure communication over HTTP

Corvusoft 1.4k Mar 8, 2021
Fast and easy C++ RESTful WebServices framework

ngrest ngrest is a simple C++ REST framework. It has small footprint, fast and very easy in use. ngrest allow you to deploy C++ RESTful webservices un

Dmitry 425 Jun 26, 2022
A RESTful environment for Arduino

aREST Overview A simple library that implements a REST API for Arduino & the ESP8266 WiFi chip. It is designed to be universal and currently supports

null 1.1k Jun 15, 2022
KoanLogic 378 Jun 22, 2022
Tink is a multi-language, cross-platform, open source library that provides cryptographic APIs that are secure, easy to use correctly, and hard(er) to misuse.

Tink A multi-language, cross-platform library that provides cryptographic APIs that are secure, easy to use correctly, and hard(er) to misuse. Ubuntu

Google 12.4k Jun 23, 2022
Easy to use cryptographic framework for data protection: secure messaging with forward secrecy and secure data storage. Has unified APIs across 14 platforms.

Themis provides strong, usable cryptography for busy people General purpose cryptographic library for storage and messaging for iOS (Swift, Obj-C), An

Cossack Labs 1.5k Jun 25, 2022
A basic 3D scene implemented with various engines, frameworks or APIs.

Here be dragons Hic sunt dracones. This repository contains multiple implementations of the same 3D scene, using different APIs and frameworks on vari

Simon Rodriguez 1.6k Jun 26, 2022
Low Level Graphics Library (LLGL) is a thin abstraction layer for the modern graphics APIs OpenGL, Direct3D, Vulkan, and Metal

Low Level Graphics Library (LLGL) Documentation NOTE: This repository receives bug fixes only, but no major updates. Pull requests may still be accept

Lukas Hermanns 1.4k Jun 19, 2022
Tools and libraries to glue C/C++ APIs to high-level languages

CppSharp is a tool and set of libraries which facilitates the usage of native C/C++ code with the .NET ecosystem. It consumes C/C++ header and library

Mono Project 2.4k Jun 24, 2022
Anime browser built with AniList APIs, showcasing clean Flutter BLoC architecture

Anime browser built with AniList APIs. The purpose of this project is to showcase clean Flutter application architecture with BLoC design pattern.

Peter A. Bizjak 21 Jun 22, 2022
proftest is a C application for testing the quality of different operating system APIs for profiling.

proftest is a C application for testing the quality of different operating system APIs for profiling.

Felix Geisendörfer 5 Jul 23, 2021
Celeborn is a Userland API Unhooker that I developed for learning Windows APIs and Syscall implementations

Celeborn is a Userland API Unhooker that I developed for learning Windows APIs and Syscall implementations. It mainly detects and patches hooking instructions in NTDLL.dll file. All PRs are welcome!

Furkan Göksel 101 May 28, 2022
match(it): A lightweight header-only pattern-matching library for C++17 with macro-free APIs.

match(it): A lightweight header-only pattern-matching library for C++17 with macro-free APIs. Features Easy to get started. Single header library. Mac

Bowen Fu 217 Jun 28, 2022
Demonstrates implementation of the Windows 10 Acrylic Effect on C++ Win32 Apps using DWM Private APIs and Direct Composition

Win32 Acrylic Effect A Demonstration of Acrylic Effect on C++ Win32 applications using Direct Composition and DWM private APIs. Table of Contents Over

Selastin 91 Jun 13, 2022
Hybrid Detect demonstrates CPU topology detection using multiple intrinsic and OS level APIs.

Hybrid Detect Hybrid Detect demonstrates CPU topology detection using multiple intrinsic and OS level APIs. First, we demonstrate usage of CPUID intri

null 25 Jun 13, 2022
This repository gives an idea about how to use UART/SPI/I2C communication using HAL APIs

STM32-UART-SPI-I2C communication with Arduino board using HAL APIs This repository gives an idea about how to use UART/SPI/I2C communication using HAL

Shrilesh(Skrillex) 1 Nov 1, 2021
NVRHI (NVIDIA Rendering Hardware Interface) is a library that implements a common abstraction layer over multiple graphics APIs

NVRHI Introduction NVRHI (NVIDIA Rendering Hardware Interface) is a library that implements a common abstraction layer over multiple graphics APIs (GA

NVIDIA GameWorks 381 Jun 19, 2022
A Cross platform implement of Wenet ASR. It's based on ONNXRuntime and Wenet. We provide a set of easier APIs to call wenet models.

RapidASR: a new member of RapidAI family. Our visio is to offer an out-of-box engineering implementation for ASR. A cpp implementation of recognize-on

RapidAI-NG 70 Jun 20, 2022
List & Read the processes memory using Windows APIs (PSAPI/ToolHelpAPI/WTSAPI)

Dumper List & Read the processes memory using Windows APIs PSAPI ToolHelp WTSAPI Usage The Dumper tool list the running procceses and provide the abil

ムハンマド 3 Apr 10, 2022
A collective list of free APIs

Public APIs A collective list of free APIs for use in software and web development Status The Project Contributing Guide • API for this project • Issu

null 197.2k Jun 25, 2022