# Com / Github / Blaxk3 / Api

## Overview

`com.github.blaxk3.api` contains a small API client for currency exchange lookups. This module appears to exist as a thin integration layer around the ExchangeRate API v6 service, handling configuration loading, HTTP requests, JSON parsing, and a couple of currency-specific convenience operations.

At a high level, the module provides a single entry point: `CurrencyRateAPI`. Engineers working in this package should expect network calls, nullable failure paths, and a dependency on a local `config.properties` file for the API key.

## Key Classes and Interfaces

### `CurrencyRateAPI`
Source: [src/main/java/com/github/blaxk3/api/CurrencyRateAPI.java](src/main/java/com/github/blaxk3/api/CurrencyRateAPI.java)

`CurrencyRateAPI` is the only class in this module and serves as a lightweight client for ExchangeRate API requests. It encapsulates four related responsibilities:

1. loading the API key from configuration,
2. building endpoint URLs,
3. fetching and parsing JSON responses, and
4. exposing convenience methods for currency metadata and conversion.

The class is intentionally simple and state-free. It does not cache credentials or responses, and it does not maintain any long-lived connection state. Each method call constructs what it needs and performs the request directly.

#### `getApiKeyService()`
Source: [CurrencyRateAPI.getApiKeyService()](src/main/java/com/github/blaxk3/api/CurrencyRateAPI.java:23)

This method loads `config.properties` from the application classpath and reads the `API_KEY` property.

- **Parameters:** none
- **Returns:** the API key as a `String`, or `null` if the file cannot be found or loaded
- **Behavior:**
  - Opens `config.properties` with the class loader.
  - Logs an error and returns `null` if the resource is missing.
  - Loads properties from the stream and returns `API_KEY`.
  - Catches `IOException`, logs the failure, and returns `null`.

This method is the module's configuration boundary. If the resource is missing or malformed, later methods will still try to build URLs, so callers need to be aware that downstream failures may surface indirectly.

#### `getURL()`
Source: [CurrencyRateAPI.getURL()](src/main/java/com/github/blaxk3/api/CurrencyRateAPI.java:38)

This method builds the base ExchangeRate API URL by concatenating the service host with the API key.

- **Parameters:** none
- **Returns:** the base API URL as a `String`
- **Behavior:** returns `https://v6.exchangerate-api.com/v6/` plus the value from `getApiKeyService()`.

This is a simple helper, but it also means the returned value depends entirely on configuration loading. If `getApiKeyService()` returns `null`, the resulting URL will contain `null` in the path.

#### `getJsonObject(URL url)`
Source: [CurrencyRateAPI.getJsonObject(URL url)](src/main/java/com/github/blaxk3/api/CurrencyRateAPI.java:42)

This method performs an HTTP GET request and parses the response body into a Gson `JsonObject`.

- **Parameters:**
  - `URL url` — the endpoint to call
- **Returns:** the parsed `JsonObject` on success, or `null` on failure
- **Behavior:**
  - Opens an `HttpURLConnection`.
  - Sets the request method to `GET`.
  - Checks the HTTP response code.
  - If the response is `200 OK`, reads the response content and parses it with `JsonParser`.
  - Logs an error for non-OK responses.
  - Catches any exception, logs it, and returns `null`.

This is the module's main I/O function. It centralizes request execution and JSON parsing, but it also swallows errors by returning `null`, so callers must perform null checks before dereferencing the result.

#### `getCurrencyCode()`
Source: [CurrencyRateAPI.getCurrencyCode()](src/main/java/com/github/blaxk3/api/CurrencyRateAPI.java:61)

This method fetches the list of available conversion codes from the `latest/USD` endpoint and returns the keys from the `conversion_rates` object.

- **Parameters:** none
- **Returns:** an array of currency codes, or `null` if the response is unavailable or does not contain the expected data
- **Behavior:**
  - Builds a URL using `getURL() + "/latest/" + "USD"`.
  - Calls `getJsonObject(...)`.
  - Checks whether the returned JSON contains `conversion_rates`.
  - Extracts the keys from that JSON object into a `String[]`.
  - Returns `null` if the object is missing or empty.

This method appears to be intended as a discovery/helper endpoint for populating a UI or validating supported currencies. It hardcodes `USD` as the base currency for the lookup.

#### `convert(String foreignCurrency1, String foreignCurrency2, BigDecimal amount)`
Source: [CurrencyRateAPI.convert(String foreignCurrency1, String foreignCurrency2, BigDecimal amount)](src/main/java/com/github/blaxk3/api/CurrencyRateAPI.java:72)

This method requests a currency conversion for a specific pair and amount, then returns the `conversion_result` field from the API response.

- **Parameters:**
  - `foreignCurrency1` — the source currency code
  - `foreignCurrency2` — the target currency code
  - `amount` — the amount to convert
- **Returns:** the `conversion_result` value as a `String`
- **Behavior:**
  - Builds a `/pair/{from}/{to}/{amount}` endpoint URL.
  - Calls `getJsonObject(...)`.
  - Reads the `conversion_result` field from the response and converts it to a string.

This method does not do any null checking before dereferencing the JSON result. If the request fails or the response is not in the expected shape, it will throw a `NullPointerException` at runtime. That makes the method convenient, but brittle.

## How It Works

The module follows a simple request pipeline:

1. Load the API key from `config.properties`.
2. Construct an ExchangeRate API URL.
3. Execute a GET request.
4. Parse the JSON response.
5. Extract the specific field the caller needs.

```mermaid
flowchart TD
CurrencyRateAPI["CurrencyRateAPI"] --> ConfigProperties["config.properties"]
CurrencyRateAPI --> ExchangeRateApi["ExchangeRate API v6"]
CurrencyRateAPI --> JsonObject["JsonObject responses"]
CurrencyRateAPI --> Logger["SLF4J logger"]
```

### Typical currency code lookup

`getCurrencyCode()` uses the `latest/USD` endpoint as a way to discover supported currencies. The response's `conversion_rates` object is treated as a dictionary of code-to-rate pairs, and only the keys are returned.

### Typical conversion request

`convert(...)` builds a `/pair/...` URL that includes the source currency, target currency, and amount. It then delegates all HTTP and JSON handling to `getJsonObject(...)` and extracts the `conversion_result` field from the parsed response.

### Error handling pattern

The module uses a consistent but minimal error strategy:

- log failures,
- return `null` in helper methods, or
- allow runtime failures if a caller assumes the response always exists.

That makes the code easy to follow, but it also means callers need to be defensive.

## Data Model

This module does not define its own domain model classes. Instead, it works directly with:

- `Properties` for configuration data,
- `URL` / `URI` for endpoint construction,
- Gson `JsonObject` / `JsonElement` for API responses, and
- `String[]` for extracted currency codes.

The implied JSON shapes are:

- `conversion_rates` — an object whose keys are currency codes
- `conversion_result` — a single numeric result field returned by the conversion endpoint

## Dependencies and Integration

### External libraries

The code uses:

- **Gson** for JSON parsing (`JsonParser`, `JsonObject`, `JsonElement`)
- **SLF4J** for logging (`Logger`, `LoggerFactory`)
- **JDK networking APIs** for HTTP access (`HttpURLConnection`, `URL`, `URI`)
- **JDK configuration APIs** for reading properties (`Properties`, `InputStream`, `InputStreamReader`)

### Runtime integration

The module integrates with the external ExchangeRate API service at `https://v6.exchangerate-api.com/v6/`.

It also depends on a classpath resource named `config.properties` containing an `API_KEY` property. Without that file, request construction cannot succeed.

## Notes for Developers

- `getApiKeyService()` can return `null`, so any code that uses `getURL()` should be prepared for malformed URLs.
- `getJsonObject(...)` returns `null` on failure; callers should check the result before dereferencing it.
- `convert(...)` currently assumes the response is valid and immediately reads `conversion_result`. If the API call fails, the method can throw at runtime.
- `getCurrencyCode()` is hardcoded to use `USD` as the base currency. If you need a different base, this method would need to change.
- The class does not cache responses or manage retries. If this client is used frequently, consider whether higher-level caching or resilience belongs elsewhere.
- The implementation is tightly coupled to the current ExchangeRate API response shape. Any upstream schema change would likely require updates here.

