- Obter uma chave de autenticação para uso não comercial da API externa em CurrencyAPI.net e inserí-la como o valor da variável de instância "apiKey", da classe CurrencyManager1, com a chave obtida;
- Configurar o ambiente a ser utilizado;
- Criar a tabela de Banco de Dados conforme descrito no arquivo challenge-bravo-DB.sql;
- Alterar os valores das variáveis de instância (server, db, user e pass) da classe ConnectionFactory de acordo com o ambiente a ser utilizado;
- Executar o arquivo inicializarAPI.php.
- PHP 7.2.24
- cURL 7.58.0
- MySQL 5.7.37
- API externa - currencyapi.net
- Servidor HTTP Apache 2.4.29
- Sistema Operacional Ubuntu 18.04.6 LTS
Este trabalho procurou implementar os requisitos solicitados, utilizando a seguinte arquitetura em camadas:
- A classe Currency para descrever o modelo;
- A classe CurrencyDAO para realizar o acesso e a persistência dos dados;
- A classe CurrencyManager para implementar as funções solicitadas nos requisitos do desafio;
- A classe SecurityManager para prover um controle básico dos valores inseridos nos parâmetros da API;
- Os endpoints convertCurrency, addCurrency, updateCurrency e removeCurrency, para responder às requisições HTTP do tipo GET;
- O endpoint currencies para tratar os verbos HTTP, funcionando como uma espécie de Adaptador, chamando o respectivo endpoint para os métodos POST, PUT, DELETE do protocolo HTTP.
Método HTTP: GET
Parâmetros obrigatórios: from, to, amount
Endpoint: convertCurrency.php
Exemplo: http://{LOCAL_DA_API}/convertCurrency.php?from={MOEDA1}&to={MOEDA2}&amount={MONTANTE}
- Retorno esperado:
{
"error":"", // true or false - se houve erro
"from":"", // parâmetro GET from
"to":"", // parâmetro GET to
"amount":"", // parâmetro GET amount
"result":"", // resultado da conversão
"msg":"", // mensagem da API de erro ou sucesso
"query-timestamp":"" // timestamp da consulta realizada
}
- Via Browser URL:
Método HTTP: GET
Parâmetros obrigatórios: code, name, rate
Endpoint: addCurrency.php
Exemplo: http://{LOCAL_DA_API}/addCurrency.php?code={CODIGO}&name={NOME}&rate={COTACAO}
- Via método HTTP POST (utilizando CLI):
Exemplo: curl -X POST -F "code={CODIGO}" -F "name={NOME}" -F "rate={COTACAO}" http://{LOCAL_DA_API}/currencies.php
- Retorno esperado:
{
"error":"", // true or false - se houve erro
"code":"", // parâmetro GET code
"name":"", // parâmetro GET nome
"rate":"", // parâmetro GET rate - cotação em dolar
"msg":"", // mensagem da API de erro ou sucesso
"query-timestamp":"" // timestamp da consulta realizada
}
- Via Browser URL:
Método HTTP: GET
Parâmetros obrigatórios: code, rate
Endpoint: updateCurrency.php
Exemplo: http://{LOCAL_DA_API}/updateCurrency.php?code={CODIGO}&rate={COTACAO}
- Via método HTTP PUT (utilizando CLI):
Método HTTP: PUT
Parâmetros obrigatórios: code, rate
Endpoint: currencies.php
Exemplo: curl -X PUT -d "code={CODIGO}&rate={COTACAO}" http://{LOCAL_DA_API}/currencies.php
- Retorno esperado:
{
"error":"", // true or false - se houve erro
"code":"", // parâmetro GET code
"rate":"", // parâmetro GET rate - cotação em dolar
"msg":"", // mensagem da API de erro ou sucesso
"query-timestamp":"" // timestamp da consulta realizada
}
- Via Browser URL:
Método HTTP: GET
Parâmetros obrigatórios: code
endpoint: removeCurrency.php
Exemplo: http://{LOCAL_DA_API}/removeCurrency.php?code={CODIGO}
- Via método HTTP DELETE (utilizando CLI):
Método HTTP: DELETE
Parâmetros obrigatórios: code
endpoint: currencies.php
Exemplo: curl -X DELETE -d "code={CODIGO}" http://{LOCAL_DA_API}/currencies.php
- Retorno esperado:
{
"error":"", // true or false - se houve erro
"code":"", // parâmetro GET code
"msg":"", // mensagem da API de erro ou sucesso
"query-timestamp":"" // timestamp da consulta realizada
}
Durante a implementação foram identificadas e tratadas as seguintes restrições de integridade:
- Moedas criadas a partir da API não podem ter o mesmo nome que moedas já existentes;
- Moedas criadas a partir da API não podem ter o mesmo código que moedas já existentes;
- Moedas obtidas a partir da API externa não podem ter a cotação atualizada;
- Moedas obtidas a partir da API externa não podem ser excluídas.
E duas restrições externas impostas pelo uso gratuito da API currencyapi.net:
- Quantidade de acessos permitido - 1250 requisições/mês;
- Taxa de atualização das cotações - hora em hora.
Por isso, esta solução também procurou economizar os acessos à API externa, tratando as requisições localmente, caso o intervalo entre o horário da última atualização e o horário atual seja menor do que uma hora.
Espero que gostem!
- Docker 20.10.7
- Docker Compose 1.17.1
- Imagens:
- Servidor HTTP: php:7.2-apache2
- Banco de dados: mysql:5.7
- Interface de Acesso ao banco de dados: phpmyadmin/phpmyadmin (Opcional)
- API externa - currencyapi.net
- Instalar o Docker e o Docker Compose (preferencialmente nas versões informadas na subseção anterior)
- Clonar este repositório (git clone https://github.com/alexandre-abdalla/challenge-bravo.git)
- Obter uma chave de autenticação para uso não comercial da API externa em CurrencyAPI.net e inserí-la no arquivo apiKey.txt, em branco, encontrado na raiz do repositório;
- Navegar até o diretório clone deste repositório e executar o comando docker-compose up -d --build
- Inicializar a API de uma das seguintes maneiras:
- Via browser: Acessar a URL: http://localhost:8088/inicializarAPI.php
- Via CLI:- curl http://localhost:8088/inicializarAPI.php
- docker-compose run web-server php /var/www/html/inicializarAPI.php 3
Após isso, é esperado que o sistema retorne a mensagem "API carregada com sucesso!".
OBS: Os exemplos de uso podem ser seguidos, de acordo com a seção Exemplos de Uso, alterando {LOCAL_DA_API} por localhost:8088.
- Notebook (descrição de hardware em lshw.txt)
- Sistema Operacional Ubuntu 18.04.6 LTS
- Instâncias Virtualizadas com o Docker Compose:
- Apache/2.4.38 (Debian)
- PHP 7.2.34
- MySQL 5.7.38
- Jmeter 2.13.20170723
Footnotes
-
Este arquivo foi alterado para se adequar à implantação com Docker. Para utilizá-lo da forma aqui descrita, será também necessário remover o construtor da classe. ↩
-
Com as extensões pdo e pdo_mysql adicionadas via Dockerfile ↩
-
No diretório clone deste repositório ↩