---

# (DD07) Business Logic — CurrencyRateAPI.getJsonObject() [17 LOC]

| Field | Value |
|-------|-------|
| Fully Qualified Name | `com.github.blaxk3.api.CurrencyRateAPI` |
| Layer | Utility (Package: `com.github.blaxk3.api`) |
| Module | `api` (Package: `com.github.blaxk3.api`) |

## 1. Role

### CurrencyRateAPI.getJsonObject()

This method is the core HTTP client dispatcher that sends a GET request to an external currency exchange rate API (Exchangerate API v6) and deserializes the JSON response into a Gson `JsonObject`. Business-wise, it serves as the **data fetcher** for currency rate lookups — retrieving either a full list of supported currency codes (via the `/latest/USD` endpoint) or a specific currency pair conversion result (via the `/pair/` endpoint). It implements the **delegation pattern**: all HTTP communication details are encapsulated behind this single method, while higher-level methods (`getCurrencyCode` and `convert`) compose it with specific endpoint URLs and post-process the returned JSON. Its role in the larger system is that of a shared utility method called exclusively from within `CurrencyRateAPI` itself; no external classes invoke it directly. The method handles three branches: (1) a successful HTTP 200 response — the JSON is parsed and returned; (2) a non-200 HTTP response — an error is logged with the response code and processing continues to return null; (3) any thrown exception — the exception is caught, logged, and null is returned.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["getJsonObject(url)"])
    START --> TRY_BLOCK["try Block Start"]
    TRY_BLOCK --> OPEN_CONN["Create HttpURLConnection from url"]
    OPEN_CONN --> SET_METHOD["Set request method to GET"]
    SET_METHOD --> GET_RESP["Get HTTP response code"]
    GET_RESP --> CHECK_OK{responseCode == HTTP_OK}
    CHECK_OK -->|true| PARSE_JSON["Parse JSON from response body"]
    PARSE_JSON --> RETURN_JSON["Return JsonObject"]
    RETURN_JSON --> END_NESTED["End"]
    CHECK_OK -->|false| LOG_ERROR["Log error with response code"]
    LOG_ERROR --> CLOSE_NESTED["End"]
    CLOSE_NESTED --> RETURN_NULL["Return null"]
    TRY_BLOCK --> CATCH_BLOCK{"catch Exception"}
    CATCH_BLOCK --> LOG_EXCEPTION["Log exception error"]
    LOG_EXCEPTION --> RETURN_NULL
```

**Constant Resolution:**

| Constant | Actual Value | Business Meaning |
|----------|-------------|------------------|
| `HttpURLConnection.HTTP_OK` | `200` | HTTP 200 OK — the API request succeeded and the response body contains valid JSON data |

**Requirements:**
- Diamond nodes represent the condition `responseCode == HttpURLConnection.HTTP_OK` (i.e., HTTP 200).
- All branches are shown: success (200), failure (non-200), and exception handling.
- Method calls: `url.openConnection()`, `setRequestMethod("GET")`, `getResponseCode()`, `request.getContent()`, `JsonParser.parseReader(...)`, `root.getAsJsonObject()`.

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| 1 | `url` | `URL` | The endpoint URL of the Exchangerate API v6 service to query. It embeds the API key (retrieved via `getApiKeyService()`) and a specific endpoint path such as `/latest/USD` for fetching supported currencies or `/pair/CAD/JPY/100` for a currency pair conversion. The URL determines which business data is returned — a full currency code map or a single conversion rate value. |

**External State Read:**
| Field | Description |
|-------|-------------|
| `logger` | Slf4j logger instance used to log errors on API failures or exceptions |

## 4. CRUD Operations / Called Services

This method performs **no database or SC (Service Component) operations**. It is a pure HTTP client method that interacts exclusively with an external REST API. The only method calls are Java standard library and Gson API calls for HTTP connection and JSON parsing.

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `HttpURLConnection.getConnection()` / `JsonParser.parseReader()` | — | — | HTTP GET request to external Exchangerate API and JSON body parsing |

**How to classify:**
- **R** (Read): `HttpURLConnection` sends an HTTP GET request to fetch data from the Exchangerate API, and `JsonParser.parseReader` deserializes the JSON response body.

## 5. Dependency Trace

### Pre-computed evidence from code analysis graph:

| # | Caller (Screen/Batch) | Call Chain (Full Path to Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|----------------------------------|-------------------------------|
| 1 | Controller:CurrencyRateAPI | `CurrencyRateAPI.getCurrencyCode` -> `CurrencyRateAPI.getJsonObject` | HTTP GET `/latest/USD` [R] Exchangerate API |
| 2 | Controller:CurrencyRateAPI | `CurrencyRateAPI.convert` -> `CurrencyRateAPI.getJsonObject` | HTTP GET `/pair/{from}/{to}/{amount}` [R] Exchangerate API |

**Callers:**

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | Controller:CurrencyRateAPI | `getCurrencyCode` -> `getJsonObject` | HTTP GET `/latest/USD` [R] Exchangerate API |
| 2 | Controller:CurrencyRateAPI | `convert` -> `getJsonObject` | HTTP GET `/pair/{from}/{to}/{amount}` [R] Exchangerate API |

## 6. Per-Branch Detail Blocks

**Block 1** — TRY-CATCH `(try)` (L43)

> Attempt to open an HTTP connection and parse the JSON response.

| # | Type | Code |
|---|------|------|
| 1 | SET | `HttpURLConnection request = (HttpURLConnection) url.openConnection()` | Create an HTTP connection object from the provided URL |
| 2 | EXEC | `request.setRequestMethod("GET")` | Configure the request as a GET operation |
| 3 | SET | `int responseCode = request.getResponseCode()` | Read the HTTP response status code |
| 4 | IF | `if (responseCode == HttpURLConnection.HTTP_OK)` → see Block 1.1 | Branch on HTTP response code; HTTP_OK = 200 |

**Block 1.1** — IF `(responseCode == HttpURLConnection.HTTP_OK)` [HTTP_OK = "200"] (L45)

> If the API returned HTTP 200 OK, parse the JSON response body and return it.

| # | Type | Code |
|---|------|------|
| 1 | SET | `JsonElement root = JsonParser.parseReader(new InputStreamReader((InputStream) request.getContent()))` | Read the response body as an InputStream, wrap in InputStreamReader, and parse into a JsonElement tree |
| 2 | RETURN | `return root.getAsJsonObject()` | Extract and return the root element as a JsonObject |

**Block 1.2** — ELSE `(responseCode != HttpURLConnection.HTTP_OK)` (L51)

> If the API returned a non-200 status code (e.g., 401 Unauthorized, 404 Not Found, 429 Rate Limited), log the error and fall through to return null.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `logger.error("GET request failed with response code: {}", responseCode)` | Log the HTTP error status code for diagnostic purposes |

**Block 1.3** — CATCH `(catch Exception e)` (L54)

> If any exception is thrown during the HTTP connection (e.g., `IOException`, `NullPointerException`), log the error and fall through to return null.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `logger.error("An error occurred during the API request", e)` | Log the exception with full stack trace for debugging |

**Block 2** — RETURN `return null` (L57)

> Return null as the default fallback when the API request fails (either non-200 response or exception). Callers must handle null — `getCurrencyCode` checks for null before accessing keys, while `convert` does not null-check and may throw `NullPointerException` if the API is unreachable.

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `url` | Parameter | The full URL of the Exchangerate API endpoint, including the API key |
| Exchangerate API | External Service | A third-party REST API (v6.exchangerate-api.com) that provides real-time and historical foreign exchange currency rates |
| HTTP_OK | Constant | HTTP status code 200, indicating a successful response |
| HttpURLConnection | Java Class | Java standard library class used to make HTTP requests |
| JsonObject | Gson Type | A mutable JSON object (key-value pairs) from the Google Gson library |
| JsonElement | Gson Type | Base class for all JSON tree nodes (can be object, array, string, number, etc.) |
| JsonParser | Gson Class | Utility class for parsing JSON strings or readers into JsonElement trees |
| `getApiKeyService()` | Method | Retrieves the API key from `config.properties`, which is embedded in the Exchangerate API URL |
| `conversion_rates` | JSON Field | A JSON object mapping 3-letter currency codes (e.g., "USD", "EUR", "JPY") to their exchange rates relative to a base currency |
| `conversion_result` | JSON Field | A numeric value returned by the `/pair/` endpoint representing the converted amount |
| API_KEY | Config Property | The authentication key for the Exchangerate API, stored in `config.properties` |

---
