BackREST API CPP

How To Build Your First C++ REST API Client

29 August 2023


This tutorial helps us understand how to access Forex data using TraderMade’s REST API with C++ programming language. Market data helps analysts and developers gain valuable insights and make informed decisions.

Getting Started

To begin with, we need to sign-up for an account with TraderMade and get our exclusive API Key to access real-time and historical Forex data. Now, we can fetch an API key to authenticate our requests. In order to learn more about real-time and historical Forex data, let us have a look at the REST API documentation.

Let us go through a practical example to demonstrate the process. We can divide the process into several steps, such as

  • Setting up the coding environment.
  • Importing necessary libraries.
  • Write some code.
  • Debugging the code and getting results.

Setting up the coding environment 

Setting-up the programming environment is essential, before jumping to the code. Now, we are ready to download a code editor or an Integrated Development Environment (IDE) and install it on the system. 

Step 1: Integrated Development Environment

As C++ is easier to set up in Linux systems, we recommend downloading Ubuntu if you are not already on linux. Otherwise, you can skip Step 2. We need to download it from the official site https://ubuntu.com/download.

Step 2: Installation

The download will start automatically, giving us an ISO file. 

Importing necessary libraries

A C++ library is a collection of standard functions and classes written in the core language. If you are new to C++ let’s get the GCC compiler so we can compile C++ program. 

Allow us to open Ubuntu now and update the package list. 

sudo apt update

If you never set a password or don't remember. Use the following command

sudo passwd

Now, we will install build-essentials on our system using this command. Build-essential packages are a form of meta-package needed to compile software.

sudo apt install build-essential

We use the following command to display information about GCC, the GNU Compiler Collection. It is a set of compilers and development tools needed to run the program.

gcc --version

Ubuntu_gcc

We need to download two libraries here: curl and jsoncpp, and install them in the Ubuntu environment.

We are ready to install the latest version of the CURL library using this code.

sudo apt-get install libcurl4-openssl-dev

We are ready to install the latest version of the jsoncpp library with the help of this code.

sudo apt-get install libjsoncpp-dev

Let's move on to the next step:

Write some code

Now, we are entering the coding section. 

The include statement helps us to include the libraries we need. It is similar to collecting all the materials needed before starting a project. These imports help us connect to the internet, request and parse data.

#include <iostream>
#include <string>
#include <curl/curl.h>
#include <json/json.h>

The ‘namespace’ code allows us to access functions and classes from the namespace std.

using namespace std;

The WriteCallback function handles data retrieved from a web request with the help of curl library. It also helps to append data received to a string userp.

size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) {
    ((string*)userp)->append((char*)contents, size * nmemb);
    return size * nmemb;
}

The performCurlRequest function uses the libcurl library to get data from a URL. It sets up the tool, sends the request, manages the response using the WriteCallback method, and confirms if it all went well. It gives back true if successful, otherwise false.

bool performCurlRequest(const string& url, string& response) {
    CURL *curl = curl_easy_init();
    if (!curl) {
        cerr << "Failed to initialize CURL" << endl;
        return false;
    }

    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);

    CURLcode res = curl_easy_perform(curl);
    curl_easy_cleanup(curl);

    if (res != CURLE_OK) {
        cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << endl;
        return false;
    }

    return true;
}

The function parseJsonResponse uses the JsonCpp library to try parsing a JSON response provided as a string. It uses a "JSON reader" tool to do this. If parsing works, the parsed data is saved in the given variable (parsedRoot), and the function returns true. If there's a parsing error, it shows an error message and returns false.

bool parseJsonResponse(const string& jsonResponse, Json::Value& parsedRoot) {
    Json::CharReaderBuilder builder;
    Json::CharReader *reader = builder.newCharReader();
    string errs;

    bool parsingSuccessful = reader->parse(jsonResponse.c_str(), jsonResponse.c_str() + jsonResponse.size(), &parsedRoot, &errs);
    delete reader;

    if (!parsingSuccessful) {
        cerr << "Failed to parse JSON: " << errs << endl;
        return false;
    }

    return true;
}

Now, let us take a look at the place where real action happens! The below program defines api_url and response as a string then passes this to the performCurlRequest fucntion we defined in the previous step then passes the response it receives from curl to parseJsonResponse function. The parsed JSON data is then iterated over to display the bid and ask prices for the different currency pairs and stock index. 

Once we done with the parsing we clean up and release the resources libcurl library used.

int main() {

    string api_url = "https://marketdata.tradermade.com/api/v1/live?currency=EURUSD,GBPUSD,UK100&api_key=your_api_key";
    string response;

    curl_global_init(CURL_GLOBAL_DEFAULT);

    if (performCurlRequest(api_url, response)) {
        Json::Value root;
        if (parseJsonResponse(response, root)) {
            const Json::Value quotes = root["quotes"];
            for (const Json::Value &quote : quotes) {
                if (quote.isMember("bid") && quote.isMember("ask")) {
                    double bid = quote["bid"].asDouble();
                    double ask = quote["ask"].asDouble();
                    cout << "Bid: " << bid << ", Ask: " << ask << endl;
                }
            }
       }
    }

    curl_global_cleanup();
    return 0;
}

Now, we will ensure the code is error-free.

Debugging the Code and Getting Results

Now, we understand the code, we can debug, execute, and see the output.

First, save the code to the system before executing it. We are opening a new document and pasting the code into it.

We will name the file live. Any name can be used to save the file, but the cpp extension is mandatory to show the computer that we are saving a C++ file. 

Now, we need to compile and execute the program.

Compilation of our code needs adding the libraries curl and jsoncpp along with the path to the jsoncpp library.

 g++ -o live live.cpp -lcurl -ljsoncpp -I/usr/include/jsoncpp -L/usr/lib/x86_64-linux-gnu

We can execute our program now using the code. We use three currency pairs here:  EURUSD, GBPUSD, and a CFD instrument UK100. We ask the computer to get and print these financial instrument’s “bid” and “ask” values via the REST API.

./live

CPP_Historical

Voila! You can now see the result. You have successfully requested and parsed JSON REST API using C++.

Next Steps

TraderMade’s REST API is a user-friendly tool to develop digital solutions and gain valuable insights. Please use and build awesome apps in C++ and let us know.

Forex data endpoints refer to a specific URL providing Forex data through an API. To understand endpoints better, you can get started by signing up and exploring the REST API documentation. For more assistance, please don't hesitate to contact us via live chat or email support@tradermade.com. 

Here is the full program

#include <iostream>
#include <string>
#include <curl/curl.h>
#include <json/json.h>

using namespace std;

// Callback function to handle curl's response
size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) {
    ((string*)userp)->append((char*)contents, size * nmemb);
    return size * nmemb;
}

// Function to perform CURL request
bool performCurlRequest(const string& url, string& response) {
    CURL *curl = curl_easy_init();
    if (!curl) {
        cerr << "Failed to initialize CURL" << endl;
        return false;
    }

    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);

    CURLcode res = curl_easy_perform(curl);
    curl_easy_cleanup(curl);

    if (res != CURLE_OK) {
        cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << endl;
        return false;
    }

    return true;
}

// Function to parse JSON response
bool parseJsonResponse(const string& jsonResponse, Json::Value& parsedRoot) {
    Json::CharReaderBuilder builder;
    Json::CharReader *reader = builder.newCharReader();
    string errs;

    bool parsingSuccessful = reader->parse(jsonResponse.c_str(), jsonResponse.c_str() + jsonResponse.size(), &parsedRoot, &errs);
    delete reader;

    if (!parsingSuccessful) {
        cerr << "Failed to parse JSON: " << errs << endl;
        return false;
    }

    return true;
}

int main() {
    string api_url = "https://marketdata.tradermade.com/api/v1/live?currency=EURUSD,GBPUSD,UK100&api_key=api_key";
    string response;
    curl_global_init(CURL_GLOBAL_DEFAULT);
    if (performCurlRequest(api_url, response)) {
        Json::Value root;
        if (parseJsonResponse(response, root)) {
            const Json::Value quotes = root["quotes"];
            for (const Json::Value &quote : quotes) {
                if (quote.isMember("bid") && quote.isMember("ask")) {
                    double bid = quote["bid"].asDouble();
                    double ask = quote["ask"].asDouble();
                    cout << "Bid: " << bid << ", Ask: " << ask << endl;
                }
            }
        }
    }

    curl_global_cleanup();
    return 0;
}