https://github.com/mfrozzz/product-go-api
RESTful API in Go for product management, with Gin, PostgreSQL and Clean Architecture. It has CRUD endpoints with pagination, filters, data validation and rate limiting.
https://github.com/mfrozzz/product-go-api
api clean-architecture docker dockerfile gin gin-gonic go golang jwt postgresql sql
Last synced: 7 months ago
JSON representation
RESTful API in Go for product management, with Gin, PostgreSQL and Clean Architecture. It has CRUD endpoints with pagination, filters, data validation and rate limiting.
- Host: GitHub
- URL: https://github.com/mfrozzz/product-go-api
- Owner: Mfrozzz
- Created: 2025-05-30T19:05:06.000Z (8 months ago)
- Default Branch: master
- Last Pushed: 2025-06-26T18:41:21.000Z (7 months ago)
- Last Synced: 2025-06-26T19:39:49.105Z (7 months ago)
- Topics: api, clean-architecture, docker, dockerfile, gin, gin-gonic, go, golang, jwt, postgresql, sql
- Language: Go
- Homepage:
- Size: 54.7 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README-ptbr.md
Awesome Lists containing this project
README
# Product API - Go lang
API RESTful para gerenciamento de produtos e usuários, desenvolvida em Go com Gin, PostgreSQL e arquitetura limpa. Suporta autenticação JWT, controle de permissões por role (admin/user), rate limiting, e está pronta para uso com Docker.
## Sumário 📋
* [Requisitos](#requirements)
* [Configurando Ambiente](#setting-up-the-environment)
* [Middlewares](#middlewares)
* [Endpoints](#endpoints)
* [Scripts](#scripts)
* [Arquitetura do Sistema](#architecture)
* [Estrutura de Pastas](#folder-structure)
* [Links Úteis](#useful-links)
* [Versão EN-US](README.md)
---
##
Requisitos 📄
- Go 1.24.3 ou 1.20+
- Docker
- PostgreSQL
- Insomnia ou Postman
---
##
Configurando Ambiente ⚙️
###
Repositório
1. **Clone o repositório:**
```sh
git clone https://github.com/Mfrozzz/product-go-api.git
cd product-go-api
```
2. **Consigure o arquivo `.env`:**
* Copie o arquivo `.env.example` para `.env` e preencha com as suas configurações:
```sh
cp .env.example .env
```
* Exemplo do arquivo:
```.env
JWT_SECRET="YOUR-SECRET-KEY"
PORT=":8000"
DB_HOST="go_db"
DB_PORT=5432
DB_USER="YOUR-DATABASE-USER"
DB_PASSWORD="YOUR-DATABASE-PASSWORD"
DB_NAME="YOUR-DATABASE-NAME"
```
* **Importante:** O projeto depende das variáveis do `.env` para conectar ao banco e gerar tokens JWT.
3. **Instale as dependências Go:**
```sh
go mod tidy
```
---
###
Docker
* Para subir os containers execute:
```sh
docker compose up -d
```
* Para realizar a build dos containers execute:
```
docker build -t product-go-api .
```
---
###
Banco de Dados
A escolha da ferramenta para gerenciar o banco de dados fica a critério do desenvolvedor, podendo ser utilizado, por exemplo, o DBeaver ou outro software de sua preferência. No entanto, neste caso, o acesso ao banco será demonstrado via linha de comando, acessando diretamente o container Docker onde o banco de dados está em execução.
* Acesso ao Banco de dados:
```sh
docker exec -it go_db bash
psql -d postgres -U postgres
```
* Criar Tabelas no Banco de dados:
```sh
CREATE TABLE product (
id SERIAL PRIMARY KEY,
product_name VARCHAR(50) NOT NULL,
price NUMERIC(10, 2) NOT NULL
);
CREATE TABLE users (
id SERIAL PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
username VARCHAR(255) NOT NULL,
password VARCHAR(255) NOT NULL,
role VARCHAR(20) NOT NULL DEFAULT 'user'
);
```
###
Dica: Como criar um usuário admin ✉️
Para transformar um usuário em admin diretamente pelo banco de dados, execute:
```sh
UPDATE users SET role = 'admin' WHERE id = 1;
```
---
##
Middlewares ↔️
O projeto utiliza três middlewares principais para garantir segurança, controle de acesso e limitação de requisições:
###
1. **Auth Middleware**
Responsável por validar o token JWT enviado no header `Authorization`.
- Só vai permitir que o usuário tenha acesso às rotas caso esteja autenticado (realizado o login).
- Se o token for válido, extrai o campo `role` das claims e armazena no contexto da requisição (`ctx.Set("role", role)`), permitindo que outros middlewares e handlers saibam o papel do usuário autenticado.
- Se o token estiver ausente ou inválido, retorna erro 401 (Unauthorized).
###
2. **Rate Limiter Middleware**
Limita o número de requisições por IP para evitar abusos (rate limiting).
- Cada IP pode fazer até 3 requisições por segundo, com um burst máximo de 5.
- Se o limite for excedido, retorna erro 429 (Too Many Requests).
###
3. **Require Admin Middleware**
Garante que apenas usuários com papel de admin possam acessar determinadas rotas.
- Verifica o campo `role` no contexto da requisição.
- Se o usuário não for admin, retorna erro 401 (Unauthorized) e bloqueia o acesso à rota.
---
##
Endpoints 📌
###
Produtos
#### POST `/api/products`
Registra no sistema um novo produto.
- Headers:
- `Authorization`: Bearer `jwt_token`
- Middlewares Aplicados:
- [Auth Middleware](#auth-middleware)
- Request Body:
```json
{
"name": "Potato",
"price": 4.45
}
```
- Response:
```json
{
"id_product": 1,
"name": "Potato",
"price": 4.45
}
```
#### GET `/api/products`
Faz a listagem de todos os produtos do banco de dados.
Pode ser usado parâmetros, filtros e paginação nos resultados
- **Parâmetros de Busca**:
- `page` (opcional): Número da página, valor padrão = 1
- `limit` (opcional): Número de itens por página, valor padrão = 10
- `name` (opcional): Filtro pelo nome do produto
- **Exemplos**:
- Listar todos os produtos (padrão):
```
GET /api/products
```
- Listar produtos com paginação, limite e filtro por nome:
```
GET /api/products?page=1&limit=5&name=Potato
```
- Headers:
- `Authorization`: Bearer `jwt_token`
- Middlewares Aplicados:
- [Auth Middleware](#auth-middleware)
- Response:
```json
[
{
"id_product": 1,
"name": "Potato",
"price": 4.45
},
{
"id_product": 9,
"name": "Potato Chips",
"price": 9
}
...
]
```
#### GET `/api/products/:id_product`
Obtém as informações de um produto específico.
- Path Params:
- `id_product`: O ID do produto.
- Headers:
- `Authorization`: Bearer `jwt_token`
- Middlewares Aplicados:
- [Auth Middleware](#auth-middleware)
- Response:
```json
{
"id_product": 1,
"name": "Potato",
"price": 4.45
}
```
#### PUT `/api/products/:id_product`
Atualiza as informações de um produto específico.
- Path Params:
- `id_product`: O ID do produto.
- Headers:
- `Authorization`: Bearer `jwt_token`
- Middlewares Aplicados:
- [Auth Middleware](#auth-middleware)
- Objeto antes da atualização:
```json
{
"id_product": 14,
"name": "Pasta",
"price": 10.2
}
```
- Request Body:
```json
{
"name": "Spaghetti Pasta",
"price": 13.2
}
```
- Response:
```json
{
"id_product": 14,
"name": "Spaghetti Pasta",
"price": 13.2
}
```
- Observações:
- Campos não enviados no JSON permanecem inalterados.
#### DELETE `/api/admin/products/:id_product`
Apenas administradores podem acessar esse endpoint e excluir um produto do banco de dados.
- Path Params:
- `id_product`: O ID do produto.
- Headers:
- `Authorization`: Bearer `jwt_token`
- Middlewares Aplicados:
- [Auth Middleware](#auth-middleware)
- [Require Admin](#require-admin)
- Response:
```json
{
"Message": "Product deleted successfully"
}
```
---
###
Usuários
#### POST `/register`
Registra um novo usuário.
- Request Body:
```json
{
"username":"Test Example",
"email": "user@example.com",
"password": "password123"
}
```
- Response:
```json
{
"Message": "Register successful",
"User": {
"email": "user@example.com",
"role": "user",
"user_id": 1,
"username":"Test Example"
}
}
```
#### POST `/login`
Autentica um usuário e retorna um token JWT.
- Request Body:
```json
{
"email": "user@example.com",
"password": "password123"
}
```
- Response:
```json
{
"Message": "Login successful",
"token": "your_jwt_token"
}
```
#### GET `/api/users/:id_user`
Obtém as informações de um usuário específico.
- Path Params:
- `id_user`: O ID do usuário.
- Headers:
- `Authorization`: Bearer `jwt_token`
- Middlewares Aplicados:
- [Auth Middleware](#auth-middleware)
- Response:
```json
{
"id_user": 1,
"username":"Test Example",
"email": "user@example.com",
"password": "your_encrypted_password",
"role": "user"
}
```
#### GET `/api/user/info`
Retorna as informações do usuário autenticado (baseado no Token JWT).
- Headers:
- `Authorization`: Bearer `jwt_token`
- Middlewares Aplicados:
- [Auth Middleware](#auth-middleware)
- Response:
```json
{
"id_user": 1,
"username":"Test Example",
"email": "user@example.com",
"password": "your_encrypted_password",
"role": "user"
}
```
#### PUT `/api/users/:id_user`
Atualiza as informações de um usuário específico.
- Qualquer usuário autenticado pode atualizar seus próprios dados (username, email, password).
- Apenas administradores podem alterar o campo `role` de qualquer usuário.
- Path Params:
- `id_user`: O ID do usuário.
- Headers:
- `Authorization`: Bearer `jwt_token`
- Middlewares Aplicados:
- [Auth Middleware](#auth-middleware)
- [Require Admin](#require-admin)
- Objeto antes da atualização:
```json
{
"id_user": 1,
"username": "Name",
"email": "email@example.com",
"password": "Password123",
"role": "user"
}
```
- Request Body:
```json
{
"username": "New Name",
"email": "newemail@example.com",
"password": "newPassword123",
"role": "admin" // Só será atualizado se o usuário autenticado for admin
}
```
- Response:
```json
{
"id_user": 1,
"username":"New Name",
"email": "newemail@example.com",
"password": "your_new_encrypted_password",
"role": "admin"
}
```
- Observações:
- Se um usuário comum tentar alterar o campo role, receberá erro 403 (Forbidden).
- Campos não enviados no JSON permanecem inalterados.
- O campo password sempre será salvo de forma criptografada.
#### DELETE `/api/admin/users/:id_user`
Apenas administradores podem acessar esse endpoint e excluir um usuário do banco de dados.
- Path Params:
- `id_user`: O ID do usuário.
- Headers:
- `Authorization`: Bearer `jwt_token`
- Middlewares Aplicados:
- [Auth Middleware](#auth-middleware)
- [Require Admin](#require-admin)
- Response:
```json
{
"Message": "User deleted successfully"
}
```
---
##
Scripts ⌨️
###
Para iniciar
```sh
docker compose up -d
```
ou
```sh
cd product-go-api/cmd
go run main.go
```
---
###
Para fazer Build
```sh
docker build -t product-go-api .
```
ou
```sh
cd product-go-api/cmd
go build -o main cmd/main.go
```
---
##
Arquitetura do sistema 🏛️
A arquitetura do sistema segue o padrão Clean Architecture, separando claramente as responsabilidades em camadas. Isso facilita a manutenção, testes e evolução do projeto.
```
┌───────────────────────────────┐
│ Controllers (Gin HTTP handler)│
└───────────────┬───────────────┘
│
┌───────────────▼───────────────┐
│ Usecase (Regras de negócio) │
└───────────────┬───────────────┘
│
┌───────────────▼───────────────┐
│ Repository (Acesso a dados) │
└───────────────┬───────────────┘
│
┌───────────────▼───────────────┐
│ Model (Entidades) │
└───────────────┬───────────────┘
│
┌───────────────▼───────────────┐
│ Database (PostgreSQL) │
└───────────────────────────────┘
```
---
##
Estrutura de Pastas 📁
```
product-go-api/
├── cmd/
| └── main.go
├── controller/
| ├── product_controller.go
| └── user_controller.go
├── db/
| └── connection.go
├── middleware
| ├── authMiddleware.go
| ├── rateLimiter.go
| └── requireAdmin.go
├── model/
| ├── product.go
| ├── response.go
| └── user.go
├── repository/
| ├── product_repository.go
| └── user_repository.go
├── usecase/
| ├── product_usecase.go
| └── user_usecase.go
├── .env
├── .env.example
├── .gitignore
├── docker-compose.yml
├── Dockerfile
├── go.mod
├── go.sum
├── README-ptbr.md
└── README.md
```
---
##
Links Úteis 🔗
- [Documentação Oficial do Go (Golang)](https://golang.org/doc/)
- [Referência de módulos Go](https://blog.golang.org/using-go-modules)
- [Documentação do Gin Web Framework](https://gin-gonic.com/en/docs/)
- [Documentação do Docker](https://docs.docker.com/)
- [Documentação Oficial do PostgreSQL](https://www.postgresql.org/docs/)
- [Introdução ao JWT](https://jwt.io/introduction)
- [Insomnia](https://insomnia.rest/) / [Postman](https://www.postman.com/) — Ferramentas de testes de API
---
Desenvolvido por [Marcos Vinicius Boava](https://github.com/Mfrozzz), usando como base [Go Lab Tutoriais](https://www.youtube.com/watch?v=3p4mpId_ZU8&t=3317s).