Projeto com atualizações para a quarta entrega da pós graduação em Software Architecture da FIAP.
Este serviço ficou responsavel pela criação de Produtos e do Pedido em si.
Link do miro: https://miro.com/app/board/uXjVKTJ4mvk=/?share_link_id=556895060297
Link do desenho da arquitetura: https://drive.google.com/file/d/186D8N2BxR907FRHDmWTzllt5tJ4GfxJi/view?usp=drive_link
Link do repositorio da aplicação users: https://github.com/gabrielronei/tastytap-users
Link do repositorio do payments: https://github.com/thaisandre/tastytap-payments
Link do repositorio do terraform: https://github.com/thaisandre/terraform-tastytap-infra
Link do repositorio do database: https://github.com/thaisandre/terraform-tastytap-database
Link do repositorio do rds: https://github.com/thaisandre/terraform-tastytap-rds
Link do repositorio do terraform: https://github.com/thaisandre/terraform-tastytap-infra
Link do repositorio do lambda: https://github.com/gabrielronei/tastytap-auth
Para executar o projeto em sua máquina siga os seguintes passos.
- Docker com compose Veja a documentação para instalar o docker no seu sistema se ainda não tiver instalado.
A instalação é bem simples, siga as seguintes etapas:
- Clone o repositório
git clone https://github.com/gabrielronei/tastytap.git
- Entre na pasta do projeto
cd tastytap
- Agora execute o projeto usando o docker compose
docker compose up
- Para acessar a documentação no swagger, acesse em seu navegador.
http://localhost:8080/
Da para rodar localmente nossa arquitetura usando o minikube, siga os seguintes passos:
- Inicie o minikube
minikube start
- Entre na pasta do kubernetes dentro do nosso projeto
cd kubernetes/
- Agora execute o script
bash configure.sh
- Só acessar a url com ip do cluster que foi mostrado na execução do script
http://IP_DO_CLUSTER:30000/
Temos o arquivo tastytap-fiap.postman_collection.json que pode ser importado no Postman ou em seu API Client de preferência(insomnia, testfully e etc), já estão estruturadas na ordem correta, ou caso prefira, pode seguir os exemplos abaixo:
1. Criar usuário (opcionalmente):
// GET /user
{
"name": "Saul Hudson",
"email": "saul.hudson@gmail.com",
"cpf": "285.977.970-10"
}
2. Buscar usuário por CPF (opcionalmente):
// GET /user/285.977.970-10
2.5 Pegar token do usuário (opcionalmente):
// POST no serviço do `tastytap-auth`
{
"body": '{\n "cpf": "285.977.970-10"\n}'
}
3. Criar produto de tipo lanche:
// POST /product
{
"name": "Universitario",
"description": "Pão de brioche selado na manteiga, hambúrguer artesanal 160g, queijo cheddar, alface, tomate e molho john's",
"imageURL": "https://assets.unileversolutions.com/recipes-v2/106684.jpg",
"category": "SANDWICH",
"price": 33.90
}
4. Criar produto de tipo lanche para atualizar e deletar:
// POST /product
{
"name": "Produto para deletar e atualizar",
"description": "XPTOPTOPTO",
"imageURL": "https://assets.unileversolutions.com/recipes-v2/106684.jpg",
"category": "SIDE_DISH",
"price": 10
}
5. Criar produto de tipo bebida:
// POST /product
{
"name": "Coca-Cola Original 350ml",
"description": "Lata 350ml",
"imageURL": "https://hiperideal.vtexassets.com/arquivos/ids/197362/55723-4.jpg",
"category": "DRINK",
"price": 7.90
}
6. Criar produto de tipo sobremesa:
// POST /product
{
"name": "Pudim cremoso individual",
"description": "Pudim cremoso e sem furinho",
"imageURL": "https://revistamenu.com.br/wp-content/uploads/sites/24/2020/05/diadopudim-1.jpg",
"category": "DESSERT",
"price": 13.90
}
7. Atualizar produto:
// PUT /product
{
"id": 2,
"description": "descricão novissima",
"imageURL": "https://assets.unileversolutions.com/recipes-v2/106684.jpg",
"price": 1
}
8. Buscar por categoria:
// GET /product/SIDE_DISH
9. Deletar por id:
// DELETE /product/2
10. Criar um pedido(com usuario):
// POST /order
{
"cpf": "285.977.970-10",
"items": [
{
"productId": 1,
"quantity": 2
},
{
"productId": 3,
"quantity": 2
}
]
}
11. Criar um pedido(sem usuario):
// POST /order
{
"items": [
{
"productId": 1,
"quantity": 2
}
]
}
12. Busca todos os pedidos:
// GET /order
13. Chama webhook que seria chamado pelo gateway:
// POST /payment/provider/webhook
{
"transactionId": "{{TRANSACTION_ID}}",
"status": "APPROVED"
}
14. Checa status pelo numero do pedido:
// GET /order/{{ORDER_NUMBER}}/status
15. Atualiza status do pedido:
// GET /order/{{ORDER_NUMBER}}/status
Nós fizemos os componentes da nossa aplicação bem desacoplados, protegendo nosso nucleo do sistema ao máximo, seguindo a ideia da clean architecture.
Basicamente a nossa divisão dos pacotes funciona da seguinte maneira:
- Domain: este é o core da nossa aplicação, lá se encontram nossos objetos de negócio que encapsulam as regras centrais de nosso sistema.
- Application: aqui é onde se encontram nossos casos de uso, que definem as logicas especificas de nosso negócio, essa camada orquestra o fluxo de dados entre as entidades e outras camadas externas.
- Utils: é onde se encontram alguns recursos uteis para aplicação no geral, ele consegue centralizar algumas lógicas/validações/formatações, para que mantenham-se as assinaturas independente da implementação.
- Infraestructure: aqui estão nossas pontes com a camada de aplicação em conjunto com o framework, é onde eles se juntam.
- Presentation: Onde ficam nossos endpoints, a comunicação com nossa camada mais externa, que no caso desse projeto, é somente web.
Temos nossa infraestrutura com um LoadBalancer na aplicação principal(tastytap), para suportar grande volume de requisições simultaneas, onde o minimo são 2 máquinas e podendo escalar até 6.
Nossa infraestrutura ficou definida assim dentro da aws e seus respectivos serviços ficaram assim:
A aplicação foi quebrada em serviços e foi adicionado o ingress-nginx no kubernetes.
O core(tastytap) se comunica com o serviço de users(tastytap-users) para pegar a informação do usuario que estiver logado e colocar no pedido e o core(tastytap) se comunica com payments para executar o pagamento de fato.