Standard structure for C++ REST SDK servers

Tags: , ,

This article proposes a unified standard structure for C++ REST SDK server applications. It solves the problem of user permissions using sessions and the problem of user data storage. It is a typed architecture based on the BlackJack server example included in the cpprest kit.

Resources

  • You can find the implementation of the explained architecture here (Tested on linux and MacOS X).
  • C++ REST SDK.

Schema

c++ REST SDK structure

Configuration file

The configuration file contains all the properties for configuring our objects, for example it contains the address and port where the server is going to listen, the session configuration, database connection properties etc.

The configuration file is parsed when any property is asked for the first time. The properties are accessible anywhere in the application, so we can include non native properties used in our project declared classes.

Example of configuration file:

# server address, will be http://localhost by default
address=http://192.168.1.9
# port default will be 80
port=80
# path extra uri path, will be empty by default, example: http://localhost:80/extrauripath

# Path of the directory containing the website files if it is not set or it doesn't exist,  ./www/ path will be taken, if this does not exist ./ will be taken.
# For relative paths use ./name_of_directory
root_path=www
default_files=["index.html","index.htm"]
error_paths={"404":"404/"}

# timeout
# time that has to pass since the last session use until
# the session is removed in seconds.
# 1 day = 86400
session_timeout=-1
session_clean_frequency=-1
session_clean_extra_timeout=0

Comments are declared with a # at the beginning of the line.
Properties are declared with a key and value separated by an = character.

You can see a full configuration file here.

Controllers

Controllers asynchronously handle the HTTP requests and give a response to the client.

They can deal with four HTTP methods, GET, POST, PUT and DELETE, each one will be canalized into its respective function: handle_get(http_request), handle_post(http_request), handle_put( http_request) and handle_delete(http_request).

All controllers inherit from a Controller abstract class.

Example of controller:

#include "granada/http/controller/controller.h"

namespace granada{
  namespace http{
    namespace controller{
      class ExampleController : public Controller {
        public:

          /**
           * Constructor
           */
          ExampleController(utility::string_t url);

        private:

          /**
           * Handles HTTP GET requests.
           * @param request HTTP request.
           */
          void handle_get(http_request request);


          /**
           * Handles HTTP PUT requests.
           * @param request HTTP request.
           */
          void handle_put(http_request request);


          /**
           * Handles HTTP POST requests.
           * @param request HTTP request.
           */
          void handle_post(http_request request);


          /**
           * Handles HTTP DELETE requests.
           * @param request HTTP request.
           */
          void handle_delete(http_request request);
      };
    }
  }
}

Implementation of post requests handle function:
void ExampleController::handle_post(web::http::http_request request)
{

  web::http::http_response response;

  // (...)

  request.reply(response);

}

Session

Sessions are used to manage user roles and permissions. Some can store “session data” or may be a way of clustering services.

Sessions are unique, stored until used again, they are retrieved thanks to a token passed through a cookie, a JSON or a query string.

All sessions inherit from a Session abstract class.

Their life cycle and storage is managed by a Session Handler. The basic life of a session consists of three steps: Open, Update and Close.

Business classes

Where all the application intelligence is. A simple example of business class is a cart that manages the storage of products and quantities and retrieves them taking care of user permissions.

Data/ Resources access and management

These classes are used to store and manage data and resources. They can be used for caching web resources, to store session data etc.

"Cache" classes implement a CacheHandler interface. They are called drivers, and they can store data in different supports: a map, a shared map, Redis etc. Some persist data, other do not.

Their basic methods are: Write data, Read data and Destroy data entry.

We have to be careful and destroy data entries that won't be used in the future.