{"id":29112675,"url":"https://github.com/mfrozzz/product-go-api","last_synced_at":"2026-04-28T16:04:48.907Z","repository":{"id":301418467,"uuid":"993422506","full_name":"Mfrozzz/product-go-api","owner":"Mfrozzz","description":"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.","archived":false,"fork":false,"pushed_at":"2025-06-26T18:41:21.000Z","size":56,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-06-26T19:39:49.105Z","etag":null,"topics":["api","clean-architecture","docker","dockerfile","gin","gin-gonic","go","golang","jwt","postgresql","sql"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Mfrozzz.png","metadata":{"files":{"readme":"README-ptbr.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-05-30T19:05:06.000Z","updated_at":"2025-06-26T18:41:25.000Z","dependencies_parsed_at":"2025-06-26T19:39:52.745Z","dependency_job_id":"dabf1da8-3a87-4f9a-94d7-dba90b663c14","html_url":"https://github.com/Mfrozzz/product-go-api","commit_stats":null,"previous_names":["mfrozzz/product-go-api"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Mfrozzz/product-go-api","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mfrozzz%2Fproduct-go-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mfrozzz%2Fproduct-go-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mfrozzz%2Fproduct-go-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mfrozzz%2Fproduct-go-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Mfrozzz","download_url":"https://codeload.github.com/Mfrozzz/product-go-api/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mfrozzz%2Fproduct-go-api/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262581282,"owners_count":23331908,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","clean-architecture","docker","dockerfile","gin","gin-gonic","go","golang","jwt","postgresql","sql"],"created_at":"2025-06-29T11:02:01.979Z","updated_at":"2026-04-28T16:04:48.896Z","avatar_url":"https://github.com/Mfrozzz.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Product API - Go lang\n\nAPI 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.\n\n## Sumário 📋\n* [Requisitos](#requirements)\n* [Configurando Ambiente](#setting-up-the-environment)\n* [Middlewares](#middlewares)\n* [Endpoints](#endpoints)\n* [Scripts](#scripts)\n* [Arquitetura do Sistema](#architecture)\n* [Estrutura de Pastas](#folder-structure)\n* [Links Úteis](#useful-links)\n* [Versão EN-US](README.md)\n\n---\n\n## \u003cdiv id=\"requirements\"\u003eRequisitos 📄\u003c/div\u003e\n\n- Go 1.24.3 ou 1.20+\n- Docker\n- PostgreSQL\n- Insomnia ou Postman\n\n---\n\n## \u003cdiv id=\"setting-up-the-environment\"\u003eConfigurando Ambiente ⚙️\u003c/div\u003e\n\n### \u003cdiv\u003eRepositório\u003c/div\u003e\n\n1. **Clone o repositório:**\n\n   ```sh\n   git clone https://github.com/Mfrozzz/product-go-api.git\n   cd product-go-api\n   ```\n\n2. **Consigure o arquivo `.env`:**\n\n    * Copie o arquivo `.env.example` para `.env` e preencha com as suas configurações:\n\n    ```sh\n    cp .env.example .env\n    ```\n\n    * Exemplo do arquivo:\n\n    ```.env\n    JWT_SECRET=\"YOUR-SECRET-KEY\"\n    PORT=\":8000\"\n\n    DB_HOST=\"go_db\"\n    DB_PORT=5432\n    DB_USER=\"YOUR-DATABASE-USER\"\n    DB_PASSWORD=\"YOUR-DATABASE-PASSWORD\"\n    DB_NAME=\"YOUR-DATABASE-NAME\"\n    ```\n\n    * **Importante:** O projeto depende das variáveis do `.env` para conectar ao banco e gerar tokens JWT.\n\n3. **Instale as dependências Go:**\n  ```sh\n  go mod tidy\n  ```\n\n---\n\n### \u003cdiv\u003eDocker\u003c/div\u003e\n\n* Para subir os containers execute:\n\n```sh\ndocker compose up -d\n```\n\n* Para realizar a build dos containers execute:\n\n```\ndocker build -t product-go-api .\n```\n\n---\n\n### \u003cdiv\u003eBanco de Dados\u003c/div\u003e\n\nA 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.\n\n* Acesso ao Banco de dados:\n\n```sh\ndocker exec -it go_db bash\npsql -d postgres -U postgres\n```\n\n* Criar Tabelas no Banco de dados:\n\n```sh\nCREATE TABLE product (\n  id SERIAL PRIMARY KEY,\n  product_name VARCHAR(50) NOT NULL,\n  price NUMERIC(10, 2) NOT NULL\n);\nCREATE TABLE users (\n  id SERIAL PRIMARY KEY,\n  email VARCHAR(255) UNIQUE NOT NULL,\n  username VARCHAR(255) NOT NULL,\n  password VARCHAR(255) NOT NULL,\n  role VARCHAR(20) NOT NULL DEFAULT 'user'\n);\n```\n\n### \u003cdiv\u003eDica: Como criar um usuário admin ✉️\u003c/div\u003e\n\nPara transformar um usuário em admin diretamente pelo banco de dados, execute:\n\n```sh\nUPDATE users SET role = 'admin' WHERE id = 1;\n```\n\nPara transformar um usuário em um super_admin diretamente pelo banco de dados, execute:\n\n```sh\nUPDATE users SET role = 'super_admin' WHERE id = 1;\n```\n\n---\n\n## \u003cdiv id=\"middlewares\"\u003eMiddlewares ↔️\u003c/div\u003e\n\nO projeto utiliza três middlewares principais para garantir segurança, controle de acesso e limitação de requisições:\n\n### \u003cdiv id=\"auth-middleware\"\u003e1. **Auth Middleware**\u003c/div\u003e\n\nResponsável por validar o token JWT enviado no header `Authorization`.  \n- Só vai permitir que o usuário tenha acesso às rotas caso esteja autenticado (realizado o login).\n- 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.\n- Se o token estiver ausente ou inválido, retorna erro 401 (Unauthorized).\n\n### \u003cdiv id=\"rate-limiter\"\u003e2. **Rate Limiter Middleware**\u003c/div\u003e\n\nLimita o número de requisições por IP para evitar abusos (rate limiting).\n- Cada IP pode fazer até 3 requisições por segundo, com um burst máximo de 5.\n- Se o limite for excedido, retorna erro 429 (Too Many Requests).\n\n### \u003cdiv id=\"require-admin\"\u003e3. **Require Admin Middleware**\u003c/div\u003e\n\nGarante que apenas usuários com papel de admin possam acessar determinadas rotas.\n- Verifica o campo `role` no contexto da requisição.\n- Se o usuário não for admin, retorna erro 401 (Unauthorized) e bloqueia o acesso à rota.\n\n---\n\n## \u003cdiv id=\"endpoints\"\u003eEndpoints 📌\u003c/div\u003e\n\n### \u003cdiv\u003eProdutos\u003c/div\u003e\n\n#### POST `/api/products`\n\nRegistra no sistema um novo produto.\n\n- Headers:\n  - `Authorization`: Bearer `jwt_token`\n\n- Middlewares Aplicados:\n  - [Auth Middleware](#auth-middleware)\n\n- Request Body:\n  ```json\n  {\n    \"name\": \"Potato\",\n    \"price\": 4.45\n  }\n  ```\n\n- Response:\n  ```json\n  {\n    \"id_product\": 1,\n    \"name\": \"Potato\",\n    \"price\": 4.45\n  }\n  ```\n\n#### GET `/api/products`\n\nFaz a listagem de todos os produtos do banco de dados.\nPode ser usado parâmetros, filtros e paginação nos resultados\n\n- **Parâmetros de Busca**:\n  - `page` (opcional): Número da página, valor padrão = 1\n  - `limit` (opcional): Número de itens por página, valor padrão = 10\n  - `name` (opcional): Filtro pelo nome do produto\n\n- **Exemplos**:\n  - Listar todos os produtos (padrão):\n  ```\n  GET /api/products\n  ```\n  - Listar produtos com paginação, limite e filtro por nome:\n  ```\n  GET /api/products?page=1\u0026limit=5\u0026name=Potato\n  ```\n\n- Headers:\n  - `Authorization`: Bearer `jwt_token`\n\n- Middlewares Aplicados:\n  - [Auth Middleware](#auth-middleware)\n\n- Response:\n  ```json\n  [\n    {\n      \"id_product\": 1,\n      \"name\": \"Potato\",\n      \"price\": 4.45\n    },\n    {\n      \"id_product\": 9,\n      \"name\": \"Potato Chips\",\n      \"price\": 9\n    }\n    ...\n  ]\n  ```\n\n#### GET `/api/products/:id_product`\n\nObtém as informações de um produto específico.\n\n- Path Params:\n  - `id_product`: O ID do produto.\n\n- Headers:\n  - `Authorization`: Bearer `jwt_token`\n\n- Middlewares Aplicados:\n  - [Auth Middleware](#auth-middleware)\n\n- Response:\n  ```json\n  {\n    \"id_product\": 1,\n    \"name\": \"Potato\",\n    \"price\": 4.45\n  }\n  ```\n\n#### PUT `/api/products/:id_product`\n\nAtualiza as informações de um produto específico.\n\n- Path Params:\n  - `id_product`: O ID do produto.\n\n- Headers:\n  - `Authorization`: Bearer `jwt_token`\n\n- Middlewares Aplicados:\n  - [Auth Middleware](#auth-middleware)\n\n- Objeto antes da atualização:\n  ```json\n  {\n    \"id_product\": 14,\n    \"name\": \"Pasta\",\n    \"price\": 10.2\n  }\n  ```\n\n- Request Body:\n  ```json\n  {\n    \"name\": \"Spaghetti Pasta\",\n    \"price\": 13.2\n  }\n  ```\n\n- Response:\n  ```json\n  {\n    \"id_product\": 14,\n    \"name\": \"Spaghetti Pasta\",\n    \"price\": 13.2\n  }\n  ```\n\n- Observações:\n  - Campos não enviados no JSON permanecem inalterados.\n\n\n#### DELETE `/api/admin/products/:id_product`\n\nApenas administradores podem acessar esse endpoint e excluir um produto do banco de dados.\n\n- Path Params:\n  - `id_product`: O ID do produto.\n\n- Headers:\n  - `Authorization`: Bearer `jwt_token`\n\n- Middlewares Aplicados:\n  - [Auth Middleware](#auth-middleware)\n  - [Require Admin](#require-admin)\n\n- Response:\n  ```json\n  {\n    \"Message\": \"Product deleted successfully\"\n  }\n  ```\n\n---\n\n### \u003cdiv\u003eUsuários\u003c/div\u003e\n\n#### POST `/register`\n\nRegistra um novo usuário.\n\n- Request Body:\n  ```json\n  {\n    \"username\":\"Test Example\",\n    \"email\": \"user@example.com\",\n    \"password\": \"password123\"\n  }\n  ```\n\n- Response:\n  ```json\n  {\n    \"Message\": \"Register successful\",\n    \"User\": {\n      \"email\": \"user@example.com\",\n      \"role\": \"user\",\n      \"user_id\": 1,\n      \"username\":\"Test Example\"\n    }\n  }\n  ```\n\n#### POST `/login`\n\nAutentica um usuário e retorna um token JWT.\n\n- Request Body:\n  ```json\n  {\n    \"email\": \"user@example.com\",\n    \"password\": \"password123\"\n  }\n  ```\n\n- Response:\n  ```json\n  {\n    \"Message\": \"Login successful\",\n    \"token\": \"your_jwt_token\"\n  }\n  ```\n\n#### GET `/api/users/:id_user`\n\nObtém as informações de um usuário específico.\n\n- Path Params:\n  - `id_user`: O ID do usuário.\n\n- Headers:\n  - `Authorization`: Bearer `jwt_token`\n\n- Middlewares Aplicados:\n  - [Auth Middleware](#auth-middleware)\n\n- Response:\n  ```json\n  {\n    \"id_user\": 1,\n    \"username\":\"Test Example\",\n    \"email\": \"user@example.com\",\n    \"password\": \"your_encrypted_password\",\n    \"role\": \"user\"\n  }\n  ```\n\n#### GET `/api/user/info`\n\nRetorna as informações do usuário autenticado (baseado no Token JWT).\n\n- Headers:\n  - `Authorization`: Bearer `jwt_token`\n\n- Middlewares Aplicados:\n  - [Auth Middleware](#auth-middleware)\n\n- Response:\n  ```json\n  {\n    \"id_user\": 1,\n    \"username\":\"Test Example\",\n    \"email\": \"user@example.com\",\n    \"password\": \"your_encrypted_password\",\n    \"role\": \"user\"\n  }\n  ```\n\n#### GET `/api/admin/users`\n\nRetorna todos os usuários do banco de dados. Pode ser usado parâmetros, filtros e paginação nos resultados\n\n- **Parâmetros de Busca**:\n  - `page` (opcional): Número da página, valor padrão = 1\n  - `limit` (opcional): Número de itens por página, valor padrão = 10\n  - `name` (opcional): Filtro pelo nome do usuário\n\n- **Exemplos**:\n  - Listar todos os usuários (padrão):\n  ```\n  GET /api/admin/users\n  ```\n  - Listar usuários com paginação, limite e filtro por nome:\n  ```\n  GET /api/admin/users?page=1\u0026limit=5\u0026name=user\n  ```\n\n- Headers:\n  - `Authorization`: Bearer `jwt_token`\n\n- Middlewares Aplicados:\n  - [Auth Middleware](#auth-middleware)\n  - [Require Admin](#require-admin)\n\n- Response:\n  ```json\n  [\n    {\n      \"id_user\": 1,\n      \"username\":\"Test Example\",\n      \"email\": \"user@example.com\",\n      \"password\": \"your_encrypted_password\",\n      \"role\": \"user\"\n    },\n    {\n      \"id_user\": 2,\n      \"username\":\"Test Example 2\",\n      \"email\": \"user2@example.com\",\n      \"password\": \"your_encrypted_password\",\n      \"role\": \"user2\"\n    }\n    ...\n  ]\n  ```\n\n#### PUT `/api/users/:id_user`\n\nAtualiza as informações de um usuário específico.\n\n- Qualquer usuário autenticado pode atualizar seus próprios dados (username, email, password).\n- Apenas **super_admins** têm permissão para::\n  - Promover um usuário para `super_admin`\n  - Modificar a role de outro `admin` ou `super_admin`\n\n- Path Params:\n  - `id_user`: O ID do usuário.\n\n- Headers:\n  - `Authorization`: Bearer `jwt_token`\n\n- Middlewares Aplicados:\n  - [Auth Middleware](#auth-middleware)\n  - [Require Admin](#require-admin)\n\n- Objeto antes da atualização:\n```json\n  {\n    \"id_user\": 1,\n    \"username\": \"Name\",\n    \"email\": \"email@example.com\",\n    \"password\": \"Password123\",\n    \"role\": \"user\"\n  }\n```\n\n- Request Body:\n  ```json\n  {\n    \"username\": \"New Name\",\n    \"email\": \"newemail@example.com\",\n    \"password\": \"newPassword123\",\n    \"role\": \"admin\" // Só será atualizado se o usuário autenticado for admin ou super_admin\n  }\n  ```\n\n- Response:\n  ```json\n  {\n    \"id_user\": 1,\n    \"username\":\"New Name\",\n    \"email\": \"newemail@example.com\",\n    \"password\": \"your_new_encrypted_password\",\n    \"role\": \"admin\"\n  }\n  ```\n\n- Observações:\n  - Se um usuário sem as permissões necessárias tentar alterar o campo de role, um erro 403 (Forbidden) será retornado.\n  - Campos não enviados no JSON permanecem inalterados.\n  - O campo password sempre será salvo de forma criptografada.\n  - Apenas `super_admins` podem:\n    - Promover usuários para `super_admin`\n    - Alterar a role de usuários com role `admin` ou `super_admin`\n\n#### DELETE `/api/admin/users/:id_user`\n\nApenas administradores podem acessar esse endpoint e excluir um usuário do banco de dados.\n\n- Path Params:\n  - `id_user`: O ID do usuário.\n\n- Headers:\n  - `Authorization`: Bearer `jwt_token`\n\n- Middlewares Aplicados:\n  - [Auth Middleware](#auth-middleware)\n  - [Require Admin](#require-admin)\n\n- Response:\n  ```json\n  {\n    \"Message\": \"User deleted successfully\"\n  }\n  ```\n\n- Notes:\n  - Apenas **super_admins** têm permissão para deletar usuários com a role `admin` ou `super_admin`.\n  - Se um `admin` tentar deletar outro `admin` ou um `super_admin`, um erro `403 Forbidden` será retornado.\n\n---\n\n## \u003cdiv id=\"scripts\"\u003eScripts ⌨️\u003c/div\u003e\n\n### \u003cdiv\u003ePara iniciar\u003c/div\u003e\n\n```sh\ndocker compose up -d\n```\n\nou\n\n```sh\ncd product-go-api/cmd\ngo run main.go\n```\n\n---\n\n### \u003cdiv\u003ePara fazer Build\u003c/div\u003e\n\n```sh\ndocker build -t product-go-api .\n```\n\nou\n\n```sh\ncd product-go-api/cmd\ngo build -o main cmd/main.go\n```\n\n---\n\n## \u003cdiv id=\"architecture\"\u003eArquitetura do sistema 🏛️\u003c/div\u003e\n\nA 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.\n\n```\n           ┌───────────────────────────────┐\n           │ Controllers (Gin HTTP handler)│\n           └───────────────┬───────────────┘\n                           │\n           ┌───────────────▼───────────────┐\n           │   Usecase (Regras de negócio) │\n           └───────────────┬───────────────┘\n                           │\n           ┌───────────────▼───────────────┐\n           │ Repository (Acesso a dados)   │\n           └───────────────┬───────────────┘\n                           │\n           ┌───────────────▼───────────────┐\n           │      Model (Entidades)        │\n           └───────────────┬───────────────┘\n                           │\n           ┌───────────────▼───────────────┐\n           │   Database (PostgreSQL)       │\n           └───────────────────────────────┘\n```\n\n---\n\n## \u003cdiv id=\"folder-structure\"\u003eEstrutura de Pastas 📁\u003c/div\u003e\n\n```\nproduct-go-api/\n├── cmd/\n|   └── main.go\n├── controller/\n|   ├── product_controller.go\n|   └── user_controller.go\n├── db/\n|   └── connection.go\n├── middleware\n|   ├── authMiddleware.go\n|   ├── rateLimiter.go\n|   └── requireAdmin.go\n├── model/\n|   ├── product.go\n|   ├── response.go\n|   └── user.go\n├── repository/\n|   ├── product_repository.go\n|   └── user_repository.go\n├── usecase/\n|   ├── product_usecase.go\n|   └── user_usecase.go\n├── .env\n├── .env.example\n├── .gitignore\n├── docker-compose.yml\n├── Dockerfile\n├── go.mod\n├── go.sum\n├── README-ptbr.md\n└── README.md\n```\n\n---\n\n## \u003cdiv id=\"useful-links\"\u003eLinks Úteis 🔗\u003c/div\u003e\n\n- [Documentação Oficial do Go (Golang)](https://golang.org/doc/)\n- [Referência de módulos Go](https://blog.golang.org/using-go-modules)\n- [Documentação do Gin Web Framework](https://gin-gonic.com/en/docs/)\n- [Documentação do Docker](https://docs.docker.com/)\n- [Documentação Oficial do PostgreSQL](https://www.postgresql.org/docs/)\n- [Introdução ao JWT](https://jwt.io/introduction)\n- [Insomnia](https://insomnia.rest/) / [Postman](https://www.postman.com/) — Ferramentas de testes de API\n\n---\n\nDesenvolvido por [Marcos Vinicius Boava](https://github.com/Mfrozzz), usando como base [Go Lab Tutoriais](https://www.youtube.com/watch?v=3p4mpId_ZU8\u0026t=3317s).","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmfrozzz%2Fproduct-go-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmfrozzz%2Fproduct-go-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmfrozzz%2Fproduct-go-api/lists"}