Search code examples
javaspring-bootapi-key

Cannot detect API key from .env in my Spring Boot App


I want to create an app to use API Layer for currency exchange. I used a API key of Exchange Rates Data API in apilayer.com.

When I send a request to Get Rates defined in postman_collection in my repo.

I get this error message shown below

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "message" (class com.exchangeapi.currencyexchange.exception.RestTemplateError), not marked as ignorable (4 known properties: "error", "status", "path", "timestamp"])
 at [Source: (String)"{"message":"No API key found in request"}"; line: 1, column: 42] (through reference chain: com.exchangeapi.currencyexchange.exception.RestTemplateError["message"])

It always detect it as default-key.

After endpoint converts to this URL like https://api.apilayer.com/exchangerates_data/latest?symbols=USD%2CTRY&base=EUR, I revised it in getExchangeUrl method.

How can I fix it?

Here is the .env file shown below (I defined .gitignore not to upload to git repo)

EXCHANGE_API_API_KEY=MY_APIKEY

Here is the application.yml

exchange-api:
  api-url: https://api.apilayer.com/exchangerates_data/
  api-key: ${EXCHANGE_API_API_KEY:default-key}
  api-call-limit: 60
  cache-name: exchanges
  cache-ttl: 10000

Here is the Constants class shown below

@Component
public class Constants {

    public static String EXCHANGE_API_BASE_URL;
    public static String EXCHANGE_API_API_KEY;

    public static String EXCHANGE_CACHE_NAME;
    public static Integer EXCHANGE_API_CALL_LIMIT;

    @Value("${exchange-api.api-url}")
    public void setExchangeApiBaseUrl(String apiUrl) {
        Constants.EXCHANGE_API_BASE_URL = apiUrl;
    }

    @Value("${exchange-api.api-key}")
    public void setExchangeApiKey(String apiKey) {
        EXCHANGE_API_API_KEY = apiKey;
    }

    @Value("${exchange-api.cache-name}")
    public void setExchangeCacheName(String cacheName) {
        Constants.EXCHANGE_CACHE_NAME = cacheName;
    }

    @Value("${exchange-api.api-call-limit}")
    public void setExchangeApiCallLimit(Integer apiCallLimit) {
        EXCHANGE_API_CALL_LIMIT = apiCallLimit;
    }

}

Here is the relevant methods saveRatesFromApi of RateService

private RateEntity saveRatesFromApi(LocalDate rateDate, EnumCurrency base, List<EnumCurrency> targets) {

        log.info("ExchangeService | saveRatesFromApi is called");

        HttpHeaders headers = new HttpHeaders();
        headers.add("apikey", EXCHANGE_API_API_KEY);
        headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
        final HttpEntity<String> headersEntity = new HttpEntity<>(headers);
        String url = getExchangeUrl(rateDate, base, targets);

        ResponseEntity<RateResponse> responseEntity = restTemplate.exchange(url, HttpMethod.GET, headersEntity, RateResponse.class);

        RateResponse rates = responseEntity.getBody();
        RateEntity entity = convert(rates);
        entity.setDate(rateDate);
        return rateRepository.save(entity);
    }

private String getExchangeUrl(LocalDate rateDate, EnumCurrency base, List<EnumCurrency> targets) {
        String symbols = String.join("%2C", targets.stream().map(EnumCurrency::name).toArray(String[]::new));
        return EXCHANGE_API_BASE_URL + rateDate + "?symbols=" + symbols + "&base=" + base;
    }

Here is the repo : Link


Solution

  • I solved the issue.

    After I defined this part in the application.yml file, the issue was disappeared.

    spring:
      config:
        import: optional:file:.env[.properties]