Foi construída uma API que realiza a conversão entre moedas reais, criptomoedas e moedas customizadas criadas pelos usuários, todos lastreados no dólar americano. Para tal o servidor utiliza como fonte dados os serviços CoinLayer, CurrencyLayer e Fixer, os quais oferecem uma cota gratuita de uso que gira em torno de 1.000 requisições/mês para o CoinLayer e CurrencyLayer e 100 requisições/mês para o Fixer mediante o uso de uma chave de acesso, porém é importante ressaltar que em todos os serviços existe um atraso de pelo menos 1 hora nas cotações.
Também foi desenvolvida uma interface gráfica utilizando Angular 13 a qual tem por intuito demostrar as funcionalidades da API em um caso real de uso.
Ao iniciar o bravo-server o servidor realiza a transferência da lista moedas disponíveis nos serviços e as armazena em banco de dados e em cache, em seguida é iniciado um serviço o qual é executado imediatamente e depois a cada 8 horas, o qual realiza a atualização das cotações das moedas e as armazena exclusivamente cache.
Aplicação utiliza como banco de dados o servidor PostgreSQL e como cache o servidor Redis. A linguagem de programação utilizada no servidor foi Go versão 1.17 com apoio das seguintes bibliotecas:
- Apitest - Biblioteca para testes de API
- Fiber - Framework de alta performance para roteamento de requisições web
- Go-redis - Cliente para Go para servidor Redis
- Scany - Converte resultados de consultas SQL em structs
- Squirrel - Gerador de consultas SQL
- Testify - Ferramenta para casos de teste
Enquanto na aplicação de front end foi utilizado o framework Angular 13 com o apoio da biblioteca de componentes PimeNG.
O bravo-server pode obter suas configurações das variáveis do ambiente ou da linha de comando, sendo que os valores fornecidos pela linha de comando possuem prioridade. Abaixo segue a relação dos parâmetros de linha de comando e ambiente disponíveis:
- -host ou BRAVO_HOST (opcional) - Nome do host do servidor web, o padrão é todos
- -port ou BRAVO_PORT (opcional, padrão 8080) - Número da porta do servidor web
- -cert ou BRAVO_CERT_FILE (opcional) - Caminho do arquivo .pem para conexões https
- -key ou BRAVO_KEY_FILE (opcional) - Caminho do arquivo .key para conexões https
- -db ou BRAVO_DB - String de conexão com o servidor Postgres ex: postgres://usuario:senha@url:5432/banco
- -cache ou BRAVO_CACHE - String de conexão com o servidor Redis ex: redis://url:6379/0
- -coin-layer ou BRAVO_COIN_LAYER_KEY - Chave do serviço CoinLayer
- -currency-layer ou BRAVO_CURRENCY_LAYER_KEY - Chave do serviço CurrencyLayer
- -fixer ou BRAVO_FIXER_KEY - Chave do serviço Fixer
- -help - Imprime a ajuda
Na pasta deployments
existe uma configuração para a execução da aplicação, de seus testes unitários e dos servidores
de banco de dados, cache e administração do Postgres em containers Docker. Caso seja necessário alterar alguma
configuração como, por exemplo, alguma chave de serviço deve-se editar o arquivo docker-composer.yml
onde
encontram-se as variáveis de ambiente.
Para executar a aplicação execute os seguintes comandos:
git clone https://github.com/aandrade1234/challenge-bravo.git
cd challenge-bravo
chmod +x server.sh
./server.sh
Para executar os testes de aplicação execute os seguintes comandos após os comandos anteriores:
docker exec bravo go test -v challenge-bravo/server
Para compilar e acessar a aplicação frontend, basta executar container do bravo-server, pois ao preparar sua imagem
aplicação também é compilada e empacotada com o servidor. O acesso à aplicação se dá pela url raiz, enquanto os arquivos
estáticos estão armazenados na pasta /app/static
.
Caso o serviço bravo
entre em um ciclo de reinicialização devido à falta de conectividade com o banco de dados em
função de falha na autenticação. O problema possivelmente está sendo causado devido a uma imagem antiga do servidor de
banco de dados. Para solucionar o problema você deve remover suas imagens e volumes relacionados ao Postgres e reiniciar
os serviços, porém não se esqueça de realizar o backup, pois os eventuais dados contidos nesses volumes serão perdidos.
docker system prune -a --volumes -f
O endpoint padrão do bravo-server é http://127.0.0.1:8080/api/v1 e possui dois serviços, um para o gerenciamento
de moedas /currency
e outro para a realização de conversões /convert
. Todas as requisições utilizam a convenção
REST e os dados seguem o formato JSON.
A representação de uma moeda nos serviços possui os seguintes atributos e convenções:
code
: Código da moeda, sempre em caracteres maiúsculos e com 3 dígitos para moedas reais e de 1 até 10 dígitos para cripto moedas e moedas customizadas. Para moedas reais poderá conter somente letras e para os demais tipos de moedas poderá conter letras, números e *. Não é possível a alteração do código de uma moeda.name
: Nome da moeda, pode conter até 100 caracteres de qualquer tipo.type
: Tipo da moeda, ondeC
é para moedas reais,Y
para cripto moedas eU
para moedas customizadas. Este atributo é somente de consulta, e não é necessário para a criação e alteração de uma moeda.rate
: Cotação da moeda em relação ao dólar americano. Este atributo está disponível somente para as moedas customizadas.
Quando o servidor está em execução a documentação também é disponibilizada no format Swagger
através do endpoint /swagger
.
-
GET
/currency
- Obtém uma lista de todas as moedas disponíveis para conversão. -
POST
/currency
- Cria uma moeda customizada, o corpo da requisição deve conter a representação da moeda. Caso o atributotype
esteja presente ele será ignorado.- Exemplo:
curl --location --request POST 'localhost:8080/api/v1/currency' --header 'Content-Type: application/json' --data-raw '{ "code": "HURB", "name": "Hurb Coin", "rate": 2.5 }'
- Exemplo:
-
GET
/currency/{code}
- Obtém uma moeda qualquer. -
DEL
/currency/{code}
- Apaga uma moeda customizada. -
PUT
/currency/{code}
- Atualiza uma moeda customizada, o corpo da requisição deve conter a representação da moeda. Caso o atributotype
esteja presente ele será ignorado. Também não é possível atualizar o atributocode
.
- GET
/convert
- Realiza a conversão de duas moedas, os parâmetros para esta requisição devem ser passados como querystring e são os seguintesamount
montante a ser convertidofrom
código da moeda de origemto
código da moeda de destinoverbose
parâmetro opcional, que se passado comotrue
retornará informações adicionais para depuração.- Exemplo:
curl --location --request GET 'localhost:8080/api/v1/convert?amount=10.5&from=HURB&to=ARS&verbose=true'
- Exemplo:
Foi adicionada ferramenta Φορτίο para a execução do teste de estresse do bravo-server. Para a execução dos testes execute o seguinte comando:
docker exec -it fortio fortio load -qps 5000 -c 8 -t 20s "http://host.docker.internal:8080/api/v1/convert?amount=10.5&from=USD&to=BRL"
Os parâmetros dos testes acima são os seguintes:
- Transações por segundo desejadas = 5.000
- Processos = 8
- Duração do teste = 20s
Os resultados obtidos em um notebook com processador Intel Core I7 10510U e 16GB de memória RAM foram os seguintes:
- Total de requisições: 20.570
- Tempo médio por requisição: 1,933 ms
- Requisições por segundo: 4.113,5
A ferramenta ainda oferece uma interface gráfica a qual pode ser acessada pelo navegador através da URL http://localhost:8088/fortio/ onde é possível a geração relatórios gráficos como o observado abaixo.
Quaisquer dúvidas que você venha a ter ou problema que encontrar por favor consulte ou poste nas issues do projeto.