Índice

Este conjunto de arquivos constitui a espinha dorsal de uma aplicação RESTful desenvolvida em Go, que gerencia um sistema de pedidos para um estabelecimento, possivelmente um bar ou restaurante. A arquitetura da aplicação é projetada para separar as preocupações entre as camadas de roteamento, manipulação, serviços e acesso aos dados, proporcionando uma base sólida e modular para a funcionalidade do sistema.

Estrutura da Aplicação

A aplicação é organizada em pacotes distintos que refletem suas responsabilidades principais:

  • Bootstrap: Configuração inicial e roteamento da aplicação, incluindo a verificação e criação de um usuário administrador se necessário.
  • Handlers: Manipuladores que processam as requisições HTTP, delegando a lógica de negócios para os serviços correspondentes e formatando as respostas HTTP.
  • Models: Definições de modelos de dados que representam as entidades da aplicação, como usuários, itens de menu, pedidos e itens de pedido.
  • Services: Camada de serviço que contém a lógica de negócios e interage com a camada de acesso a dados para executar operações CRUD, entre outras funcionalidades.
  • Store: Camada de acesso a dados que interage diretamente com o banco de dados para realizar operações relacionadas a entidades específicas.
  • Utils: Funções auxiliares e constantes globais, incluindo a geração de senhas aleatórias, validação de e-mails, e outras utilidades.

Funcionalidades Principais

A aplicação suporta um amplo espectro de operações essenciais para a gestão de pedidos, incluindo:

  • Autenticação de usuários e gerenciamento de sessões com tokens JWT.
  • Criação, atualização, recuperação e exclusão de usuários, itens de menu, pedidos e itens de pedido.
  • Controle de acesso baseado em papéis, garantindo que apenas usuários autorizados possam realizar certas operações.

Segurança e Manutenção

Medidas de segurança são implementadas através do uso de middleware de autenticação e a prática de armazenar senhas como hashes. A aplicação também adota convenções de codificação e organização que facilitam a manutenção e a expansão futura do código.

Descrição dos Pacotes

A estrutura de diretórios da API REST em GoLang está organizada de forma modular e escalável, seguindo boas práticas de desenvolvimento de software.

Bash

user@computer:~$ tree .
.
├── bootstrap
│ └── bootstrap.go
├── go.mod
├── go.sum
├── handlers
│ ├── auth.go
│ ├── item_order_handler.go
│ ├── menu_item_handler.go
│ ├── middleware.go
│ ├── order_handler.go
│ └── user_handler.go
├── main.go
├── models
│ ├── credentials.go
│ ├── item_order.go
│ ├── menu_item.go
│ ├── order.go
│ └── user.go
├── services
│ ├── auth_service.go
│ ├── item_order_service.go
│ ├── menu_item_service.go
│ ├── order_service.go
│ └── user_service.go
├── store
│ ├── database.go
│ ├── item_order_store.go
│ ├── menu_item_store.go
│ ├── order_store.go
│ └── user_store.go
└── utils
├── constants.go
├── database_functions.go
└── generic_functions.go

Os tópicos a seguir trazem um detalhamento mais profundo de cada pacote.

Diretório models

Os modelos definidos representam a estrutura de dados da aplicação, cada um desempenhando um papel específico no contexto do sistema de gestão de bares. Abaixo, detalho brevemente cada um dos modelos:

Arquivo models/credentials.go

  • Credentials: Representa as credenciais de login de um usuário, contendo Email, Password e Name. Este modelo é utilizado durante o processo de autenticação para verificar a identidade do usuário.

Arquivo models/user.go

  • Role: Define diferentes papéis que um usuário pode ter dentro do sistema (Cliente, Garcom, Gerente, Admin, Cozinha, Caixa). Esses papéis são usados para controlar o acesso a diferentes partes da aplicação com base nas permissões de cada usuário.
  • User: Estrutura que representa um usuário do sistema, incluindo informações como Id, Name, Email, PasswordHash, e Role. A senha é armazenada como um hash, importante para proteger as credenciais dos usuários.

Arquivo models/menu_item.go

  • MenuItem: Representa um item do menu do bar, incluindo detalhes como Id, Name, Description, Price, e ImageURL. Este modelo é usado para gerenciar os itens disponíveis para o menu e pedidos.

Arquivo models/order.go

  • Status: Enumera os possíveis estados de um pedido (Recebido, Preparando, Pronto, Entregue). Isso ajuda a rastrear o progresso de cada pedido.
  • Order: Estrutura que representa um pedido feito no sistema, contendo Id, UserId (o usuário que fez o pedido), DateHour (data e hora do pedido), e Status (o estado atual do pedido).

Arquivo models/item_order.go

  • ItemOrder: Detalha os itens específicos dentro de um pedido, incluindo Id, OrderId (referência ao pedido ao qual o item pertence), ItemId (referência ao item do menu pedido), Amount (quantidade pedida), e Comments (comentários ou instruções especiais para o item pedido).

Cada um desses modelos é uma representação crucial dos dados que a aplicação manipula, permitindo que o sistema armazene e recupere informações de forma estruturada. Utilizando esses modelos, a aplicação pode efetivamente gerenciar usuários, itens do menu, e pedidos, além de aplicar lógicas específicas com base nos papéis dos usuários e no estado dos pedidos.

Diretório store

Responsável pela interação com o banco de dados, contendo a implementação da persistência de dados.

Arquivo store/database.go

O arquivo store/database.go é responsável pela gestão da conexão com o banco de dados e pela definição inicial da estrutura do banco de dados (tabelas, índices, etc.). Abaixo, detalho o propósito e o funcionamento de cada parte deste arquivo:

Constantes
  • Tabelas e Colunas: Define constantes para os nomes das tabelas (TableUsers, TableMenuItem, TableOrders, TableItensOrders) e colunas usadas nas tabelas do banco de dados. Essas constantes são utilizadas nas queries SQL para evitar repetição de strings e facilitar manutenção.
  • Índices: Define constantes para os nomes dos índices (IndexMenuItem, IndexUserId, IndexOrderId) que serão criados para otimizar as consultas ao banco de dados.
Estrutura DatabaseStore
  • DatabaseStore: Mantém informações necessárias para a conexão com o banco de dados, incluindo o nome do banco (DBName) e a própria conexão (*sql.DB).
Funções
  • NewDatabaseStore: Cria uma nova instância de DatabaseStore, inicializando-a com o nome do banco de dados e a conexão com o banco.
  • DatabaseOpen: Abre uma nova conexão com o banco de dados usando a string de conexão fornecida. Testa a conexão com db.Ping() para garantir que a conexão é válida antes de retornar a instância de DatabaseStore.
  • CreateDatabase: Engloba uma série de operações para criar o banco de dados (se não existir), usar o banco de dados, criar as tabelas necessárias e criar os índices. Cada uma dessas operações é realizada por uma função dedicada.
  • createDatabaseIfNotExists: Cria o banco de dados caso ele não exista, utilizando o nome fornecido na instância DatabaseStore.
  • useDatabase: Seleciona o banco de dados para ser usado nas operações subsequentes.
  • createTables: Cria as tabelas necessárias para a aplicação, baseadas nas constantes definidas para tabelas e colunas. As tabelas incluem usuários, itens de menu, pedidos e itens de pedido, cada uma com suas respectivas colunas e tipos de dados.
  • createIndexes: Cria índices nas tabelas para otimizar consultas específicas, melhorando a performance da aplicação.
  • DatabaseClose: Fecha a conexão com o banco de dados, liberando os recursos associados.
Práticas de Codificação e Padrões
  • Preparação de Queries: Ao criar tabelas e índices, o código prepara as queries SQL antes de executá-las, uma prática que ajuda a prevenir SQL injection e otimiza a execução de consultas repetidas.
  • defer stmt.Close(): Usado para garantir que os recursos de statement sejam liberados apropriadamente após a conclusão da consulta, evitando vazamentos de recursos.
  • Tratamento de Erros: Cada operação de banco de dados inclui tratamento de erros, registrando e retornando erros para serem tratados adequadamente pela chamada de função.

Este arquivo desempenha um papel crítico na inicialização da aplicação, garantindo que a estrutura do banco de dados esteja pronta e otimizada para o uso pela aplicação, e que a conexão com o banco de dados seja gerenciada de forma eficiente.

A imagem abaixo representa o esquema do banco de dados.

Arquivo store/user_store.go

O arquivo users_store.go define a camada de acesso a dados para usuários no sistema, interagindo diretamente com o banco de dados para executar operações CRUD (Create, Read, Update, Delete) sobre os dados dos usuários. A seguir, comento as partes principais do código:

Estrutura e Interface
  • UserStore: Mantém uma referência à conexão com o banco de dados (*sql.DB), permitindo realizar operações no banco de dados relacionadas a usuários.
  • UserStorer: Interface que define os métodos que UserStore deve implementar, garantindo que UserStore siga um contrato específico para operações de usuário.
Constantes SQL

Define strings de consulta SQL para várias operações relacionadas a usuários, como criar, atualizar, deletar, e buscar usuários. Essas strings são formatadas dinamicamente com nomes de tabelas e colunas para serem utilizadas nas consultas SQL.

Métodos
  • CreateUser: Adiciona um novo usuário ao banco de dados, utilizando bcrypt para gerar um hash da senha do usuário antes de armazená-la, prática recomendada para segurança das senhas.
  • GetUserByEmail, GetUser, GetUsersByRole, GetAllUsers: Métodos para buscar usuários no banco de dados por diferentes critérios, como email, ID, papel, ou buscar todos os usuários.
  • UpdateUser: Atualiza os dados de um usuário no banco de dados, exceto a senha. Isso inclui o nome, o email e o papel do usuário.
  • UpdateUserPass: Atualiza apenas a senha de um usuário, também utilizando bcrypt para gerar um novo hash da senha.
  • DeleteUser: Remove um usuário do banco de dados pelo ID.
Práticas de Codificação e Padrões
  • Preparação de Consultas SQL: Antes de executar uma consulta, o código prepara a consulta SQL com store.DB.Prepare(sqlString), o que pode ajudar a prevenir injeção de SQL e melhora a eficiência da execução de consultas repetidas.
  • defer stmt.Close(): Garante que os recursos de statement sejam liberados adequadamente após o término da operação.
  • Tratamento de Erros: Cada operação de banco de dados inclui tratamento de erros, onde os erros são registrados e, em seguida, retornados para serem tratados pela chamada de função.
  • Uso de fmt.Sprintf para Montagem de Consultas SQL: Permite flexibilidade nas consultas SQL. Neste contexto, os parâmetros de entrada para fmt.Sprintf são controlados e não representam um risco direto a segurança.

Este arquivo é um componente essencial para a gestão de usuários na aplicação, permitindo uma interação segura e eficaz com o banco de dados para todas as operações relacionadas a usuários.

Arquivo store/menu_item_store.go

O arquivo menu_item_store.go define a camada de acesso a dados específica para operações relacionadas a itens do menu na aplicação. Abaixo, vou comentar sobre as principais partes e funcionalidades deste arquivo:

Estrutura e Interface
  • MenuItemStore: Uma estrutura que mantém uma referência à conexão com o banco de dados (*sql.DB). Isso permite que a estrutura execute operações no banco de dados relacionadas a itens do menu.
  • MenuItemStorer: Uma interface que define os métodos que MenuItemStore deve implementar. Isso inclui adicionar, buscar, atualizar e deletar itens do menu, bem como buscar todos os itens do menu ou por nome.
Constantes SQL
  • O arquivo define várias constantes de strings SQL para realizar operações CRUD nos itens do menu. Cada consulta é formatada dinamicamente com nomes de tabelas e colunas para facilitar a manutenção e evitar erros de digitação.
Métodos
  • NewMenuItem: Um construtor para criar uma nova instância de MenuItemStore, inicializando-a com a conexão com o banco de dados fornecida.
  • CreateMenuItem: Adiciona um novo item do menu ao banco de dados. Antes de inserir, prepara a consulta SQL e, em seguida, executa a consulta com os valores dos atributos do item do menu.
  • GetMenuItem: Busca um item do menu pelo ID. Prepara e executa uma consulta SQL para buscar um único item do menu, retornando o item se encontrado.
  • UpdateMenuItem: Atualiza os detalhes de um item do menu existente no banco de dados, com exceção do ID, que é utilizado para identificar qual item deve ser atualizado.
  • DeleteMenuItem: Remove um item do menu do banco de dados pelo ID. Este método destaca a necessidade de tratar remoções com cuidado, especialmente em um ambiente de produção.
  • GetAllMenuItem: Busca e retorna todos os itens do menu, ordenados pelo nome. Isso permite a exibição de uma lista completa dos itens disponíveis.
  • GetMenuItemByName: Busca um item do menu pelo nome. Isso será útil buscar itens específicos sem conhecer o ID.
Práticas de Codificação e Padrões
  • Preparação e Execução de Consultas: Para cada operação de banco de dados, o código prepara a consulta SQL, executa a consulta com os parâmetros apropriados e trata os resultados ou erros conforme necessário.
  • defer stmt.Close(): Garante que os recursos do statement sejam liberados apropriadamente após o término da operação, prevenindo vazamentos de recursos.
  • Tratamento de Erros: Cada operação inclui um tratamento robusto de erros, logando e retornando erros para serem tratados adequadamente pela chamada de função.
  • log.Printf para Logar Erros: Utilizado para registrar erros que ocorrem durante as operações de banco de dados, facilitando o diagnóstico de problemas.

Este arquivo é crucial para o gerenciamento de itens do menu na aplicação, permitindo uma interação eficaz e segura com o banco de dados para manipulação desses itens.

Arquivo store/order_store.go

O arquivo order_store.go é responsável por gerenciar a camada de acesso a dados para operações relacionadas aos pedidos (Order) na aplicação. A seguir, comento as partes principais do código para uma compreensão mais clara:

Estrutura e Interface
  • OrderStore: Mantém uma referência à conexão com o banco de dados (*sql.DB), o que permite realizar operações no banco de dados relacionadas aos pedidos.
  • OrderStorer: Interface que define as operações que um OrderStore precisa implementar, incluindo criar, atualizar, deletar pedidos, obter um pedido por ID, obter todos os pedidos de um usuário, e obter pedidos pendentes.
Métodos Implementados
  • CreateOrder: Insere um novo pedido no banco de dados. Requer informações como o ID do usuário (UserId), a data e hora (DateHour), e o status do pedido (Status).
  • GetOrder: Busca um pedido pelo ID, retornando um objeto Order preenchido com os dados encontrados no banco de dados.
  • UpdateOrder: Atualiza os dados de um pedido existente no banco de dados. Permite modificar o UserId, DateHour, e Status de um pedido existente.
  • DeleteOrder: Remove um pedido do banco de dados pelo ID. Inclui uma nota sobre a necessidade de tratar remoções de registros com cuidado.
  • GetOrderByUser: Busca todos os pedidos feitos por um usuário específico, identificado pelo UserId. Retorna uma lista de pedidos.
  • GetPendingOrders: Retorna todos os pedidos que estão com status diferente de “entregue”. Útil para rastrear pedidos que ainda precisam ser processados ou entregues.
Constantes SQL
  • São definidas strings de consulta SQL para as operações de CRUD nos pedidos. Essas strings são formatadas dinamicamente com os nomes das tabelas e colunas.
Função Auxiliar
  • dateHourParse: Uma função auxiliar para converter strings de data e hora no formato “2006-01-02 15:04:05” (formato comum do MySQL) para o tipo time.Time do Go. Isso é usado para converter os valores de data e hora quando pedidos são recuperados do banco de dados.
Práticas de Codificação e Padrões
  • Preparação de Consultas SQL: As consultas são preparadas (store.DB.Prepare) antes de serem executadas, o que ajuda a evitar injeções SQL e melhora a performance.
  • Tratamento de Erros: Cada operação de banco de dados inclui tratamento de erros, onde os erros são registrados e retornados para serem tratados pela chamada de função.
  • Fechamento de Recursos: Utiliza defer stmt.Close() para garantir que os recursos do statement sejam liberados apropriadamente após a conclusão da operação.

Este arquivo desempenha um papel crucial na gestão de pedidos dentro da aplicação, facilitando a interação com o banco de dados para realizar operações relacionadas aos pedidos de forma segura e eficiente.

Arquivo store/item_order_store.go

O arquivo item_order_store.go define a camada de acesso a dados para operações relacionadas a itens de pedidos no sistema. Esse componente é essencial para gerenciar a relação entre pedidos e itens específicos que fazem parte desses pedidos. A seguir, comento detalhadamente cada parte deste arquivo:

Estrutura e Interface
  • ItemOrderStore: Mantém a conexão com o banco de dados (*sql.DB) e é responsável por executar operações relacionadas a itens de pedidos, como adicionar, buscar, atualizar e remover itens de pedidos.
  • ItemOrderStorer: Define um conjunto de operações (CRUD) que ItemOrderStore deve implementar, estabelecendo um contrato que garante a consistência e a previsibilidade das interações com itens de pedidos.
Métodos Implementados
  • CreateItemOrder: Insere um novo item de pedido no banco de dados, utilizando informações de models.ItemOrder fornecidas.
  • GetItemOrder: Busca um item de pedido específico pelo ID, retornando uma instância de models.ItemOrder com os dados recuperados.
  • UpdateItemOrder: Atualiza os detalhes de um item de pedido existente no banco de dados, como quantidade e comentários.
  • DeleteItemOrder: Remove um item de pedido do banco de dados pelo ID.
Constantes SQL
  • Define strings de consulta SQL para diversas operações de banco de dados relacionadas a itens de pedidos. As consultas são formatadas dinamicamente com nomes de tabelas e colunas, permitindo a flexibilidade e a reutilização do código.
Práticas de Codificação e Padrões
  • Uso de fmt.Sprintf para Consultas SQL: O código utiliza fmt.Sprintf para construir consultas SQL dinamicamente.
  • Preparação e Execução de Consultas: As consultas são preparadas com store.DB.Prepare e executadas com stmt.Exec, seguindo boas práticas para interação segura com o banco de dados.
  • Tratamento de Erros: Cada operação de banco de dados inclui tratamento de erros, onde os erros são registrados e, em seguida, retornados para serem tratados pelo chamador.
  • Fechamento de Recursos: O uso de defer stmt.Close() assegura que os recursos associados ao statement sejam liberados corretamente, evitando vazamentos de recursos.
  • Comentários FIXME: Indica áreas do código que requerem atenção adicional ou cautela, especialmente em relação à remoção de registros, uma prática que deve ser abordada com considerações adicionais em ambientes de produção para evitar efeitos colaterais indesejados.

Este arquivo é crucial para o gerenciamento de itens dentro dos pedidos, permitindo que a aplicação mantenha um registro detalhado dos itens que os usuários pedem, incluindo quantidades e comentários especiais, e oferece a flexibilidade necessária para atualizar ou remover itens conforme necessário.

Segurança Contra Injeção SQL

Embora a validação de entrada por si só não seja suficiente para prevenir injeção SQL, ela pode ser uma camada adicional de defesa. Validar a entrada do usuário contra um conjunto de critérios específicos (por exemplo, garantindo que um campo numérico contenha apenas números) pode reduzir a superfície de ataque.

ORMs (Object-Relational Mappings): Ferramentas ORM, como GORM para Go, abstraem a construção de consultas SQL e geralmente oferecem proteção contra injeção SQL, construindo automaticamente consultas seguras com base nas operações de objeto que você executa.

Diretório services

Contém a lógica de negócios da aplicação, onde cada serviço interage com os modelos e a camada de armazenamento para executar operações específicas.

Arquivo services/auth_service.go

O arquivo auth_service.go define um serviço de autenticação para sua aplicação, responsável por validar as credenciais dos usuários durante o processo de login. A seguir, detalho o propósito e o funcionamento de cada parte deste serviço:

Estrutura AuthService
  • AuthService: Mantém uma referência ao UserStore, que permite acessar o banco de dados para operações relacionadas a usuários. Essa estrutura é usada para gerenciar operações de autenticação, como validar credenciais.
Função NewAuthService
  • NewAuthService: Função construtora que cria uma nova instância de AuthService, recebendo um UserStore como parâmetro. Esse UserStore é usado para interagir com os dados dos usuários no banco de dados.
Método ValidateCredentials
  • ValidateCredentials: Este é o método central do serviço de autenticação. Ele recebe credenciais (email e senha) como entrada e realiza as seguintes operações:
  • Busca do Usuário: Primeiro, tenta encontrar o usuário no banco de dados usando o email fornecido. Se o usuário não for encontrado, retorna um erro indicando que o usuário não existe.
  • Verificação da Senha: Se o usuário for encontrado, compara a senha fornecida com o hash da senha armazenado no banco de dados usando bcrypt.CompareHashAndPassword. Essa função é segura contra ataques de força bruta, pois implementa um custo computacional significativo para a comparação.
  • Resultado da Autenticação: Se a senha corresponder ao hash armazenado, o método retorna o usuário e nenhum erro, indicando que a autenticação foi bem-sucedida. Se a senha não corresponder, retorna um erro indicando que a senha está incorreta.
Considerações de Segurança
  • Hash de Senhas com bcrypt: O uso de bcrypt para armazenar e verificar as senhas é uma prática de segurança recomendada. bcrypt é projetado para ser lento e custoso computacionalmente, o que torna os ataques de força bruta impraticáveis.
  • Mensagens de Erro: As mensagens de erro específicas, como “usuário não encontrado” ou “senha incorreta”, podem fornecer pistas para atacantes. Em alguns contextos, pode ser preferível usar mensagens de erro genéricas para evitar a enumeração de contas. No entanto, mensagens específicas podem melhorar a experiência do usuário, ajudando-os a entender o que deu errado durante o processo de login. Como o objetivo deste projeto é de estudo e aprendizagem optei pela informação neste ponto.

Este serviço de autenticação é uma parte crucial da segurança da aplicação, garantindo que apenas usuários com credenciais válidas possam acessar recursos protegidos. Ao separar a lógica de autenticação em um serviço dedicado, facilita a manutenção e a potencial expansão das funcionalidades relacionadas à segurança no futuro.

Arquivo services/user_service.go

O arquivo user_service.go define o UserService, que encapsula a lógica de negócios relacionada à manipulação de usuários na aplicação. Este serviço atua como um intermediário entre a camada de acesso a dados (store) e o restante da aplicação, abstraindo detalhes específicos de implementação do banco de dados e validações. Segue alguns comentário das partes principais deste serviço:

Interface UserServiceInterface
  • UserServiceInterface: Define um contrato para as operações relacionadas a usuários que o UserService deve implementar. Isso inclui criar, buscar, atualizar, e deletar usuários, além de verificar a existência de um usuário administrador.
Estrutura UserService
  • store: Mantém uma referência à interface UserStorer, que é usada para interagir com o banco de dados e realizar operações CRUD em registros de usuários.
Métodos Implementados
  • NewUsuarioService: Função construtora que inicializa uma nova instância de UserService com a referência a uma implementação concreta de UserStorer.
  • CreateUser: Valida os dados de um novo usuário (como o formato do e-mail e a unicidade do e-mail no sistema) antes de tentar criá-lo no banco de dados. Também valida o papel do usuário utilizando utils.ValidateRole.
  • GetUser, GetAllUsers: Buscam usuários no banco de dados por ID ou retornam todos os usuários, respectivamente.
  • UpdateUser, UpdateUserPass: Atualizam os dados de um usuário existente e a senha do usuário, respectivamente. A atualização da senha inclui uma verificação da força da senha.
  • DeleteUser: Remove um usuário do banco de dados pelo ID.
  • CheckIfAdminExists: Verifica se existe pelo menos um usuário com o papel de administrador no sistema.
Considerações de Design e Práticas Recomendadas
  • Abstração e Encapsulamento: Ao abstrair as operações de banco de dados para trás de uma interface (UserStorer), o UserService permite flexibilidade na implementação da camada de acesso a dados e facilita testes unitários, pois dependências podem ser facilmente simuladas (mocked).
  • Validação de Entradas: A validação de e-mails e a verificação da força da senha são práticas importantes para garantir a integridade e segurança dos dados dos usuários.
  • Gestão de Erros: O serviço trata erros de maneira adequada, convertendo erros de baixo nível (como um e-mail já existente) em erros de alto nível mais úteis para a lógica de negócios da aplicação.
  • Segurança: A utilização de bcrypt para comparação de senhas no AuthService (mencionado anteriormente) e a avaliação da força da senha neste serviço são práticas recomendadas de segurança.
  • Melhoria Potencial: Para a função UpdateUserPass, após verificar a força da senha, o código simplesmente loga se a senha é fraca, mas não impede a atualização da senha. Isso pode ser parte de um FIXME para implementar uma lógica que efetivamente bloqueie a atualização se a senha não atender aos critérios de segurança em uma versão final deste produto. No entanto, serve ao objetivo central deste projeto.

Este serviço é crucial para gerenciar o ciclo de vida dos usuários na aplicação, desde a criação até a exclusão, garantindo que as operações sejam realizadas de forma segura e eficiente.

Arquivo services/menu_item_service.go

O arquivo menu_item_service.go define o MenuItemService, que encapsula a lógica de negócios para gerenciar operações relacionadas a itens de menu na aplicação. Este serviço serve como uma camada intermediária entre a camada de acesso a dados (store) e as funções de alto nível da aplicação, como endpoints da API ou interface de usuário. Segue abaixo detalhe das responsabilidades e implementações deste serviço:

Estrutura MenuItemService
  • store: Uma instância de store.MenuItemStorer, que fornece métodos para interagir com o banco de dados. Essa dependência é injetada no serviço através do construtor NewItemMenuService, permitindo que o serviço execute operações de banco de dados necessárias para gerenciar itens de menu.
Métodos Implementados
  • NewItemMenuService: Construtor que inicializa um novo MenuItemService com a implementação concreta de store.MenuItemStorer, permitindo realizar operações de banco de dados sobre itens de menu.
  • CreateMenuItem: Realiza a lógica de negócios necessária para criar um novo item de menu. Isso inclui verificar se já existe um item de menu com o mesmo nome para evitar duplicatas, antes de prosseguir com a criação do item no banco de dados.
  • GetMenuItem: Busca um item de menu pelo ID, retornando os detalhes do item especificado.
  • UpdateMenuItem: Atualiza os detalhes de um item de menu existente no banco de dados, como nome, descrição, preço e URL da imagem.
  • DeleteMenuItem: Remove um item de menu do banco de dados pelo ID.
  • GetAllMenuItem: Recupera todos os itens de menu do banco de dados, provavelmente para exibição em uma lista ou menu na interface da aplicação.
  • GetMenuItemByNome: Busca um item de menu pelo nome. Esta função é útil para operações que precisam verificar a existência de um item de menu baseado em seu nome, como validações durante a criação ou atualização de itens de menu.
Considerações de Design e Práticas Recomendadas
  • Validação e Gestão de Conflitos: A validação antes da criação de um novo item de menu ajuda a manter a integridade dos dados, evitando itens de menu duplicados.
  • Flexibilidade e Manutenção: A injeção da dependência store.MenuItemStorer no serviço permite flexibilidade na implementação do armazenamento de dados e facilita a manutenção e teste do serviço, pois diferentes implementações ou mocks podem ser injetados conforme necessário.
  • Cobertura Funcional: O serviço cobre um conjunto completo de operações CRUD para itens de menu, fornecendo uma interface robusta para a gestão de itens de menu na aplicação.

Este serviço é crucial para a gestão eficaz de itens de menu na aplicação, abstraindo a complexidade das operações de banco de dados e fornecendo uma interface clara e focada para manipulação desses itens.

Arquivo services/order_service.go

Este arquivo define o OrderService, responsável pelas operações relacionadas a pedidos na aplicação, como criar, atualizar, deletar e recuperar pedidos.

Estrutura OrderService
  • store: Mantém uma referência ao store.OrderStorer, permitindo ao serviço executar operações de banco de dados em pedidos.
Métodos Implementados
  • CreateOrder: Cria um novo pedido.
  • GetOrder: Recupera um pedido pelo ID.
  • UpdateOrder: Atualiza um pedido existente.
  • DeleteOrder: Remove um pedido pelo ID.
  • GetOrderByUser: Busca todos os pedidos feitos por um usuário específico.
  • GetPendingOrder: Retorna todos os pedidos pendentes (não entregues).
Considerações de Design e Práticas Recomendadas
  • A separação da lógica de negócios relativa a pedidos em um serviço dedicado promove a clareza do código e facilita a manutenção.

Arquivo services/item_order_service.go

Este arquivo define o ItemOrderService, que gerencia operações relacionadas a itens de pedidos, como adicionar novos itens a pedidos, atualizar, buscar por ID e remover itens de pedidos do banco de dados.

Estrutura ItemOrderService
  • store: Mantém uma referência a store.ItemOrderStorer, facilitando a interação com a camada de acesso a dados para realizar operações CRUD em itens de pedidos.
Métodos Implementados
  • CreateItemOrder: Adiciona um novo item de pedido ao banco de dados, encapsulando a lógica de negócios necessária para essa operação.
  • GetItemOrder: Busca um item de pedido específico pelo ID, oferecendo acesso direto a um item de pedido no banco de dados.
  • UpdateItemOrder: Atualiza os detalhes de um item de pedido existente, como quantidade ou comentários.
  • DeleteItemOrder: Remove um item de pedido do banco de dados pelo ID, tratando da lógica de negócios para a remoção segura de itens de pedidos.
Considerações de Design e Práticas Recomendadas
  • Abstração e Encapsulamento: A estrutura ItemOrderService abstrai a complexidade das operações de banco de dados relacionadas a itens de pedidos, oferecendo uma interface clara e simplificada para essas operações. Isso facilita a manutenção e a expansão futuras da aplicação.
  • Flexibilidade: A dependência da interface ItemOrderStorer permite que o serviço interaja com qualquer implementação concreta dessa interface, aumentando a flexibilidade e a testabilidade do serviço.
  • Coesão: Agrupar operações relacionadas a itens de pedidos em um serviço dedicado mantém o código coeso, organizado e focado em uma única responsabilidade. Isso melhora a legibilidade e facilita o entendimento da lógica de negócios relacionada a itens de pedidos na aplicação.

O ItemOrderService é essencial para o gerenciamento eficiente de itens de pedidos dentro do sistema, permitindo que a aplicação execute operações cruciais de maneira eficaz e segura, enquanto mantém a lógica de negócios claramente separada da camada de acesso a dados.

Diretório utils

Contém utilitários e funções auxiliares que podem ser usados em várias partes da aplicação:

Arquivo utils/constants.go

Arquivo utils/constants.go

Este arquivo define constantes para representar métodos HTTP na aplicação, facilitando a referência a esses métodos de maneira tipada e segura em outras partes do código.

Tipo HttpMethod
  • Define um tipo HttpMethod como string para representar os métodos HTTP como uma enumeração.
Constantes
  • HttpMethodGet: Representa o método HTTP GET.
  • HttpMethodPost: Representa o método HTTP POST.
  • HttpMethodPut: Representa o método HTTP PUT.
  • HttpMethodDelete: Representa o método HTTP DELETE.
Considerações de Design e Práticas Recomendadas
  • O uso de constantes tipadas para métodos HTTP melhora a legibilidade e a segurança do código, prevenindo erros com strings literais dispersas.
  • A definição de tipos e constantes em utils/constants.go centraliza configurações comuns e facilita a manutenção e o reuso em diferentes partes da aplicação.

Arquivo utils/generic_functions.go

utils/generic_functions.go

Este arquivo contém uma coleção de funções utilitárias que oferecem suporte a várias operações comuns e validações em toda a aplicação.

Funções Implementadas

  • GenerateRandomPassword: Gera uma senha aleatória de comprimento especificado, contendo caracteres alfanuméricos e símbolos especiais. A função garante que a senha gerada atenda a um critério mínimo de força antes de retorná-la.
  • TrimSpaceLB: Remove espaços em branco e quebras de linha do início e do fim de uma string.
  • IPCheck: Retorna o endereço IP da primeira interface de rede não-local encontrada na máquina. Útil para determinar o endereço IP em ambientes com múltiplas interfaces de rede.
  • ValidateEmail: Valida se uma string é um endereço de e-mail bem-formado, utilizando expressões regulares.
  • ValidateRole: Verifica se o e-mail fornecido segue um padrão específico que implica um determinado papel (role) do usuário, como um cliente associado a uma mesa.

Estrutura PasswordStrength e Função de Avaliação

  • PasswordStrength: Uma estrutura que contém detalhes sobre a força de uma senha, incluindo uma pontuação geral e indicadores de presença de números, letras maiúsculas e minúsculas, símbolos e comprimento adequado.
  • EvaluatePasswordStrength: Avalia a força de uma senha com base em critérios predefinidos, como a presença de diferentes tipos de caracteres e o comprimento da senha, retornando uma instância de PasswordStrength.

Considerações de Design e Práticas Recomendadas

  • Expressões Regulares para Validação: O uso de expressões regulares para validar e-mails e outros padrões de string é uma prática comum que ajuda a garantir que os dados atendam a formatos específicos.
  • Geração Segura de Senhas: A função GenerateRandomPassword utiliza crypto/rand para a geração de senhas, o que é recomendado para segurança, pois fornece números aleatórios criptograficamente seguros.
  • Validação de Entrada de Usuário: Funções como ValidateEmail e ValidateRole são essenciais para garantir que a entrada do usuário atenda a certos critérios antes de ser processada ou armazenada, ajudando a prevenir erros e vulnerabilidades de segurança.
  • Flexibilidade e Reusabilidade: A separação de funções utilitárias comuns em um arquivo dedicado promove a reusabilidade e a manutenção do código, permitindo que essas funções sejam facilmente utilizadas em várias partes da aplicação.

Este arquivo utils/generic_functions.go serve como um recurso centralizado para operações utilitárias, validações e geração de dados, apoiando a aplicação com funções reutilizáveis e confiáveis.

Arquivo utils/database_functions.go

utils/database_functions.go

Este arquivo é responsável por estabelecer uma conexão com o banco de dados, solicitando ao usuário as credenciais necessárias e utilizando essas informações para tentar uma conexão.

Funções Implementadas
  • CreateDataBaseConn: Solicita ao usuário o nome e a senha para acessar o banco de dados e, em seguida, tenta estabelecer uma conexão com o banco de dados utilizando essas credenciais. A função repete o processo até que uma conexão bem-sucedida seja estabelecida ou o usuário interrompa o processo.
Considerações de Design e Práticas Recomendadas
  • Interatividade com o Usuário: A função interage diretamente com o usuário através do terminal para obter as credenciais do banco de dados, o que pode ser útil em cenários onde as credenciais não estão pré-configuradas ou em ferramentas de linha de comando que requerem configuração manual pelo usuário.
  • Segurança da Senha: Utiliza term.ReadPassword para ler a senha do usuário sem exibi-la na tela, aumentando a segurança ao evitar que a senha seja visível ou armazenada em logs.
  • Validação de Conexão: Antes de concluir a configuração da conexão, a função verifica se a conexão com o banco de dados é bem-sucedida, garantindo que as credenciais fornecidas sejam válidas e que o banco de dados esteja acessível.
  • Loop de Tentativas: Em caso de falha na conexão, a função informa o usuário e repete o processo de solicitação de credenciais, permitindo múltiplas tentativas sem necessidade de reiniciar o aplicativo.
  • Log de Erros: Os erros encontrados durante o processo de conexão são registrados, fornecendo feedback útil para diagnóstico e correção de problemas de conexão.

Esta abordagem de configuração da conexão com o banco de dados é particularmente simplista para aplicação aqui proposta.

Diretório handlers

Contém os manipuladores de requisições HTTP (handlers) para diferentes partes da API. Cada arquivo define endpoints relacionados a uma funcionalidade específica da aplicação.

Arquivo handlers/auth.go

Este arquivo define o AuthHandler, responsável por gerenciar as requisições de autenticação na aplicação, incluindo a validação de credenciais e a geração de tokens JWT para usuários autenticados.

Estrutura AuthHandler
  • Service: Mantém uma referência ao AuthService, que é utilizado para validar as credenciais dos usuários.
Método Implementado
  • NewAuthHandler: Cria uma nova instância de AuthHandler, inicializando-a com uma referência ao AuthService.
  • LoginHandlers: Lida com as requisições de login. Decodifica as credenciais enviadas pelo usuário, valida essas credenciais utilizando o AuthService, gera um token JWT se as credenciais forem válidas, e retorna o token junto com informações básicas do usuário em caso de sucesso. Em caso de falha na validação das credenciais ou erro na geração do token, retorna uma resposta de erro adequada.
Considerações de Design e Práticas Recomendadas
  • Validação de Credenciais: A separação da lógica de validação de credenciais no AuthService permite reutilizar essa funcionalidade em diferentes partes da aplicação, mantendo o princípio DRY (Don’t Repeat Yourself).
  • Uso de JWT para Autenticação: A geração de tokens JWT é uma prática comum para sistemas de autenticação em aplicações web e móveis, proporcionando um método seguro e eficiente para gerenciar sessões de usuário.
  • Tratamento de Erros: O manipulador de login cuidadosamente captura e trata diferentes tipos de erros, como erro de decodificação de credenciais e falha na validação, e retorna respostas HTTP apropriadas para cada caso, melhorando a experiência do usuário final.
  • Log de Atividades: Os logs de atividades fornecem insights valiosos durante o desenvolvimento e a depuração, além de serem úteis para monitoramento e análise em produção.
  • Segurança do Token: A chave secreta usada para assinar os tokens JWT está esposta no código. No entanto, a proposta deste projeto é estudo e não vou trabalhar este ponto aqui. De uma forma geral o aconselhável é manter esta chave em segurança e não exposta no código ou em repositórios públicos. Idealmente, ela deve ser armazenada em variáveis de ambiente ou em serviços de gerenciamento de chaves.

Este handler desempenha um papel crucial na segurança da aplicação, assegurando que apenas usuários autenticados possam acessar recursos protegidos.

Arquivo handlers/middleware.go

O arquivo middleware.go desempenha um papel fundamental na segurança e autorização da aplicação, implementando a lógica de middleware para verificar a presença e validade de tokens JWT em requisições HTTP. Além disso, ele contém lógicas específicas para controlar o acesso a diferentes partes da aplicação com base nos papéis dos usuários. Abaixo, exploro os aspectos principais deste arquivo:

Função Principal: AuthMiddleware
  • Objetivo: O AuthMiddleware é uma função que cria um middleware HTTP responsável por interceptar todas as requisições e validar o token JWT presente no cabeçalho Authorization. Esse processo é essencial para garantir que apenas usuários autenticados e autorizados possam acessar recursos protegidos na aplicação.
  • Processo de Validação:
    • Extrai o token JWT do cabeçalho Authorization.
    • Valida o formato do cabeçalho para assegurar que segue o padrão “Bearer “.
    • Decodifica e verifica o token usando a chave secreta definida (secretKey).
    • Extrai o papel (role) do usuário do token e realiza verificações de autorização baseadas nesse papel.
  • Autorização Baseada em Papéis:
    • Implementa uma verificação de permissões, onde o acesso a determinadas rotas é controlado com base no papel do usuário. Isso é feito comparando o papel extraído do token com as permissões definidas para a rota e o método HTTP específicos.
    • Utiliza duas abordagens para definir permissões: rotas estáticas e rotas dinâmicas, permitindo uma configuração detalhada de quem pode acessar o quê na aplicação.
Estruturas de Permissões
  • staticsPermissions: Define um mapa de permissões para rotas estáticas, onde as chaves são caminhos de URL específicos e os valores são mapas dos métodos HTTP permitidos para cada papel de usuário. Isso permite um controle granular sobre quem pode realizar ações como GET, POST, PUT e DELETE em endpoints específicos.
  • dynamicPermissions: Lista permissões para rotas dinâmicas usando expressões regulares para combinar padrões de URL. Cada entrada define métodos HTTP e os papéis de usuários permitidos para essas rotas, oferecendo flexibilidade para autorizar o acesso a recursos que incluem identificadores ou outros parâmetros variáveis nos caminhos de URL.
Considerações de Design e Segurança
  • Uso de JWT: A utilização de JSON Web Tokens (JWT) para autenticação e autorização é uma prática comum em aplicações web modernas, oferecendo um método seguro e eficiente para gerenciar sessões de usuário e controlar o acesso a recursos.
  • Chave Secreta: A chave secreta (secretKey) usada para assinar tokens deve ser mantida em segurança, idealmente armazenada em um cofre de senhas ou injetada na aplicação através de variáveis de ambiente seguras. Isso garante que apenas a aplicação possa gerar e validar tokens JWT. Este procedimento não está sendo empregado aqui, conforme mencionado anteriormente.
  • Verificação de Papéis: O sistema de controle de acesso baseado em papéis permite uma gestão flexível e segura de permissões na aplicação, garantindo que os usuários possam acessar apenas os recursos adequados ao seu nível de autorização.

Este arquivo é um componente crucial para manter a segurança da aplicação, assegurando que apenas usuários autenticados e com as devidas permissões possam acessar recursos sensíveis ou realizar operações críticas.

Arquivo handlers/user_handler.go

O arquivo user_handler.go contém o UserHandler, que é responsável por gerenciar as requisições HTTP relacionadas a usuários na aplicação. Ele interage com o UserService para executar operações como criar, buscar, atualizar e deletar usuários. Aqui está um resumo detalhado das funcionalidades e práticas implementadas neste arquivo:

Estrutura UserHandler
  • Mantém uma referência ao UserService, permitindo que o manipulador acesse os serviços necessários para processar as requisições de usuários.
Métodos Implementados
  • NewUserHandler: Cria uma nova instância de UserHandler, configurando-a com o serviço necessário para operações de usuário.
  • CreateUser: Lida com requisições POST para adicionar um novo usuário. Decodifica o corpo da requisição para um objeto User, valida as credenciais e, se válido, chama o serviço para criar o usuário no banco de dados. Retorna o usuário criado ou um erro em caso de falha.
  • GetUser: Gerencia requisições GET para buscar um usuário pelo ID. Utiliza o ID fornecido na URL para buscar o usuário correspondente e retorna os dados do usuário (excluindo a hash da senha) ou um erro se não encontrado.
  • GetAllUsers: Trata requisições GET para listar todos os usuários. Recupera uma lista de todos os usuários do banco de dados, limpa a hash da senha de cada usuário para proteger informações confidenciais e retorna a lista.
  • UpdateUser: Lida com requisições PUT para atualizar um usuário existente. Decodifica o usuário do corpo da requisição e chama o serviço para atualizar os dados do usuário no banco de dados.
  • UpdateUserPass: Gerencia requisições PUT específicas para atualizar a senha de um usuário. Extraí a nova senha do corpo da requisição e atualiza a senha do usuário especificado.
  • DeleteUser: Lida com requisições DELETE para remover um usuário pelo ID. Usa o ID fornecido na URL para excluir o usuário correspondente do banco de dados.
Práticas de Segurança e Design
  • Segurança de Dados: Ao tratar as informações do usuário, especialmente ao retornar dados do usuário em respostas, o UserHandler garante que a hash da senha nunca seja exposta, aumentando a segurança da aplicação.
  • Validação de Entrada: Antes de processar as operações, o UserHandler valida a entrada para garantir que os dados sejam adequados para a operação solicitada, como verificar se o ID é um número válido e se o corpo da requisição contém os dados necessários.
  • Tratamento de Erros: O manipulador loga e retorna erros de maneira adequada, garantindo que os clientes da API recebam feedback claro sobre o sucesso ou falha de suas requisições.
  • Cabeçalhos de Resposta HTTP: Configura devidamente os cabeçalhos das respostas, como Content-Type, e o status HTTP, facilitando a integração com clientes da API que dependem desses cabeçalhos para processar as respostas corretamente.

Este manipulador desempenha um papel crucial na interface da aplicação com os usuários finais, gerenciando como as requisições de usuários são recebidas, processadas e respondidas, assegurando que a interação do usuário com o sistema seja segura, eficiente e de acordo com as regras de negócio estabelecidas.

Arquivo handlers/menu_item_handler.go

O arquivo menu_item_handler.go implementa manipuladores HTTP específicos para gerenciar as operações CRUD relacionadas a itens do menu na aplicação. Cada função manipuladora interage com a camada de serviços para executar a lógica de negócios necessária e responder às requisições HTTP. Segue uma visão detalhada dessas funcionalidades:

Estrutura MenuItemHandler
  • Service: Mantém uma referência ao MenuItemService, permitindo que o manipulador acesse e execute operações relacionadas a itens do menu.
Métodos Implementados
  • NewMenuItemHandler: Construtor que cria uma nova instância de MenuItemHandler, inicializando-a com o serviço necessário para operações de itens do menu.
  • CreateMenuItem: Processa requisições POST para adicionar um novo item ao menu. Decodifica o corpo da requisição para extrair os dados do item e, em seguida, utiliza o serviço para criar o item no banco de dados.
  • GetMenuItem: Atende requisições GET para buscar um item do menu por ID. Utiliza o mux.Vars para extrair o ID do item da URL e busca o item correspondente através do serviço.
  • GetAllMenuItem: Processa requisições GET para listar todos os itens do menu. Busca todos os itens disponíveis através do serviço e retorna a lista ao cliente.
  • GetMenuItemByName: Atende requisições GET para buscar um item do menu pelo nome. Extrai o nome do item da URL e busca o item correspondente através do serviço.
  • UpdateMenuItem: Gerencia requisições PUT para atualizar um item do menu existente. Decodifica o corpo da requisição para obter os novos dados do item e solicita a atualização ao serviço.
  • DeleteMenuItem: Atende a requisições DELETE para remover um item do menu pelo ID. Extrai o ID do item da URL e solicita a remoção ao serviço.
Considerações de Design e Práticas Recomendadas
  • Separação de Preocupações: Ao delegar a lógica de negócios ao serviço (MenuItemService), os manipuladores mantêm-se focados em tratar as interações HTTP, promovendo uma arquitetura limpa e modular.
  • Tratamento de Erros: O código verifica erros em várias etapas, desde a decodificação do corpo da requisição até a execução das operações solicitadas, respondendo com códigos de status HTTP apropriados para diferentes situações de erro.
  • Content-Type JSON: Todos os manipuladores definem o cabeçalho Content-Type como application/json nas respostas, garantindo que o cliente saiba que está recebendo um payload JSON.

Estes manipuladores são essenciais para a funcionalidade da aplicação, permitindo que usuários e sistemas interajam com a base de dados de itens do menu através de uma interface HTTP clara e bem definida.

Arquivo handlers/order_handler.go

O arquivo order_handler.go estabelece a ponte entre as requisições HTTP relacionadas a pedidos e a camada de serviços, permitindo a execução de operações CRUD sobre os pedidos dentro da aplicação. Utilizando o framework gorilla/mux para roteamento e extração de parâmetros das URLs, este manipulador define métodos específicos para lidar com diferentes tipos de requisições HTTP associadas aos pedidos.

Estrutura OrderHandler
  • Service: Uma referência ao OrderService, que fornece acesso aos métodos necessários para interagir com os dados dos pedidos.
Métodos Implementados
  • NewOrderHandler: Função construtora que inicializa um novo OrderHandler com uma referência a OrderService.
  • CreateOrder: Lida com requisições POST, decodificando o corpo da requisição para um objeto Order e chamando o serviço para criar um novo pedido no sistema.
  • GetOrder: Atende requisições GET para buscar um pedido específico pelo ID, usando o OrderService para recuperar os dados do pedido e enviá-los na resposta.
  • GetOrderByUser: Lida com requisições GET para buscar todos os pedidos associados a um usuário específico, identificado pelo usuarioId.
  • GetPendingOrder: Processa requisições GET para buscar todos os pedidos pendentes, sem especificar um usuário, e retorna a lista de pedidos que ainda não foram concluídos.
  • UpdateOrder: Processa requisições PUT para atualizar um pedido existente, decodificando os dados do pedido atualizados do corpo da requisição e utilizando o serviço para aplicar as mudanças.
  • DeleteOrder: Gerencia requisições DELETE para remover um pedido pelo ID, chamando o serviço correspondente para realizar a operação.
Práticas de Design e Considerações
  • Separação de Preocupações: Mantendo a lógica de negócios no OrderService, o OrderHandler foca exclusivamente na recepção de requisições HTTP, tratamento de dados de entrada/saída e comunicação com o cliente, seguindo boas práticas de arquitetura de software.
  • Tratamento de Erros: O manipulador verifica e trata erros em várias etapas, desde a decodificação do corpo da requisição até a execução das operações solicitadas, respondendo com códigos de status HTTP apropriados para facilitar a identificação de problemas pelos clientes.
  • Uso do gorilla/mux: A utilização deste pacote facilita o roteamento e a extração de parâmetros das URLs, permitindo uma manipulação mais limpa e eficiente das requisições.

Este conjunto de manipuladores fornece a infraestrutura necessária para a gestão eficaz dos pedidos na aplicação, oferecendo aos usuários a capacidade de criar, atualizar, visualizar e deletar pedidos de maneira controlada e segura.

Arquivo handlers/item_order_handler.go

O arquivo item_order_handler.go é responsável por lidar com as requisições HTTP específicas para operações CRUD em ItemPedido, os itens individuais de um pedido dentro da aplicação. Utilizando o pacote gorilla/mux para roteamento e o serviço ItemOrderService para a lógica de negócios, este manipulador facilita a interação entre a interface do usuário e a persistência de dados no banco de dados.

Estrutura ItemOrderHandler
  • Service: Uma referência ao ItemOrderService, que oferece os métodos necessários para interagir com os dados de itens de pedidos.
Métodos Implementados
  • NewItemOrderHandler: Construtor que inicializa uma nova instância de ItemOrderHandler, configurando-a com o serviço necessário para operações de item de pedido.
  • CreateItemOrder: Processa requisições POST para criar um novo ItemPedido. Decodifica o corpo da requisição para um objeto ItemOrder e chama o serviço para adicionar o item ao banco de dados.
  • GetIItemOrder: Atende requisições GET para buscar um ItemPedido pelo ID. Extrai o ID do item da URL e utiliza o serviço para recuperar e retornar os dados do item pedido.
  • UpdateItemOrder: Gerencia requisições PUT para atualizar um ItemPedido existente. Decodifica os novos dados do item do corpo da requisição e solicita a atualização ao serviço.
  • DeleteItemOrder: Lida com requisições DELETE para remover um ItemPedido pelo ID. Extrai o ID do item da URL e chama o serviço para realizar a remoção.
Práticas de Design e Considerações
  • Separação de Preocupações: Ao delegar responsabilidades específicas de manipulação de dados ao ItemOrderService, os manipuladores se concentram em tratar as requisições e respostas HTTP, mantendo o código organizado e modular.
  • Tratamento de Erros: O manipulador verifica erros em todas as etapas do processo, desde a decodificação do corpo da requisição até a execução das operações de banco de dados, garantindo que respostas apropriadas sejam enviadas para diferentes tipos de falhas.
  • Transparência na Comunicação: Ao definir o Content-Type como application/json e enviar códigos de status HTTP adequados, o manipulador facilita a interpretação das respostas pelo cliente, promovendo uma interface de comunicação clara.

Este conjunto de manipuladores fornece a infraestrutura necessária para a gestão de itens de pedidos na aplicação, permitindo que os usuários interajam de maneira eficaz com a funcionalidade de pedidos, seja adicionando itens a um pedido, atualizando informações de itens, ou removendo itens de pedidos existentes.

Diretório bootstrap

Arquivo bootstrap.go

O arquivo bootstrap/bootstrap.go desempenha um papel crucial na inicialização e configuração inicial da aplicação, especialmente em termos de configuração de rotas e verificação da existência de usuários administrativos no sistema. Aqui está um resumo detalhado das funcionalidades e abordagens adotadas neste arquivo:

Função SetupRouter

Esta função é o coração da configuração do roteamento da aplicação, utilizando o mux.Router do pacote gorilla/mux para definir as rotas e associá-las a manipuladores específicos. A função realiza as seguintes ações principais:

  • Inicialização dos Stores: Cria instâncias dos stores necessários para interagir com o banco de dados, como userStore, menuItemStore, orderStore e itemOrderStore.
  • Inicialização dos Serviços: Inicializa os serviços que encapsulam a lógica de negócios da aplicação, utilizando os stores previamente criados.
  • Inicialização dos Manipuladores: Configura os manipuladores para as diferentes entidades da aplicação (UserHandler, AuthHandler, MenuItemHandler, OrderHandler, ItemOrderHandler), passando os serviços correspondentes.
  • Configuração das Rotas: Define as rotas públicas e privadas, aplicando middleware de autenticação nas rotas privadas para garantir que apenas usuários autenticados e autorizados possam acessá-las.
Função CheckAndCreateAdminUser

Esta função verifica a presença de um usuário administrador no sistema e, caso não exista, guia o usuário através do processo de criação de uma conta administrativa. Este processo inclui:

  • Verificação da Existência do Usuário Administrador: Utiliza o UserService para verificar se já existe um usuário com o papel de administrador no sistema.
  • Criação do Usuário Administrador: Caso não exista, a função solicita ao usuário que forneça as informações necessárias (nome, e-mail e senha) para criar uma nova conta administrativa. A senha é verificada quanto à sua força e, se aprovada, o usuário é criado no sistema.
Considerações de Design e Segurança
  • Separação de Responsabilidades: Ao modularizar a configuração das rotas e a verificação da conta administrativa, o arquivo bootstrap.go mantém uma separação clara de responsabilidades, facilitando a manutenção e a compreensão do código.
  • Segurança do Usuário Administrador: A criação de uma conta administrativa é um passo crítico para a segurança da aplicação. A função CheckAndCreateAdminUser assegura que o sistema sempre tenha pelo menos um usuário com capacidade de administração, evitando bloqueios acidentais ou perda de acesso administrativo.
  • Uso de Middleware de Autenticação: A aplicação do middleware de autenticação nas rotas privadas é uma prática de segurança essencial, garantindo que operações sensíveis sejam protegidas contra acessos não autorizados.

Em suma, bootstrap/bootstrap.go estabelece a fundação para a configuração inicial da aplicação, assegurando que a estrutura de roteamento esteja corretamente definida e que medidas de segurança iniciais, como a presença de um usuário administrador, estejam em vigor.

Arquivo main.go

O ponto de entrada da aplicação, onde a função main é definida. Este arquivo inicia o servidor web e chama o bootstrap para configurar a aplicação.

Cada componente dessa estrutura desempenha um papel essencial no desenvolvimento da aplicação GoLang com foco em um projeto limpo, organizado e de fácil manutenção. A separação clara entre lógica de negócios, manipulação de requisições, modelos de dados e acesso ao banco de dados ajuda a manter o código modular e facilita a implementação de novas funcionalidades e a manutenção do código existente.

Conclusão

Este sistema exemplifica uma aplicação RESTful robusta, com um design que enfatiza a clareza, a segurança e a modularidade. Através da separação de responsabilidades e da adoção de padrões de projeto comprovados, a aplicação estabelece uma fundação sólida para o desenvolvimento de funcionalidades adicionais e a adaptação a novos requisitos no futuro.