# Com / Github / Blaxk3 / Api

## Overview

The `com.github.blaxk3.api` package appears to provide a small adapter around the ExchangeRate-API service. Its only class, [`CurrencyRateAPI`](src/main/java/com/github/blaxk3/api/CurrencyRateAPI.java:19), loads an API key from local configuration, constructs request URLs, fetches JSON responses over HTTP, and exposes convenience methods for retrieving currency codes and converting amounts between currencies.

This module exists to keep external currency-rate access in one place. Rather than spreading HTTP and JSON parsing logic across the application, the package centralizes the remote API interaction behind a single class.

## Key Classes and Interfaces

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

`CurrencyRateAPI` is a lightweight service-style class with no fields beyond a logger. It encapsulates the mechanics of talking to `https://v6.exchangerate-api.com/`, including configuration lookup, request execution, and basic response extraction.

The class is intentionally simple, but it has a few distinct responsibilities:

- read the API key from `config.properties`
- build base and endpoint URLs
- execute GET requests and parse the JSON body
- expose higher-level helpers for listing available currency codes and converting between two currencies

Because the class is self-contained and stateless, it can be instantiated where needed without additional setup.

#### Methods

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

Loads `config.properties` from the classpath and returns the value of the `API_KEY` property.

- **Parameters:** none
- **Returns:** the API key as a `String`, or `null` if the file cannot be found or loaded
- **Side effects:** logs an error when the config file is missing or unreadable

Implementation notes:

- The method uses the class loader to read `config.properties` as a resource.
- If the resource stream is `null`, it logs `Unable to find config.properties` and returns `null`.
- If loading fails with `IOException`, it logs the exception and returns `null`.

This method is the module’s configuration entry point, so any caller depending on currency access must ensure the property file is packaged correctly.

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

Builds the base URL used by the ExchangeRate API.

- **Parameters:** none
- **Returns:** a base URL string in the form `https://v6.exchangerate-api.com/v6/<API_KEY>`
- **Side effects:** indirectly depends on `getApiKeyService()` and therefore on `config.properties`

This method does not validate the returned key. If `getApiKeyService()` returns `null`, the resulting URL will contain the string `null`.

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

Performs an HTTP GET request and parses the JSON response into a `JsonObject`.

- **Parameters:** `url` - the endpoint to call
- **Returns:** a parsed `JsonObject` when the server responds with HTTP 200, otherwise `null`
- **Side effects:** performs network I/O and logs failures

How it behaves:

1. Opens an `HttpURLConnection` for the given URL.
2. Sets the request method to `GET`.
3. Checks the HTTP response code.
4. If the response is `HTTP_OK`, it reads the response body and parses it with `JsonParser`.
5. If the response code is anything else, it logs the status code and returns `null`.
6. If any exception occurs, it logs the error and returns `null`.

A notable detail is that the method reads the response body via `request.getContent()` and casts it to `InputStream`. That means callers rely on the remote service returning a parseable JSON payload for successful requests.

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

Fetches the latest conversion table for USD and returns the available currency codes as a string array.

- **Parameters:** none
- **Returns:** an array of currency code strings, or `null` if the response is missing or malformed
- **Throws:** `MalformedURLException`, `URISyntaxException`
- **Side effects:** performs network I/O through `getJsonObject()`

The method calls the endpoint built from `getURL() + "/latest/USD"` and expects the response to contain a `conversion_rates` object.

Processing steps:

1. Build the latest-rates URL for `USD`.
2. Fetch and parse the JSON payload.
3. Check for a `conversion_rates` field.
4. Read the keys of that object and convert them to `String[]`.
5. Return `null` if the object is missing or empty.

This appears to be a convenience method for populating UI controls or validation lists with supported currency codes.

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

Converts a monetary amount from one currency to another using the remote API.

- **Parameters:**
  - `foreignCurrency1` - source currency code
  - `foreignCurrency2` - target currency code
  - `amount` - amount to convert
- **Returns:** the `conversion_result` field from the JSON response as a `String`
- **Throws:** `MalformedURLException`, `URISyntaxException`
- **Side effects:** performs network I/O through `getJsonObject()`

The method calls the pair conversion endpoint and extracts only the `conversion_result` field. It does not validate the input currencies, and it does not perform null checks on the returned JSON object, so callers should treat it as a thin, failure-prone wrapper around the remote API.

## How It Works

At a high level, the flow through this module is:

1. Read an API key from `config.properties`.
2. Construct the ExchangeRate-API base URL.
3. Append an endpoint path for the desired operation.
4. Execute the HTTP request.
5. Parse the JSON response.
6. Extract either currency codes or a conversion result.

The class uses the same low-level request method for both supported operations, which keeps the HTTP behavior consistent. The price of that simplicity is limited resilience: failures are mostly reported through logs and `null` returns, with only a small amount of validation before dereferencing response fields.

### Relationship diagram

```mermaid
flowchart LR
API["CurrencyRateAPI"] --> Config["config.properties"]
API --> ExchangeRate["v6.exchangerate-api.com"]
API --> JsonParser["Gson JsonParser"]
API --> Latest["getCurrencyCode()"]
API --> Convert["convert(String, String, BigDecimal)"]
Latest --> Rates["conversion_rates"]
Convert --> Result["conversion_result"]
```

## Data Model

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

- `String` for API keys, currency codes, base URLs, and conversion results
- `BigDecimal` for the amount being converted
- `JsonObject` and `JsonElement` for parsed API responses
- `String[]` for the set of supported currency codes

The implicit API response model is important:

- `/latest/USD` is expected to contain a `conversion_rates` object
- `/pair/{from}/{to}/{amount}` is expected to contain a `conversion_result` field

Those fields are treated as part of the contract of the remote service, not as local model classes.

## Dependencies and Integration

### External libraries

The class relies on a small set of external APIs:

- `com.google.gson` for JSON parsing
- `org.slf4j` for logging
- `java.net.HttpURLConnection` and `java.net.URL` for HTTP access
- `java.util.Properties` for configuration loading

### Remote service

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

- the API key is present in `config.properties`
- the service responds with JSON
- the relevant response fields are present and named as expected

## Notes for Developers

- **Configuration is mandatory.** If `config.properties` is missing from the runtime classpath, `getApiKeyService()` returns `null`, which will likely break every downstream request.
- **Error handling is minimal.** Most failures become logs plus `null` returns. Callers should check for `null` before using results from `getJsonObject()` or `getCurrencyCode()`.
- **`convert()` assumes success.** It immediately dereferences `getJsonObject(...).get("conversion_result")`, so a failed request can produce a `NullPointerException`.
- **`getCurrencyCode()` is hard-coded to USD.** If other base currencies are needed, this method would need to be generalized.
- **The class is a thin wrapper, not a full client.** There is no retry logic, caching, request timeout configuration, or structured error model.
- **Potential extension point:** if the application starts making more currency-related calls, this class could be split into a reusable HTTP client layer plus higher-level currency operations.

## Source Reference

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