AlgoDaily

Lesson 4: Working with REST APIs in C++

Read at your own pace. Code execution, quizzes, progress tracking, and the AI tutor are available in the interactive view with JavaScript enabled.

REST Bridge

Why this lesson matters

In Lesson 1: Introduction to API in C++, you learned to treat an API like a contract. In Lesson 2, you used that contract to read Gmail messages. In Lesson 3, you turned email text into structured buy/sell intent.

Now we zoom out and strengthen the layer underneath all of that: REST APIs over HTTP.

For an algorithmic trading workflow, REST is often used for:

  • reading account state
  • checking current positions
  • placing simple orders
  • fetching historical data
  • calling services like Gmail, broker APIs, or market-data APIs

A useful mental model:

signal parser  ->  REST client  ->  external service
BUY AAPL 10       HTTP request      broker / Gmail / data API

Today’s goal is not to memorize every HTTP detail. It is to build a clean C++ mindset for making REST calls safely and predictably.

REST Bridge

REST Shape

REST is resource-oriented HTTP

A REST API usually exposes resources through URLs.

Examples:

GET    /messages
GET    /messages/abc123
POST   /orders
GET    /positions
DELETE /orders/old-order-id

The key pieces of a REST request are:

Piece Example Trading meaning Method GET read data URL/path /positions resource to access Query string ?symbol=AAPL filters/options Headers Authorization: Bearer ... credentials/metadata Body JSON order payload data you send

In Lesson 2, Gmail used this shape. Here we make that shape reusable so your C++ code does not become a pile of one-off HTTP strings.

REST Shape

Build Requests

Separate request construction from sending

A common beginner mistake is mixing everything together:

build URL + add token + send + parse + trade decision

That becomes hard to test.

Instead, start with a tiny request model. Even before using a real HTTP library, your code can clearly represent:

  • method
  • path
  • query parameters
  • headers
  • optional body

This example does not contact the internet. It builds and prints the exact request shape your transport layer would send.

```cpp
#include <iostream>
#include <map>
#include <sstream>
#include <string>

struct RestRequest {
    std::string method;
    std::string baseUrl;
    std::string path;
    std::map<std::string, std::string> query;
    std::map<std::string, std::string> headers;
    std::string body;
};

std::string buildUrl(const RestRequest& req) {
    std::ostringstream out;
    out << req.baseUrl << req.path;

    if (!req.query.empty()) {
        out << "?";
        bool first = true;
        for (const auto& [key, value] : req.query) {
            if (!first) out << "&";
            out << key << "=" << value;
            first = false;
        }
    }
    return out.str();
}

void printRequest(const RestRequest& req) {
    std::cout << req.method << " " << buildUrl(req) << "\n";
    for (const auto& [key, value] : req.headers) {
        std::cout << key << ": " << value << "\n";
    }
    if (!req.body.empty()) {
        std::cout << "\n" << req.body << "\n";
    }
}

int main() {
    RestRequest req;
    req.method = "GET";
    req.baseUrl = "https://api.example-broker.com";
    req.path = "/positions";
    req.query = {{"symbol", "AAPL"}};
    req.headers = {
        {"Authorization", "Bearer ACCESS_TOKEN"},
        {"Accept", "application/json"}
    };

    printRequest(req);
    return 0;
}
```

Choose The Method

You are calling a broker-style REST API and want to read current open positions without changing anything on the server.

Which HTTP method is the best default choice?

Status Codes

REST responses are not just bodies

A REST response has at least two important parts:

status code + response body

Examples:

Status Meaning C++ client behavior 200 OK parse body 201 Created order/resource created 400 bad request fix payload/validation 401 unauthorized refresh token / re-auth 404 not found check ID/path 429 rate limited back off before retrying 500 server error retry carefully or alert

For trading-related code, never parse the body as if every response succeeded. Check the status first, then decide what the next safe action is.

```cpp
#include <iostream>
#include <string>

struct RestResponse {
    int statusCode;
    std::string body;
};

std::string classifyResponse(const RestResponse& res) {
    if (res.statusCode >= 200 && res.statusCode < 300) {
        return "success: parse response body";
    }
    if (res.statusCode == 401) {
        return "auth error: refresh token or stop";
    }
    if (res.statusCode == 429) {
        return "rate limited: wait before retry";
    }
    if (res.statusCode >= 500) {
        return "server error: retry carefully";
    }
    return "client error: inspect request before retry";
}

int main() {
    RestResponse examples[] = {
        {200, "{\"positions\":[]}"},
        {401, "{\"error\":\"expired token\"}"},
        {429, "{\"error\":\"too many requests\"}"},
        {500, "{\"error\":\"temporary failure\"}"}
    };

    for (const auto& res : examples) {
        std::cout << res.statusCode << " -> "
                  << classifyResponse(res) << "\n";
    }
    return 0;
}
```

Safe Retries

Retrying is powerful and dangerous

REST calls fail for normal reasons:

  • network timeout
  • rate limit
  • expired token
  • temporary server issue
  • malformed request

But in trading software, retries need discipline.

A failed GET /positions can usually be retried safely. A failed POST /orders is more sensitive because the first request might have succeeded even if your client did not receive the response.

A practical rule:

Retry reads more freely.
Retry writes only with safeguards.

Safeguards may include request IDs, idempotency keys, order status checks, and clear logging. We will stay REST-focused here; the next lesson will contrast this with FIX-style workflows.

Safe Retries

GET Is Harmless

True or false?

A GET request is normally intended for reading data, so a well-designed REST API should not use it to place trades or create orders.

Tiny REST Client

Use an interface around transport

In real C++ projects, you might use libcurl, Boost.Beast, CPR, Poco, or another HTTP library.

But your trading logic should not care which transport library is underneath. It should depend on a small interface like:

RestRequest -> RestResponse

That makes it easier to:

  • test without hitting real APIs
  • swap HTTP libraries later
  • log all requests in one place
  • keep Gmail, broker, and market-data calls consistent

The example below uses a fake transport so it is runnable and testable without external dependencies.

```cpp
#include <iostream>
#include <map>
#include <string>

struct RestRequest {
    std::string method;
    std::string path;
    std::map<std::string, std::string> headers;
    std::string body;
};

struct RestResponse {
    int statusCode;
    std::string body;
};

class IRestTransport {
public:
    virtual ~IRestTransport() = default;
    virtual RestResponse send(const RestRequest& request) = 0;
};

class FakeBrokerTransport : public IRestTransport {
public:
    RestResponse send(const RestRequest& request) override {
        std::cout << "Sending " << request.method
                  << " " << request.path << "\n";

        if (request.method == "GET" && request.path == "/positions") {
            return {200, "{\"positions\":[{\"symbol\":\"AAPL\",\"qty\":10}]}"};
        }
        return {404, "{\"error\":\"not found\"}"};
    }
};

int main() {
    FakeBrokerTransport transport;

    RestRequest req;
    req.method = "GET";
    req.path = "/positions";
    req.headers = {{"Authorization", "Bearer DEMO_TOKEN"}};

    RestResponse res = transport.send(req);

    std::cout << "Status: " << res.statusCode << "\n";
    std::cout << "Body: " << res.body << "\n";

    return 0;
}
```

Auth Header

Fill in the missing HTTP header name commonly used to send a bearer access token:

__________: Bearer ACCESS_TOKEN

REST Checklist

A practical C++ REST checklist

Before connecting a parsed trading signal to a real REST endpoint, walk through this checklist:

  1. Resource: What URL/path are you calling?
  2. Method: Is this a read or a write?
  3. Headers: Do you need auth, JSON content type, or request IDs?
  4. Body: Is the JSON payload valid and minimal?
  5. Status handling: What happens on 200, 401, 429, and 500?
  6. Retry policy: Is the request safe to retry?
  7. Logging: Can you debug without leaking secrets?
  8. Parsing: Do you validate the response before using it?

This lesson gives you the REST layer that sits between the signal parser from Lesson 3 and any external service you call next.

REST Checklist

Method Match

A parsed signal says:

BUY MSFT 5

You are preparing a REST request to create a new order resource on a broker-like API.

Which request shape is the most appropriate default?

Open interactive view →