---
name: http_get_json
kind: function
lang: cpp
domain: core
version: "1.0.0"
purity: impure
signature: "nlohmann::json fn_http::get_json(const std::string& url, const std::string& bearer_token = \"\", int timeout_ms = 5000)"
description: "Convenience wrapper over fn_http::request for the common case: GET <url> with optional Bearer auth, expect 2xx, parse body as JSON. Returns nlohmann::json. Throws std::runtime_error on transport failure, non-2xx status, or JSON parse error. For non-GET, custom headers, or status-aware control flow use http_request directly."
tags: [http, json, client, curl, network, registry-gap, core, helper]
uses_functions:
  - http_request_cpp_core
uses_types: []
returns: []
returns_optional: false
error_type: "error_go_core"
imports:
  - "core/http_get_json.h"
tested: true
tests:
  - "get_json: parses 200 JSON body"
  - "get_json: throws on 404"
  - "get_json: bearer_token reaches server"
  - "get_json: throws on invalid JSON"
test_file_path: "cpp/tests/test_http_get_json.cpp"
file_path: "cpp/functions/core/http_get_json.cpp"
params:
  - name: url
    desc: "Full URL incl. scheme (https://api.example.com/path?q=1)."
  - name: bearer_token
    desc: "Optional. If non-empty, sent as Authorization: Bearer <token>. Pass empty string for unauthenticated."
  - name: timeout_ms
    desc: "Hard timeout. Default 5000ms."
output: "nlohmann::json — the parsed body. Whatever shape the endpoint returns (object, array, scalar). Use json[\"key\"] / .at() / .get<T>() to traverse. Throws std::runtime_error on any failure."
---

## Ejemplo

```cpp
#include "core/http_get_json.h"

try {
    auto data = fn_http::get_json("https://httpbin.org/get");
    std::cout << "url echoed: " << data["url"].get<std::string>() << "\n";
} catch (const std::exception& e) {
    std::cerr << "fetch failed: " << e.what() << "\n";
}
```

Con Bearer token + timeout corto (sqlite_api `/api/databases`):

```cpp
auto dbs = fn_http::get_json(
    "http://localhost:8484/api/databases",
    std::getenv("SQLITE_API_TOKEN"),
    2000);
for (const auto& db : dbs) {
    std::cout << db["name"].get<std::string>() << "\n";
}
```

## Cuando usarla

- Cuando una app C++ necesita GET a un endpoint JSON y prefiere fail-fast (throw) en vez de inspeccionar `Response.status` a mano.
- Para pollers / heartbeats / health checks contra APIs internas (sqlite_api, services_api, registry_api).
- NO usar cuando necesites POST, headers custom, o distinguir entre 404 y 500 sin try/catch — usa `http_request` directo.

## Gotchas

- **Throws**, no devuelve un Result. Si llamas en un loop tight, envuelve en try/catch o tu app peta al primer 5xx.
- **Hereda gotchas de `http_request`**: requiere `curl` en PATH, sin streaming, sin cookies, TLS verify activo por defecto.
- **No reusa `get_json` cuando un endpoint devuelve algo que NO es JSON** (HTML, texto plano). La excepcion sera `invalid JSON` y perderas el status real. Usa `http_request` para esos casos.
- **`bearer_token` vacio es valido** (no se manda header). No pasar el `Authorization: Bearer ` literal — eso ya lo construye `http_request`.
- **No se ofrece `post_json`** intencionalmente — la combinatoria de POST + JSON + auth + retry es lo suficientemente rica como para que `http_request` directo sea mas claro que un wrapper con N parametros opcionales.
