API para listagem de produtos e cadastro de pedidos.
A API Shop-Orders tem como objetivo persistir dados para gerenciamento de pedidos com base em um estoque de produtos. Foi realizado academicamente durante o Bootcamp Java Academy, iniciativa da Ada em parceria com a Avanade.
- 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/search?q=phone
- Sistema permite apenas as requisições de listagem de produtos, detalhes de produto, cadastro de usuário e login sem autenticação por meio de JWT;
- Com usuário logado, o sistema permite a criação de pedido, validando o estoque de produtos antes de armazenar o pedido;
- Sistema atualiza o estoque automaticamente e encaminha e-mail de confirmação do pedido ao usuário;
-
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, então se faz necessário que você tenha-o instalado em sua máquina.
-
Com ele instalado, crie um database e preencha o arquivo "application.proporties" com a url (colocando o nome do database criado no local indicado), username e password.
spring.datasource.url=jdbc:mysql://localhost/{nomedatabase} spring.datasource.username={username} spring.datasource.password={password}
-
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ê pode rodar os testes automatizados criados com JUnit, caso queira (mais testes em desenvolvimento).
Auth
POST /auth/
- Autenticação de usuário (login)
User
GET /user/
- Listagem de usuários (Rota apenas para Admin)
GET /user/:id
- Detalhamento de um usuário
POST /user/
- Criação de um novo usuário
PATCH /user/:id
- Atualização de dados de um usuário
PATCH /user/admin/:id
- Conceder credencial de Admin para usuário (Rota apenas para Admin)
DELETE /user/:id
- Deleção de um usuário (Rota apenas para Admin)
Address
GET /address/:id
- Detalhamento de um endereço
POST /address/
- Criação de um novo endereço
PUT /address/:id
- Atualização de dados de um endereço
DELETE /address/:id
- Deleção de um endereço
Product
GET /product/
- Listagem de produtos com parâmetros
GET /product/:id
- Detalhamento um de produto
POST /product/
- Criação de um novo produto (Rota apenas para Admin)
PUT /product/:id
- Atualização de dados de um produto (Rota apenas para Admin)
DELETE /product/:id
- Deleção de um produto (Rota apenas para Admin)
Order
GET /order/
- Listagem de pedidos (Rota apenas para Admin)
GET /order/:id
- Detalhamento de um pedido
POST /order/
- Criação de um novo pedido
DELETE /order/:id
- Deleção de um pedido (Rota apenas para Admin)
Request
Nome | Obrigatório | Tipo | Descrição |
---|---|---|---|
username | sim | string |
Username do usuário |
password | sim | string |
Senha do usuário |
NOTA: Não é necessário enviar Token JWT via Authorization Header.
Response
Sucesso
{
"type": "Bearer",
"token": "abcdefghijklmnopqrstuvwxyz"
}
status: 200
Erro comum
{
"message": "Authentication failed."
}
status: 401
Request
Listar todos os usuários
Nome | Obrigatório | Tipo | Descrição |
---|---|---|---|
- | - | - | Não é necessário enviar nenhum parâmetro |
NOTA: É necessário enviar Token JWT via Authorization Header (rota exclusiva de administrador).
Response
Sucesso
[
{
"id": 1,
"name": "Fulano",
"username": "fulano",
"cpf": "12345678910",
"email": "fulano@email.com",
"phone": "11999998888",
"registerDate": "2023-08-25T21:00:00.000000",
"addresses": null,
"orders": null
},
{
"id": 2,
"name": "Beltrano",
"username": "beltrano",
"cpf": "98765432101",
"email": "beltrano@email.com",
"phone": "1133330000",
"registerDate": "2023-08-25T21:30:00.000000",
"addresses": null,
"orders": null
}
]
status: 200
Sucesso sem retorno de dados
[]
status: 200
Request
Detalhar um usuário
Nome | Obrigatório | Tipo | Descrição |
---|---|---|---|
id | sim | number |
Enviar via parâmetro de rota |
NOTA: É necessário enviar Token JWT via Authorization Header.
Response
Sucesso
{
"id": 1,
"name": "Fulano",
"username": "fulano",
"cpf": "12345678910",
"email": "fulano@email.com",
"phone": "11999998888",
"registerDate": "2023-08-25T21:00:00.000000",
"addresses": [
{
"id": 1,
"street": "Rua 1",
"number": "111, apto 01",
"postalCode": "12345678",
"city": "Cidade",
"state": "Estado",
"country": "País",
"userId": 1
}
],
"orders": [
{
"id": 1,
"userId": 1,
"orderDate": "2023-08-25T22:45:06.786814",
"totalPrice": 99100,
"orderItems": [
{
"id": 1,
"orderId": 1,
"productId": 2,
"qty": 1
},
{
"id": 2,
"orderId": 1,
"productId": 3,
"qty": 2
}
]
}
]
}
status: 200
Erro comum
{
"message": "User not found."
}
status: 404
Criar um usuário
Request
Nome | Obrigatório | Tipo | Descrição |
---|---|---|---|
name | sim | string |
Nome para perfil |
username | sim | string |
Username do usuário |
password | sim | string |
Senha do usuário |
cpf | sim | string |
CPF do usuário |
sim | string |
E-mail do usuário | |
phone | sim | string |
Telefone do usuário |
address | não | object |
Endereço do usuário |
Caso o endereço seja cadastrado junto com o registro do usuário, deve seguir os seguintes parâmetros:
Nome | Obrigatório | Tipo | Descrição |
---|---|---|---|
street | não | string |
Rua/Avenida |
number | sim | string |
Número com complemento |
postalCode | sim | string |
CEP |
city | não | string |
Cidade |
state | não | string |
Estado |
country | não | string |
País |
Exemplo de requisição:
{
"name": "Fulano",
"username": "fulano",
"password": "password",
"cpf": "12345678910",
"email": "fulano@email.com",
"phone": "11999998888",
"address": {
"street": "Rua 1",
"number": "111 apto 11",
"postalCode": "12345678",
"city": "Cidade 1",
"state": "Estado 1",
"country": "País 1"
}
}
NOTA: Não é necessário enviar Token JWT via Authorization Header.
Response
Sucesso
{
"id": 1,
"name": "Fulano",
"username": "fulano",
"cpf": "12345678910",
"email": "fulano@email.com",
"phone": "11999998888",
"registerDate": "2023-08-25T21:00:00.000000",
"addresses": [
{
"id": 1,
"street": "Rua 1",
"number": "111, apto 01",
"postalCode": "12345678",
"city": "Cidade",
"state": "Estado",
"country": "País",
"userId": 1
}
],
"orders": []
}
status: 201
Erros comuns
{
"message": "User already exists."
}
status: 400
{
"errors": [
"invalid Brazilian individual taxpayer registry number (CPF)"
]
}
status: 400
{
"field": "password",
"message": "The password must have at least 8 characters"
}
status: 400
Request
Editar um usuário. Apenas nome, email e telefone poder ser editados.
Nome | Obrigatório | Tipo | Descrição |
---|---|---|---|
id | sim | number |
ID do produto que será atualizado (recebido como parâmetro de rota) |
name | não | string |
Nome do usuário |
não | string |
Email do usuário | |
phone | não | string |
Telefone do usuário |
NOTA: É necessário enviar Token JWT de Admin via Authorization Header.
Response
Sucesso
{
"id": 1,
"name": "Fulano Editado",
"username": "fulano",
"cpf": "12345678910",
"email": "fulano.editado@email.com",
"phone": "11999998888",
"registerDate": "2023-08-25T21:00:00.000000",
"addresses": [
{
"id": 1,
"street": "Rua 1",
"number": "111, apto 01",
"postalCode": "12345678",
"city": "Cidade",
"state": "Estado",
"country": "País",
"userId": 1
}
],
"orders": [
{
"id": 1,
"userId": 1,
"orderDate": "2023-08-25T22:45:06.786814",
"totalPrice": 99100,
"orderItems": [
{
"id": 1,
"orderId": 1,
"productId": 2,
"qty": 1
},
{
"id": 2,
"orderId": 1,
"productId": 3,
"qty": 2
}
]
}
]
}
status: 200
Erros comuns
{
"message": "User not found."
}
status: 404
Request
Conceder credencial de Admin para um usuário
Nome | Obrigatório | Tipo | Descrição |
---|---|---|---|
id | sim | number |
Enviar via parâmetro de rota |
NOTA: É necessário enviar Token JWT via Authorization Header.
Response
Sucesso
no body returned for response
status: 200
Erro comum
{
"message": "User not found."
}
status: 404
Deletar um usuário
Request
Nome | Obrigatório | Tipo | Descrição |
---|---|---|---|
id | sim | number |
ID do produto que será deletado (recebido como parâmetro de rota) |
NOTA: É necessário enviar Token JWT de Admin via Authorization Header (rota exclusiva de administrador).
Response
Sucesso
no body returned for response
status: 204
Erro comum
{
"message": "User not found."
}
status: 404
Request
Detalhar endereço
Nome | Obrigatório | Tipo | Descrição |
---|---|---|---|
id | sim | number |
Enviar via parâmetro de rota |
NOTA: É necessário enviar Token JWT via Authorization Header.
Response
Sucesso
{
"id": 1,
"street": "Rua 1",
"number": "111, apto 01",
"postalCode": "12345678",
"city": "Cidade",
"state": "Estado",
"country": "País",
"userId": 1
}
status: 200
Erro comum
{
"message": "Address not found."
}
status: 404
Cadastrar um endereço
Request
Nome | Obrigatório | Tipo | Descrição |
---|---|---|---|
userId | sim | number |
Id do usuário que o endereço pertence |
street | não | string |
Rua/Avenida |
number | sim | string |
Número com complemento |
postalCode | sim | string |
CEP |
city | não | string |
Cidade |
state | não | string |
Estado |
country | não | string |
País |
NOTA: É necessário enviar Token JWT de Admin via Authorization Header.
Response
Sucesso
{
"id": 2,
"street": "Rua 2",
"number": "222, apto 02",
"postalCode": "87654321",
"city": "Cidade",
"state": "Estado",
"country": "País",
"userId": 1
}
status: 201
Erros comuns
{
"message": "User not found."
}
status: 404
[
{
"field": "number",
"message": "must not be blank"
}
]
status: 400
Editar um endereço
Request
Nome | Obrigatório | Tipo | Descrição |
---|---|---|---|
userId | sim | number |
Id do usuário (recebido por parâmetro) |
street | não | string |
Rua/Avenida |
number | sim | string |
Número com complemento |
postalCode | sim | string |
CEP |
city | não | string |
Cidade |
state | não | string |
Estado |
country | não | string |
País |
NOTA: É necessário enviar Token JWT de Admin via Authorization Header.
Response
Sucesso
{
"id": 2,
"street": "Rua 22",
"number": "444, apto 04",
"postalCode": "87654321",
"city": "Cidade",
"state": "Estado",
"country": "País",
"userId": 1
}
status: 200
Erros comuns
{
"message": "Address not found."
}
status: 404
{
"message": "User not found."
}
status: 404
Request
Nome | Obrigatório | Tipo | Descrição |
---|---|---|---|
id | sim | number |
ID do produto que será deletado (recebido por parâmetro) |
NOTA: É necessário enviar Token JWT de Admin via Authorization Header.
Response
Sucesso
no body returned for response
status: 204
Erro comum
{
"message": "Address not found."
}
status: 404
Listar produtos (pode receber filtros)
Request
Nome | Obrigatório | Tipo | Descrição |
---|---|---|---|
title | não | string |
Nome do produto a ser pesquisado |
brand | não | string |
Marca do produto a ser pesquisado |
category | não | string |
Categoria do produto a ser pesquisado |
Response
Sucesso
[
{
"id": 1,
"title": "Produto 1",
"description": "Qualquer coisa",
"price": 2000,
"stock": 50,
"brand": "Marca 1",
"category": "Eletronico"
},
{
"id": 2,
"title": "Produto 2",
"description": "Qualquer coisa 2",
"price": 4000,
"stock": 70,
"brand": "Marca 2",
"category": "Vestuario"
}
]
status: 200
Sucesso sem retorno de dados
[]
status: 200
Detalhar um produto
Request
Nome | Obrigatório | Tipo | Descrição |
---|---|---|---|
id | sim | number |
Enviar via parâmetro de rota |
NOTA: É necessário enviar Token JWT via Authorization Header.
Response
Sucesso
{
"id": 3,
"title": "Produto 3",
"description": "Qualquer coisa 3",
"price": 1000,
"stock": 10,
"brand": "Marca 3",
"category": "Eletronico"
}
status: 200
Erro comum
{
"message": "Product not found."
}
status: 404
Cadastrar um produto
Request
Nome | Obrigatório | Tipo | Descrição |
---|---|---|---|
title | sim | string |
Nome do produto |
description | sim | string |
Descrição do produto |
price | sim | number |
Preço do produto |
stock | sim | number |
Estoque do produto |
brand | sim | string |
Marca do produto |
category | sim | string |
Categoria do produto |
NOTA: É necessário enviar Token JWT de Admin via Authorization Header (rota exclusiva de administrador).
Response
Sucesso
{
"id": 4,
"title": "Produto 4",
"description": "Qualquer coisa",
"price": 52000,
"stock": 5,
"brand": "Marca 4",
"category": "Mobiliario"
}
status: 201
Erros comuns
[
{
"field": "price",
"message": "must be greater than or equal to 1"
}
]
status: 400
{
"message": "Product already exist"
}
status: 400
Editar um produto
Request
Nome | Obrigatório | Tipo | Descrição |
---|---|---|---|
title | não | string |
Nome do produto |
description | não | string |
Descrição do produto |
price | não | number |
Preço do produto |
stock | não | number |
Estoque do produto |
brand | não | string |
Marca do produto |
category | não | string |
Categoria do produto |
NOTA: É necessário enviar Token JWT de Admin via Authorization Header (rota exclusiva de administrador).
Response
Sucesso
{
"id": 2,
"title": "Produto 2",
"description": "Qualquer coisa",
"price": 2000,
"stock": 50,
"brand": "Marca 2",
"category": "Eletronico"
}
status: 200
Erros comuns
{
"message": "Product not found."
}
status: 404
[
{
"field": "price",
"message": "must be greater than or equal to 1"
}
]
Deletar um produto
Request
Nome | Obrigatório | Tipo | Descrição |
---|---|---|---|
id | sim | number |
ID do produto que será deletado (recebido por parâmetro) |
NOTA: É necessário enviar Token JWT de Admin via Authorization Header (rota exclusiva de administrador).
Response
Sucesso
no body returned for response
status: 204
Erro comum
{
"message": "Product not found."
}
status: 404
Listar pedidos
Request
Nome | Obrigatório | Tipo | Descrição |
---|---|---|---|
- | - | - | Não é necessário enviar nenhum parâmetro |
NOTA: É necessário enviar Token JWT de Admin via Authorization Header (rota exclusiva de administrador).
Response
Sucesso
[
{
"id": 1,
"userId": 1,
"orderDate": "2023-08-26T14:45:06.786814",
"totalPrice": 50000,
"orderItems": [
{
"id": 1,
"orderId": 1,
"productId": 2,
"qty": 5
},
{
"id": 2,
"orderId": 1,
"productId": 3,
"qty": 1
}
]
},
{
"id": 2,
"userId": 1,
"orderDate": "2023-08-26T18:41:12.651864",
"totalPrice": 100000,
"orderItems": [
{
"id": 3,
"orderId": 2,
"productId": 5,
"qty": 20
},
{
"id": 4,
"orderId": 2,
"productId": 1,
"qty": 8
}
]
}
]
status: 200
Sucesso sem retorno de dados
[]
status: 200
Detalhar um produto
Request
Nome | Obrigatório | Tipo | Descrição |
---|---|---|---|
id | sim | number |
Enviar via parâmetro de rota |
NOTA: É necessário enviar Token JWT via Authorization Header.
Response
Sucesso
{
"id": 1,
"userId": 1,
"orderDate": "2023-08-26T23:59:38.468445729",
"totalPrice": 94500,
"orderItems": [
{
"id": 1,
"orderId": 1,
"productId": 2,
"qty": 1
},
{
"id": 2,
"orderId": 1,
"productId": 3,
"qty": 1
}
]
}
status: 200
Erro comum
{
"message": "Order not found."
}
status: 404
Criar um pedido
Request
Nome | Obrigatório | Tipo | Descrição |
---|---|---|---|
userId | sim | number |
Id do usuário |
orderItems | sim | object |
Lista de produtos e quantidades |
productId | sim | number |
Id do produto |
qty | sim | number |
Quantidade do produto |
Exemplo de requisição:
{
"userId": 1,
"orderItems": [
{
"productId": 2,
"qty": 1
},
{
"productId": 3,
"qty": 1
}
]
}
NOTA: É necessário enviar Token JWT de Admin via Authorization Header.
Response
Sucesso
{
"id": 1,
"userId": 1,
"orderDate": "2023-08-26T23:59:38.468445729",
"totalPrice": 94500,
"orderItems": [
{
"id": 1,
"orderId": 1,
"productId": 2,
"qty": 1
},
{
"id": 2,
"orderId": 1,
"productId": 3,
"qty": 1
}
]
}
status: 201
Erros comuns
{
"field": null,
"message": "No stock available"
}
status: 400
{
"message": "Product not found."
}
status: 404
{
"message": "USer not found."
}
status: 404
Request
Nome | Obrigatório | Tipo | Descrição |
---|---|---|---|
id | sim | number |
ID do pedido que será deletado (recebido por parâmetro) |
NOTA: É necessário enviar Token JWT de Admin via Authorization Header (rota exclusiva de administrador).
Response
Sucesso
no body returned for response
status: 204
Erro comum
{
"message": "Order not found."
}
status: 404
Criado por Daniel Justo
Obrigado pela visita!