Closed FlightofIcarus closed 7 months ago
A linguagem escolhida para o desenvolvimento da API foi a JavaScript, pois além de ser uma linguagem bastante atual, sua integração com o ambiente de execução Node.js é nativo, não precisando de módulos específicos para a execução, nem que o código seja buildado antes da execução, o que acelera a produção do nosso MVP, de forma a termos uma API funcional já em pouco tempo. Além disso, esta linguagem acrescenta um bom nível de simplicidade de codificação, sendo amplamente conhecida por todos da equipe, que a veem inclusive como uma ótima ferramenta para prototipagem rápida, por ter um vasto ecossistema e uma comunidade bastante ativa.
Como escolhemos a linguagem JavaScript, decidimos usar o paradigma funcional pois ele tem uma ótima integração com o próprio JavaScript. Além disso, reconhecemos que, embora seja possível aplicar conceitos de orientação a objetos em JavaScript puro, TypeScript oferece ferramentas mais precisas e aconselháveis para POO, como o sistema de tipos estáticos que facilita a injeção e inversão de dependências. Além do ponto de conseguir extrair o máximo do paradigma com a linguagem, este paradigma nos facilita trabalhar com paralelismo e assincronicidade, usando promises, por exemplo, para processamentos paralelos de itens não diretamente dependentes. Outro ponto que fortalece a decisão do paradigma, é a maior velocidade e facilidade de construção do código. Além disso, nossa estratégia de testes incluirá testes unitários para garantir as partes micros do código. A natureza das funções puras facilita a escrita desses testes e ajuda a garantir a qualidade do código. Finalmente, reconhecemos a importância de considerar as habilidades da equipe ao escolher um paradigma de programação. Dado o conhecimento prévio e a experiência da equipe com o paradigma funcional, acreditamos que essa escolha seja adequada para o sucesso do projeto.
Optamos por adotar a arquitetura MVC para o desenvolvimento da nossa API REST, tendo em vista uma série de vantagens que esta estrutura proporciona. Da mesma forma que escolhemos a linguagem JavaScript e o paradigma funcional por sua excelente integração e adequação ao próprio JavaScript, reconhecemos que o MVC oferece uma organização clara e uma separação distinta de responsabilidades. O MVC nos permite uma divisão nítida entre modelos, controladores e rotas, facilitando a manutenção e a escalabilidade do código. Além disso, assim como o paradigma funcional nos permite tirar o máximo proveito das características da linguagem, a estrutura MVC nos facilita trabalhar com paralelismo e assincronicidade, elementos essenciais em aplicações REST, por meio de práticas como o uso de middlewares e serviços. A capacidade de lidar com múltiplas requisições de forma eficiente é crucial em ambientes de API, e o padrão MVC nos oferece uma base sólida para implementar essa funcionalidade de forma organizada e eficaz. Outro ponto a ser considerado é a maior velocidade e facilidade de construção do código proporcionada pelo MVC. Com uma estrutura bem definida, nossa equipe poderá desenvolver e modificar partes da aplicação de forma independente, promovendo a reutilização de código e reduzindo a duplicação. Além disso, nossa estratégia de testes incluirá testes unitários para garantir a qualidade do código, e a clareza e simplicidade da arquitetura MVC facilitarão a escrita e execução desses testes. Por fim, assim como consideramos as habilidades da equipe ao escolher o paradigma de programação, reconhecemos a importância de uma arquitetura que seja familiar e adequada ao conhecimento prévio dos desenvolvedores. Dada a experiência da equipe com o padrão MVC e sua eficácia comprovada em aplicações REST, acreditamos que essa escolha seja a mais adequada para o sucesso do projeto e para o desenvolvimento de uma API robusta e de alta qualidade.
Com base nas justificativas anteriores e considerando que todas elas são aplicáveis ao mesmo projeto, optamos por utilizar o GitFlow como nosso modelo de fluxo de trabalho para controle de versão. Assim como escolhemos a arquitetura MVC por sua clareza, separação de responsabilidades e facilidade de manutenção, o GitFlow nos oferece uma estrutura organizada e padronizada para gerenciar o desenvolvimento de recursos em equipe. Assim como o MVC nos permite desenvolver e modificar partes da aplicação de forma independente, o GitFlow nos possibilita trabalhar com múltiplos membros da equipe desenvolvendo funcionalidades diferentes de maneira isolada e simultânea. Com a criação de branches de feature para cada funcionalidade em desenvolvimento, garantimos que cada membro da equipe possa trabalhar em sua área sem interferir no trabalho dos outros. Além disso, seguindo o GitFlow, todas as alterações são integradas e testadas na branch de desenvolvimento (development) antes de serem mescladas na branch principal (main), garantindo a integridade e a estabilidade do código como um todo. Isso está alinhado com nossa estratégia de testes, que inclui testes unitários para garantir a qualidade do código.
Guia a ser seguido:
• A branch development(Dev) é onde seguiremos o fluxo de desenvolvimento, verificando cada nova feature criada para garantir que o funcionamento, a qualidade do código e a integração com o que já foi produzido está ok.
• Para cada nova feature a ser trabalhada(verificar tasks do projeto), uma branch de feature será criada para que o desenvolvimento não tenha impacto sobre o código base ou sobre o que outros devs já estão desenvolvendo. Após finalizada a feature, uma PR para Dev precisa ser aberta para avaliação e aprovação.
• A branch main terá apenas código finalizado e funcional, sendo o repositório onde ficará a aplicação pronta para realease.
• O padrão para a criação de novas branchs de features será feat/nome-da-feature/task
Considerando todas as decisões e justificativas feitas até o momento para o nosso projeto, optamos por adotar os Conventional Commits como nossa convenção padrão para mensagens de commit. Assim como escolhemos a arquitetura MVC pela sua clareza e organização, e o GitFlow pelo seu modelo estruturado e padronizado de controle de versão, os Conventional Commits nos oferecem uma maneira consistente e semântica de documentar as mudanças em nosso código. Ao utilizar os Conventional Commits, cada mensagem de commit segue um formato predefinido que inclui um prefixo indicando o tipo de mudança (como "feat" para novas funcionalidades, "fix" para correções de bugs, "chore" para tarefas de manutenção, entre outros), seguido por uma descrição concisa e clara da alteração realizada. Isso proporciona uma comunicação eficaz entre os membros da equipe e facilita a compreensão do histórico de alterações do projeto. Assim como a estrutura MVC nos ajuda a manter uma separação clara de responsabilidades em nosso código, os Conventional Commits nos ajudam a manter uma estrutura clara e consistente em nossos registros de alterações. Isso é especialmente útil ao trabalhar em equipe, pois permite que todos os membros entendam rapidamente o propósito e o impacto de cada alteração no código.
Optamos por utilizar um banco de dados relacional em nossa aplicação devido à natureza estruturada e claramente definida dos nossos dados, que se encaixam bem no modelo de tabelas e relacionamentos típicos dos bancos SQL. Ao optar por um banco de dados relacional, garantimos a consistência dos dados e a integridade referencial, elementos essenciais para a estabilidade e confiabilidade da nossa aplicação. Além disso, os bancos de dados relacionais oferecem a capacidade de realizar consultas complexas envolvendo múltiplas tabelas de forma eficiente, o que é crucial para atender às demandas de análise e manipulação de dados do nosso projeto. Comparativamente, os bancos de dados NoSQL são mais adequados para cenários onde a estrutura dos dados é flexível e as relações entre as entidades são menos definidas, o que não corresponde às características da nossa aplicação, onde a consistência e a estruturação dos dados são prioritárias.
Escolhemos o MySQL para nossa aplicação devido à sua ampla adoção e confiabilidade como um dos bancos de dados relacionais mais utilizados no mundo. Sua versão gratuita atende completamente às nossas necessidades, oferecendo uma sólida base de recursos e funcionalidades. Além disso, como produto da Oracle, podemos contar com suporte robusto tanto da comunidade de usuários quanto da própria empresa mantenedora, o que nos proporciona acesso a documentação detalhada e recursos de suporte adicionais, se necessário. A familiaridade da equipe com o MySQL também é um ponto forte, acelerando o desenvolvimento e a configuração do sistema, enquanto a integração facilitada com a infraestrutura OCI (Oracle Cloud Infrastructure) oferece flexibilidade adicional para futuras necessidades de escalabilidade e migração. Esses fatores combinados tornam o MySQL uma escolha altamente pertinente e vantajosa para o nosso projeto.
Além do fato de que o Sequelize foi estudado por todos durante o bootcamp, tornando todos os membros proficientes no uso deste ORM, temos como vantagens sua facilidade de manipulação de bancos de dados. Este ORM é bastante popular, estando já há bastante tempo no mercado, o que agrega a ele maturidade e estabilidade, questões interessantes para garantir a integridade da nossa API. Além disso, tem uma boa documentação, uma comunidade bastante presente e participativa, o que facilita encontrar soluções para possíveis problemas, tem também compatibilidade com diferentes tipos de bancos de dados, então caso precisemos escolher um novo, ele consegue se adequar facilmente.
Optamos por adotar a prática de "Nomeação descritiva, clara e sempre em inglês" para funções e variáveis em nosso código, em conformidade com os princípios do Clean Code. Essa abordagem oferece uma série de benefícios significativos para o desenvolvimento e manutenção do nosso projeto. Primeiramente, a padronização dos nomes das variáveis e funções em inglês facilita a colaboração entre os membros da equipe, garantindo que todos possam entender e contribuir para o código de forma consistente. Além disso, nomes descritivos e claros tornam o código mais legível e compreensível, permitindo que outros desenvolvedores e até mesmo nós mesmos possamos entender facilmente a finalidade e o propósito de cada parte do código apenas ao ler seus nomes. Essa clareza na nomenclatura também ajuda na identificação e correção de possíveis erros ou problemas, agilizando o processo de depuração e manutenção do código ao longo do tempo.
Exemplo de nome descritivo, claro e em inglês: function sumOfTwoValues(numberOneToSum. numberTwoToSum){...}
Definir parâmetros técnicos de ferramentas, tecnologias, pattners, etc.
• Linguagem • Paradigma • Arquitetura • Fluxo de trabalho • Pattern de commits • Tipo de banco de dados • Banco de dados • ORM (Object Relational Mapper) • Padrão de nomenclatura de variáveis e funções • Ferramentas de desenvolvimento • Módulos/Dependências