Giter Site home page Giter Site logo

fipe-api's Introduction

fipe-api

Sistema para consulta de modelos de veículos de carros presentes na tabela FIPE. Para os usuários as principais funcionalidades são:

  1. Disparar a carga inicial ou atualização dos dados;
  2. Listar as marcas de todos os veículos;
  3. Listar todos os modelos de veículos de uma marca específica;
  4. Adicionar/editar os campos modelo e observações de um veículo.

Observação

Quando a pessoa responsável pela avaliação for testar a aplicação, o banco de dados estará limpo e será
necessário disparar a carga inicial dos dados para popular o banco. Detalhes mais abaixo.

Execução utilizando a aplicação em produção hospedada no GCP

O deploy da aplicação em produção foi feita usando os serviços do Cloud Build e Cloud Run.

De forma bem resumida, o Cloud Build foi configurado para ser executado sempre que houver uma modificação na branch master do repositório no github. Como esta descrito no arquivo cloudbuild.yaml na raiz do projeto, é criada uma imagem docker para API-1 e outra para API-2 e são armazenadas no serviço Artifact Registry. Após criar as imagens o Cloud Build realiza o deploy de cada API no serviço do Cloud Run passando as configurações correspondentes. Dessa forma, temos a API-1 e API-2 sendo executas em instâncias do google e disponíveis para acesso por qualquer pessoa.

Para realiza a comunicação entre as 2 API's foi utilizado o serviço Cloud Tasks, onde a API-1 cria tasks do tipo http_request com destino para API-2 e essas requests são disparadas de forma assíncrona.

E na API-2 quando recebe essas requests feitas pelo Cloud Tasks, realiza todo o processamento e salva os dados no Firestore, que é um banco de dados NoSQL do google.

Sendo assim, toda aplicação incluindo a hospedagem das 2 API's, sistema de filas e banco de dados estão rodando no GCP.

Pré-requisitos para execução local

Certifique-se de ter instalado os seguintes requisitos antes de executar o projeto:

  • Docker
  • Docker Compose
  • Make

Instalação

  1. Clone o repositório:

    git clone [email protected]:Augusto94/fipe-api.git
  2. Acesse o diretório do projeto:

    cd fipe-api
  3. Execute o comando do Docker Compose para construir e iniciar o projeto:

    docker-compose up

    ou

    make start

Nesse momento as API's estarão disponíveis em http://localhost:8000/ e http://localhost:8001/.

Localmente são utilizadas outras ferramentas para armazenamento dos dados e o sistema de filas para comunicação entre as API's.

Em produção o banco de dados utilizado é o Firestore. Já no ambiente de desenvolvimento o banco escolhido foi o MongoDB. Já o sistema de filas adotado foi o Redis ao invés do Cloud Tasks. Onde a API-1 envia mensagens contendo as informações das marcas para uma fila no redis e um serviço terceiro, chamado de consumer fica monitorando essa fila e a cada nova mensagem realiza a chamada para a API-2 realizar a criação dos veículos.

Em resumo o funcionamento da aplicação é o mesmo mas as ferramentas de banco de dados e fila são diferentes dependendo do ambiente (local ou prod.)

Explicação das API's

Por definição do desafio teste, 2 API's foram criadas para manipular os dados. As API's foram criadas utilizando o framework FastAPI.

  1. API-1: Possui os endpoints para realizar a carga inicial dos dados e ler as marcas e os dados dos veículos;
  2. API-2: Possui os endpoints para criação e atualização dos dados.

De forma simples, a API-1 é utilizada para leitura dos dados e a API-2 para criação e edição.

A fonte dos dados utilizada para popular a nossa base de dados se encontra em: https://deividfortuna.github.io/fipe/. Basicamente, ao chamar o endpoint GET /atualizar-dados a API-1 realiza uma request na api externa para buscar a lista das marcas dos veículos na tabela FIPE. Os veículos podem ser carros, motos ou caminhoes. A API-1 consulta as marcas nessas 3 categorias.

Em posse dos resultados, para cada marca, a API-1 envia as informações de codigo, nome e categoria para uma fila e de forma assíncrona as mensagens que chegam na fila realizam uma request para o endpoint de criação de veículo na API-2.

Observação: Ao fazer uma request para o endpoint GET `/atualizar-dados` a seguinte mensagem é retornada:
{"message": "Marcas enviadas para a fila."}. Nesse momento a API-2 estará processando em background as
requests recebidas e salvando os dados no banco. Para finalizar a ingestão de toda base leva em média
2 minutos e então você consultar todos os veículos da base. Antes disso a consulta poderá retornar dados
incompletos.

Agora na API-2, o endpoint de criação de veículos recebe as informações que foram enviadas para fila pela API-1 e em posse dessas informações das marcas, realiza uma request para a api externa para consultar os modelos de veículos daquela marca espefícificada.

Ao receber o retorno da API externa prepara os dados e salva em um banco de dados NoSQL. Nesse momento já teremos no nosso banco os dados de veículos prontos para serem consultados. Um exemplo de veículo salvo no banco de dados, pela API-2, é:

{
    "observacoes": "",
    "modelo": "Q3 Prestige 2.0 TFSI Tiptr.Quatro ",
    "codigo": "10111",
    "categoria": "carros",
    "marca": "Audi"
}

No endpoint GET /marcas da API-1 é possível obter a lista das marcas dos veículos, de forma ordenada, que existem na nossa base. Um exemplo de response JSON é:

[
  "AM Gen",
  "ASTON MARTIN",
  "Acura",
  "Agrale",
  "Alfa Romeo",
  "Asia Motors",
  "Audi",
  "BMW",
  "BRM",
  "BYD"
]

E no endpoint GET /veiculos/{marca} da API-1 é possível obter a lista de veículos de uma marca específica. Um exemplo de response JSON é:

[
  {
    "codigo": "100",
    "modelo": "A6 2.4 30V Mec",
    "observacoes": "",
    "categoria": "carros",
    "marca": "Audi"
  },
  {
    "observacoes": "",
    "modelo": "Q5 Perf. Black 2.0 TFSIe S.Tr. Qt (Hib.)",
    "codigo": "10045",
    "categoria": "carros",
    "marca": "Audi"
  },
  {
    "observacoes": "",
    "modelo": "Q5 Performance 2.0 TFSIe S.Tr. Qt (Hib.)",
    "codigo": "10046",
    "categoria": "carros",
    "marca": "Audi"
  }
]

Agora, voltando na API-2, é possível realizar a atualização de 2 campos de um veículo: modelo e observacoes. No endpoint PUT /veiculo da API-2 é possível realizar a atualização de um veículo. Um exemplo do body de uma request para esse endpoint é:

{
  "codigo": "100",
  "observacoes": "Esse veículo é maravilhoso!"
}

E um exemplo de response JSON para essa request é:

{
    "codigo": "100",
    "modelo": "A6 2.4 30V Mec",
    "observacoes": "Esse veículo é maravilhoso!",
    "categoria": "carros",
    "marca": "Audi"
}

Organização do projeto

Por se tratar de 2 API's FastAPI que compartilham de vários recursos, foi tomado um grande cuidado para evitar repetições de código e/ou arquivos.

Dockerfile, docker-compose.yml, dependências pelo poetry, cloudbuild.yaml, entre outros recursos, são os mesmos para as 2 API's. Database, logger, constants, etc, foram inseridos em uma pasta chamada common e podem ser facilmente acessados por ambas API's.

Os projetos FastAPI foram organizados utilizando o padrão service-repository onde ficam bem definidas as responsabilidades de lógica de negócio (service) e comunicação e manipulação no banco de dados (repository) possibilitando escalar de forma organizada.

Foi feito uso do pre-commit para padronização e garantir uma qualidade no código. Também foi utilizado type hint e escrita de docstrings no padrão do google nas funções, facilitando o entendimento do código.

Também foram implementados testes unitários e de integração usando o pytest.

Testes

Para executar os testes automatizados, utilize o seguinte comando:

docker-compose run --rm app pytest --cov --cov-report term-missing --cov-fail-under 90 --disable-pytest-warnings

ou simplesmente:

make test

Observações e análise do projeto

Stack das principais tecnologias/serviços utilizados

  • FastAPI
  • Cloud Build
  • Cloud Run
  • Cloud Tasks
  • Firestore/Firebase
  • MongoDB
  • Redis
  • Docker
  • Docker Compose
  • Pytest
  • Poetry
  • pre-commit

Possíveis melhorias

  • Melhorar os teste e adicionar sua execução como um step do cloud build para fazer o deploy somente códigos que passam nos testes.
  • Fazer o deploy da aplicação usando kubernetes possibilitando uma maior gerenciamento, escalabilidade, resiliência e vários outros benefícios do kubernetes.
  • Adicionar algumas verificações nas API's para evitar respostas inesperadas. Melhorar os testes pode ajudar nesse ponto.
  • Utilizar a mesmas tecnologias e ferramentas independente do ambiente.

Contato

email: [email protected]

redes sociais: @augustoarl

fipe-api's People

Contributors

augusto94 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.