API para catálogo de produtos.
A API Catálogo-Produtos tem como objetivo persistir dados para gerenciamento de um catálogo de produtos. Foi realizado para um teste de um estágio.
- Sistema permite o cadastro de usuário, com validação de informações;
- Sistema recupera e armazena, caso a tabela de produtos esteja vazia, os produtos da API externa: https://dummyjson.com/products/category/smartphones e https://dummyjson.com/products/category/laptops
- Sistema permite apenas as requisições de cadastro de usuário e login sem autenticação por meio de JWT;
- Com usuário logado, o sistema permite a criação, listagem, detalhamento, edição e deleção de produtos;
- Sistema armazena em cache (Redis) o resultado das buscas de listagem e detalhamento de produtos;
-
Instale as dependências necessárias com o Maven para rodar a API (relacionadas no pom.xml):
mvn dependency:copy-dependencies
-
A API utiliza o PostgreSQL como banco de dados e o Redis como cache, então se faz necessário que você verifique se o arquivo
docker-compose.yaml
não possui confronto de portas com as existentes no sistema local. Para criar um container com os servidores basta rodar o comando abaixo:docker compose up -d
-
Se alguma configuração no arquivo
docker-compose.yaml
foi alterada, verifique as propriedades de conexão com o banco de dados e o cache no arquivoapplication.properties
:spring.datasource.url=jdbc:jdbc:postgresql://localhost:{porta}/{nome_db} spring.datasource.username={username} spring.datasource.password={password} redis.host=localhost redis.port={porta}
-
Rode a aplicação que o sistema já irá criar as tabelas e popular a tabela produtos automaticamente, deixando-as prontas para uso. Por padrão, a aplicação rodará na porta 8080.
-
Você precisará de uma ferramenta de teste de requisições como o Insomnia ou utilizar o Swagger-Ui, devendo seguir as orientações da documentação abaixo para utilizar a API.
-
Você também pode usar o front-end desenvolvido para teste desta api: Front-end
-
Você pode rodar os testes automatizados criados com JUnit, caso queira (mais testes em desenvolvimento).
Login - Autenticação de usuário
POST users/login
Logar com um usuário por meio de username
e password
. Retorna um token JWT para ser utilizado nas requisições.
Request
Nome | Obrigatório | Tipo | Descrição |
---|---|---|---|
username | sim | string |
E-mail do usuário |
password | sim | string |
Senha do usuário |
NOTA: Não é necessário enviar Token JWT via Authorization Header.
Exemplo de requisição:
{
"username": "fulaninho",
"password": "password"
}
Response
Sucesso
{
"type": "Bearer",
"token": "abcdefghijklmno.abcdefghijklmnopqrstuvwxyz.abcdefghijklmnop"
}
status: 201
Erro comum
{
"statusCode": "UNAUTHORIZED",
"message": "Bad credentials",
"dateTime": "02-12-2023 19:00:24"
}
User - Criação de um novo usuário, edição de um usuário, detalhamento de um usuário e deleção do usuário
POST user
Criar um usuário para poder utilizar a API.
Request
Nome | Obrigatório | Tipo | Descrição |
---|---|---|---|
name | sim | string |
Nome do usuário |
username | sim | string |
Username do usuário |
sim | string |
Email do usuário | |
password | sim | string |
Senha do usuário |
NOTA: Não é necessário enviar Token JWT via Authorization Header.
Exemplo de requisição:
{
"name": "Fulano de Ciclano",
"username": "fulaninho",
"email": "fulano@email.com",
"password": "password"
}
Response
Sucesso
{
"id": "753ae2c4-edd0-4d4c-8f7f-1cffa5eea4f6",
"name": "Fulano de Ciclano",
"username": "fulaninho",
"email": "fulano@email.com"
}
status: 201
Erro comum
{
"statusCode": "BAD_REQUEST",
"message": "Email already in use",
"dateTime": "29-11-2023 21:31:14"
}
PUT user
Editar um usuário. Apenas nome e email podem ser alterados, mas nenhum dos dois é obrigatório.
Request
Nome | Obrigatório | Tipo | Descrição |
---|---|---|---|
name | não | string |
Nome do usuário |
não | string |
Email do usuário |
NOTA: É necessário enviar Token JWT via Authorization Header.
Exemplo de requisição:
{
"name": "Fulano Editado",
"email": "fulano.editado@email.com",
"password": "password"
}
Response
Sucesso
{
"id": "753ae2c4-edd0-4d4c-8f7f-1cffa5eea4f6",
"name": "Fulano de Ciclano Editado",
"username": "fulaninho",
"email": "fulano.editado@email.com"
}
status: 200
Erros comuns
{
"statusCode": "BAD REQUEST",
"message": "User not found",
"dateTime": "02-12-2023 19:21:55"
}
{
"statusCode": "UNAUTHORIZED",
"message": "Invalid token",
"dateTime": "02-12-2023 19:21:55"
}
{
"statusCode": "BAD_REQUEST",
"message": "Email already in use",
"dateTime": "29-11-2023 21:31:14"
}
GET user
Detalhar um usuário. Não é necessário enviar qualquer dado na requisição.
NOTA: É necessário enviar Token JWT via Authorization Header.
Response
Sucesso
{
"id": "753ae2c4-edd0-4d4c-8f7f-1cffa5eea4f6",
"name": "Fulano de Ciclano",
"username": "fulaninho",
"email": "fulano@email.com"
}
status: 200
Erros comuns
{
"statusCode": "BAD REQUEST",
"message": "User not found",
"dateTime": "02-12-2023 19:21:55"
}
{
"statusCode": "UNAUTHORIZED",
"message": "Invalid token",
"dateTime": "02-12-2023 19:21:55"
}
DELETE user
Deletar o usuario. Não é necessário enviar qualquer dado na requisição.
NOTA: É necessário enviar Token JWT via Authorization Header.
Response
Sucesso
no body returned for response
status: 204
Erro comum
{
"statusCode": "BAD REQUEST",
"message": "User not found",
"dateTime": "02-12-2023 19:21:55"
}
{
"statusCode": "UNAUTHORIZED",
"message": "Invalid token",
"dateTime": "02-12-2023 19:21:55"
}
Products - Criação de um novo produto, edição de um produto, listagem de produtos, deleção de um produto e detalhamento de um produto.
POST products
Criar um filme.
Request
Nome | Obrigatório | Tipo | Descrição |
---|---|---|---|
title | sim | string |
Nome do produto |
description | sim | string |
Descrição do produto |
price | sim | bigdecimal |
Preço do produto |
stock | sim | integer |
Estoque do produto |
brand | sim | string |
Marca do produto |
category | sim | string |
Categoria do produto |
image | não | string |
URL da imagem do produto |
NOTA: É necessário enviar Token JWT via Authorization Header.
Exemplo de requisição:
{
"title": "Iphone 12",
"description": "Qualquer coisa",
"price": 2499.99,
"stock": 25,
"brand": "Apple",
"category": "smartphones"
}
Response
Sucesso
{
"id": "590ced29-016a-4c7e-bf35-818e2bed8539",
"title": "Iphone 12",
"description": "Qualquer coisa",
"price": 2499.99,
"stock": 25,
"brand": "Apple",
"category": "SMARTPHONES",
"image": null
}
status: 201
Erros comuns
{
"statusCode": "BAD_REQUEST",
"message": "Product already exist",
"dateTime": "02-12-2023 19:39:38"
}
{
"statusCode": "BAD_REQUEST",
"message": "Invalid category. Categories available: 'smartphones', 'laptops'",
"dateTime": "02-12-2023 19:59:50"
}
{
"statusCode": "UNAUTHORIZED",
"message": "Invalid token",
"dateTime": "02-12-2023 19:37:36"
}
GET products
Listar produtos. É possível passar um parâmetro query
para buscar por categoria.
Request
Nome | Obrigatório | Tipo | Descrição |
---|---|---|---|
category | não | string |
Enviado via query na url |
NOTA: É necessário enviar Token JWT via Authorization Header.
Exemplo de requisição:
http://localhost:8080/products?category=laptop
Response
Sucesso
[
{
"id": "201c2e19-a6e1-4036-8678-692b50d5b246",
"title": "MacBook Pro",
"description": "MacBook Pro 2021 with mini-LED display may launch between September, November",
"price": 6996.00,
"stock": 83,
"brand": "Apple",
"category": "LAPTOPS",
"image": "https://i.dummyjson.com/data/products/6/1.png"
},
{
"id": "e9812960-678b-4fad-9756-9b936aaed303",
"title": "Samsung Galaxy Book",
"description": "Samsung Galaxy Book S (2020) Laptop With Intel Lakefield Chip, 8GB of RAM Launched",
"price": 5996.00,
"stock": 50,
"brand": "Samsung",
"category": "LAPTOPS",
"image": "https://i.dummyjson.com/data/products/7/1.jpg"
},
{
"id": "b2d77720-4267-4d13-9f2a-2cd9c2d6902f",
"title": "Microsoft Surface Laptop 4",
"description": "Style and speed. Stand out on HD video calls backed by Studio Mics. Capture ideas on the vibrant touchscreen.",
"price": 5996.00,
"stock": 68,
"brand": "Microsoft Surface",
"category": "LAPTOPS",
"image": "https://i.dummyjson.com/data/products/8/1.jpg"
}
]
status: 200
Sucesso sem retorno
[]
status: 200
GET products/id
Detalhar um produto. O id
deve ser enviado na url.
Request
Nome | Obrigatório | Tipo | Descrição |
---|---|---|---|
id | sim | string |
Enviar via parâmetro de rota |
NOTA: É necessário enviar Token JWT via Authorization Header.
Response
Sucesso
{
"id": "4b5a9bcd-a10e-4965-8939-22d24f408138",
"title": "Infinix INBOOK",
"description": "Infinix Inbook X1 Ci3 10th 8GB 256GB 14 Win10 Grey – 1 Year Warranty",
"price": 4396.00,
"stock": 96,
"brand": "Infinix",
"category": "LAPTOPS",
"image": "https://i.dummyjson.com/data/products/9/1.jpg"
}
status: 200
Erros comuns
{
"statusCode": "NOT_FOUND",
"message": "Product not found",
"dateTime": "02-12-2023 19:48:00"
}
{
"statusCode": "UNAUTHORIZED",
"message": "Invalid token",
"dateTime": "02-12-2023 19:48:12"
}
PUT products/id
Alterar os dados do produto. O id
deve ser enviado na url. Nenhuma propriedade do body é obrigatória, mas as validações persistem.
Request
Nome | Obrigatório | Tipo | Descrição |
---|---|---|---|
id | sim | string |
Enviar via parâmetro de rota |
title | não | string |
Nome do produto |
description | não | string |
Descrição do produto |
price | não | bigdecimal |
Preço do produto |
stock | não | integer |
Estoque do produto |
brand | não | string |
Marca do produto |
category | não | string |
Categoria do produto |
image | não | string |
URL da imagem do produto |
NOTA: É necessário enviar Token JWT via Authorization Header.
Response
Sucesso
{
"id": "4b5a9bcd-a10e-4965-8939-22d24f408138",
"title": "Infinix INBOOK EDITADO",
"description": "Infinix Inbook X1 Ci3 10th 16GB 256GB 14 Win10 Grey",
"price": 5000.00,
"stock": 50,
"brand": "Infinix",
"category": "LAPTOPS",
"image": "https://i.dummyjson.com/data/products/9/1.jpg"
}
status: 200
Erros comuns
{
"statusCode": "NOT_FOUND",
"message": "Product not found",
"dateTime": "02-12-2023 19:48:00"
}
{
"statusCode": "BAD_REQUEST",
"message": "Other product already have this title and brand",
"dateTime": "02-12-2023 19:51:34"
}
{
"statusCode": "UNAUTHORIZED",
"message": "Invalid token",
"dateTime": "02-12-2023 19:48:12"
}
DELETE products/id
Deletar um produto. O id
deve ser enviado na url.
Request
Nome | Obrigatório | Tipo | Descrição |
---|---|---|---|
id | sim | string |
Enviar via parâmetro de rota |
NOTA: É necessário enviar Token JWT via Authorization Header.
Response
Sucesso
no body returned for response
status: 204
Erros comums
{
"statusCode": "NOT_FOUND",
"message": "Product not found",
"dateTime": "02-12-2023 19:48:00"
}
{
"statusCode": "UNAUTHORIZED",
"message": "Invalid token",
"dateTime": "02-12-2023 19:48:12"
}
Criado por Daniel Justo
Obrigado pela visita!