# Com / Github / Blaxk3 / Api

## Overview

The `com.github.blaxk3.api` package appears to provide a very small HTTP client wrapper around the ExchangeRate-API service. Its main responsibility is to load an API key from local configuration, build request URLs, call the remote service, and expose a couple of convenience methods for discovering supported currency codes and converting an amount between two currencies.

This module exists to centralize the external API integration behind a simple Java class so the rest of the application does not need to manage URL construction, HTTP details, or JSON parsing directly.

## Key Classes and Interfaces

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

`CurrencyRateAPI` is the only class in this package and it acts as the service boundary for currency-rate lookups. It encapsulates three concerns:

1. loading the API key from `config.properties`,
2. executing HTTP requests against the ExchangeRate-API endpoint, and
3. extracting the specific pieces of JSON the caller needs.

The class is intentionally lightweight, but it mixes configuration access, network access, and response parsing into one place. That makes it easy to call, but also means failures are handled locally rather than through a richer domain abstraction.

#### `getApiKeyService()`

- **Purpose:** Loads the `API_KEY` value from `config.properties` on the classpath.
- **Parameters:** None.
- **Returns:** A `String` containing the API key, or `null` if the file is missing or unreadable.
- **Behavior:**
  - Opens `config.properties` using the class loader.
  - Logs an error and returns `null` if the file cannot be found.
  - Loads the properties file and reads the `API_KEY` property.
  - Logs and returns `null` if an `IOException` occurs.
- **Important note:** Callers must be prepared for `null`, because the method does not fail fast or throw a custom exception when configuration is missing.

#### `getURL()`

- **Purpose:** Builds the base ExchangeRate-API URL using the configured API key.
- **Parameters:** None.
- **Returns:** A `String` such as `https://v6.exchangerate-api.com/v6/<API_KEY>`.
- **Behavior:** Concatenates the service base URL with the value returned by `getApiKeyService()`.
- **Important note:** If the API key lookup returns `null`, the resulting URL will contain `null` as part of the path.

#### `getJsonObject(URL url)`

- **Purpose:** Performs a GET request and parses the response body as JSON.
- **Parameters:**
  - `URL url` - the endpoint to call.
- **Returns:** A `JsonObject` when the HTTP response is `200 OK`; otherwise `null`.
- **Behavior:**
  - Opens an `HttpURLConnection`.
  - Sets the request method to `GET`.
  - Checks the HTTP status code.
  - If the status is `HTTP_OK`, reads the response content and parses it with Gson's `JsonParser`.
  - Logs non-OK response codes and any exception encountered during the request.
- **Important note:** This method returns `null` on failure instead of throwing, so callers must check for `null` before dereferencing the result.

#### `getCurrencyCode()`

- **Purpose:** Fetches the list of currency codes supported by the API.
- **Parameters:** None.
- **Returns:** A `String[]` of currency code keys, or `null` if the response does not contain the expected data.
- **Behavior:**
  - Builds a URL for the `latest/USD` endpoint.
  - Calls `getJsonObject(...)`.
  - Looks for a `conversion_rates` object in the JSON response.
  - Returns the keys of that object as an array.
- **Throws:** `MalformedURLException`, `URISyntaxException`.
- **Important note:** The method assumes the API response schema contains `conversion_rates`; if the schema changes or the request fails, it returns `null`.

#### `convert(String foreignCurrency1, String foreignCurrency2, BigDecimal amount)`

- **Purpose:** Converts an amount from one currency to another using the remote API.
- **Parameters:**
  - `foreignCurrency1` - source currency code.
  - `foreignCurrency2` - target currency code.
  - `amount` - the amount to convert.
- **Returns:** The `conversion_result` field from the JSON response as a `String`.
- **Behavior:**
  - Builds a `/pair/<from>/<to>/<amount>` endpoint.
  - Calls `getJsonObject(...)`.
  - Reads the `conversion_result` field from the JSON object.
- **Throws:** `MalformedURLException`, `URISyntaxException`.
- **Important note:** This method does not check whether `getJsonObject(...)` returned `null`, so a failed request will likely cause a `NullPointerException`.

## How It Works

A typical interaction with this module follows this flow:

1. A caller creates a `CurrencyRateAPI` instance.
2. The class reads the API key from `config.properties` through the classpath.
3. It constructs a request URL for the ExchangeRate-API service.
4. It opens an HTTP connection and issues a GET request.
5. It parses the JSON response using Gson.
6. It extracts either:
   - the available currency codes from `conversion_rates`, or
   - the converted amount from `conversion_result`.

```mermaid
flowchart TD
Module["com.github.blaxk3.api"] --> CurrencyRateAPI["CurrencyRateAPI"]
CurrencyRateAPI --> ApiKeyService["getApiKeyService"]
CurrencyRateAPI --> URLBuilder["getURL"]
CurrencyRateAPI --> JsonFetcher["getJsonObject"]
CurrencyRateAPI --> CurrencyCodes["getCurrencyCode"]
CurrencyRateAPI --> Convert["convert"]
```

### Request flow for currency code lookup

1. `getCurrencyCode()` builds a `latest/USD` request URL.
2. `getJsonObject(...)` sends the HTTP request.
3. On success, the JSON response is inspected for `conversion_rates`.
4. The keys of that object are returned as a string array.

### Request flow for conversion

1. `convert(...)` builds a `pair/<from>/<to>/<amount>` request URL.
2. `getJsonObject(...)` performs the GET request.
3. The method reads `conversion_result` from the returned JSON.
4. The result is returned as a string.

## Data Model

This package does not define its own domain entities, DTOs, or model classes. Instead, it works directly with:

- `Properties` for configuration loading,
- `JsonObject` / `JsonElement` for response parsing, and
- `String[]` / `String` for the values exposed to callers.

The external JSON schema is assumed to contain at least two fields:

- `conversion_rates` - an object whose keys represent supported currency codes.
- `conversion_result` - the converted numeric result for a pair conversion.

Because these are read directly from the upstream API response, changes to the external schema will affect this module immediately.

## Dependencies and Integration

`CurrencyRateAPI` integrates with:

- the **ExchangeRate-API** service at `https://v6.exchangerate-api.com/v6/...`,
- a local **`config.properties`** file on the classpath for the `API_KEY`,
- **Gson** (`JsonParser`, `JsonObject`, `JsonElement`) for JSON parsing, and
- **SLF4J** for error logging.

The package has no other resolved internal dependencies in the index, which suggests it is a standalone integration layer rather than part of a larger API abstraction.

## Notes for Developers

- The class treats configuration and HTTP errors as recoverable and returns `null` rather than throwing in most helper methods. Callers should handle missing data defensively.
- `convert(...)` does not guard against a `null` return from `getJsonObject(...)`, so it is the most failure-prone method in the class.
- `getCurrencyCode()` is hard-coded to query `USD` as the base currency when discovering supported codes.
- The class currently combines configuration access, transport, and parsing in one unit. If the module grows, a future refactor could separate those responsibilities into smaller collaborators.
- Since the API key is loaded from the classpath, packaging and deployment need to ensure `config.properties` is available at runtime.
