# Metodologia Twelve-Factor App

Twelve-Factor App é uma metodologia usada para a construção de aplicações SaaS (software como serviço). A metodologia fornece doze práticas definidas para permitir que aplicações possam ser construídas visando portabilidade e resiliência quando implantadas na web.

## História

A primeira empresa que entrou de cabeça no território de nuvem pública foi a Heroku. Ele entregava tudo que é preciso para criar um aplicativo e enviá-lo pelo Git, e então a nuvem assumiu o controle e o aplicativo passou a funcionar on-line.
A promessa de Heroku era que você não precisava mais se preocupar com infraestrutura, tudo o que era preciso fazer era criar um aplicativo para que aproveitasse a nuvem, e tudo ficaria bem.
O maior problema era que as pessoas praticamente não tinham ideia de como desenvolver aplicativos de uma maneira que fosse fácil de integrar com a nuvem. Os aplicativos amigáveis à nuvem não são executados apenas na nuvem, eles adotam escalabilidade flexível e tratam tudo como um serviço. Os aplicativos criados dessa maneira podem ser implantados de forma otimizada, permitindo que suas equipes de desenvolvimento adicionem novos módulos e reajam rapidamente às alterações pedidas.
Os primeiros a tentarem usar não sabiam o que podiam e o que não podiam fazer com as nuvens, nem conheciam as considerações de design e arquitetura envolvidas na criação de um aplicativo destinado à nuvem. Esta foi uma nova geração de aplicações, uma para a qual poucas pessoas podiam ser usadas como referência.
Para resolver esse problema, um grupo de pessoas dentro da Heroku desenvolveu os 12 fatores em 2012. Este é essencialmente um manifesto descrevendo as regras e diretrizes que precisavam ser seguidas para construir um aplicativo nativo na nuvem. O objetivo desses 12 fatores era ensinar aos desenvolvedores como criar aplicativos prontos para a nuvem que tinham formatos declarativos para automação e configuração, tinham um contrato limpo com o sistema operacional subjacente e eram dinamicamente escalonáveis.
O 12 Factors forneceu um ótimo ponto de partida, um critério para manter os aplicativos adequados a nuvem. Corretamente seguindo um fator torna mais fácil seguir outro, e assim por diante, ao longo de um ciclo virtuoso. Muitos que utilizam este método nem sabem responder como construíam aplicativos de outra forma.
Entregas de software como produto estão cada vez mais comuns nos dias atuais, graças à diversos meios que auxiliam desenvolvedores a construir sistemas de maneira desacoplada. Serviços como Amazon e GitHut se tornaram referência no assunto e são muito utilizados quando pensamos em SaaS.
E com a popularidade crescendo, esse novo modo de construir e entregar software recebe inúmeras sugestões para melhorar ainda mais suas práticas, sem contar que o 12 Factor é independente de linguagem de programação.
A probabilidade de que tenha de ser feito manutenção em um sistema com esta arquitetura é muito grande e a internet está cheia de dicas de profissionais para auxiliar a todos. Alguns deles são muito específicos para determinadas arquiteturas e linguagens e até mesmo podem ser relacionados a problemas exclusivos.
Dentre estes conselhos, o que é difícil de encontrar são verdades universais e conselhos práticos que possam ser usados como uma maneira de avaliar um projeto particular. Na orientação a objetos estes princípios “universais” existem. Como exemplo, podemos citar SOLID, GRASP e até o precursor dos microsserviços, o SOA.
Entre essas dicas, é difícil encontrar dogmas práticos que possam ser úteis para avaliar um projeto específico. Na orientação a objetos, esses dogmas são muito utilizado. Por exemplo o SOLID, o GRASP e o antecessor do microserviço - SOA.
A empresa Heroku, já citada, mantém um tipo de manifesto chamado “The Twelve Factor App”. Este manifesto descreve doze práticas para serem seguidas ao criar aplicações voltadas para nuvem (e consequentemente, microsserviços.
Um ponto realmente importância quando se fala de muitos serviços. Quanto mais você tem, mais importante se torna. Isto é, é um pré-requisito primordial para um projeto de microsserviços de sucesso. Além disso, quando o desenvolvimento é o máximo possível parecido com a produção, o desenvolvimento e a busca de erros tornam-se mais fáceis e rápidos.
Apenas observando os métodos, podemos ter a sensação de que isso deixaria o desenvolvimento mais agradável. É assim que deve-se pensar nesses fatores, não como uma receita, como projetar o sistema completo, mas sim um conjunto de pré-requisitos que podem dar ao projeto um grande começo. Portanto, pode-se dizer que a maioria das tentativas de microsserviços fracassadas estavam condenadas desde o início. Não foram questões de arquitetura ou algumas dificuldades de codificação que as tornaram ineficazes, mas sim que as coisas básicas estavam erradas.

## Métodos

Os métodos a seguir podem ser usados com qualquer linguagem de programação ou banco de dados, pois automatizam qualquer desenvolvimento e diminui o custo do projeto. Sem contar que diminuem consideravelmente as diferenças entre o desenvolvimento e a produção, fazendo com que seja otimizado a agilidade dos desenvolvedores.
1) Codebase: O primeiro passo é colocar todos o código em um sistema de controle, como Git ou Mercurial. Geralmente só existe uma base de código e ela é compartilhada com vários repositórios. Ou seja, é basicamente um local para produção e vários para testes, todo desenvolvedor tem uma cópia da base em seu ambiente local, onde saem vários deploys. Mesmo que o ambiente local tenha códigos que não tem em produção e vice-versa, não há problema, pois todos compartilham da mesma base de código, portanto não haverá conflitos ao passar os desenvolvimentos de local para produção.
2) Dependencies: Em diversas aplicações as bibliotecas são adicionadas diretamente no diretório, porém o 12 Factor não permite que isso ocorra, ele declara todas as dependências de acordo com o manifesto de declaração de dependência. Independente das ferramentas, as dependências devem ser declaradas e isoladas, fazendo com que a configuração da aplicação para futuros desenvolvedores fique mais fácil. Portanto, todas as dependências são isoladas, fazendo com que não haja vazamentos pelo sistema, deixando a aplicação mais segura e confiável
3) Config: Configurações podem variar entre ambientes diferentes, a ideia é armazenar as configurações no ambiente, ou seja, não colocar configurações no código-fonte. O 12 Factor armazena todas as configuração em variáveis de ambiente. Fazendo com que se possa alternar facilmente entre implementações sem precisar alterar o código. Isso faz com que os arquivos de configuração sejam dispensáveis e que a aplicação se torne independente da linguagem. Desse modo, conforme a aplicação cresce com os deploys, é evitado problemas com a configuração, sem contar que fica mais fácil de gerenciar o mesmo.
4) Baking Services: A base de código do aplicativo 12 Factors não difere bibliotecas e APIs. Para o aplicativo, os dois são ferramentas incorporadas, acessíveis por URLs ou outros localizadores salvos no diretório. Um aplicativo 12 Factor é capaz de trocar um banco de dados local por um controlado por terceiros sem que seja necessário alterar o código, sendo que apenas a configuração (método 3) precisa ser alterado.
5) Build, release, run: Separar estritamente os builds e executar em estágios.A separação dessas etapas é importante para garantir que a automação e a manutenção do sistema seja o mais simples possível.
6) Processes: Processos de 12 Factors não gravam estado, quaisquer dados que precisam ser armazenados devem ser gravados em um serviço de apoio, geralmente em um banco de dados. Tais dados podem ser usados como um cache curto. Isto é de extrema importância, pois permite que a aplicação execute de forma mais rápida, porém em contrapartida quando o sistema é reiniciado, todos os estados locais são destruídos.
7) Port Binding: Ao contrário de alguns aplicativos da web que são executados de um servidor da web, o 12 Factor age como serviço independente, o que significa que não depende de nenhum servidor de aplicativos para ser executado. Isso significa que a porta à qual o aplicativo está conectado também é salva no Config (Método 3). Essa abordagem também ajuda na troca de serviços de suporte.
8) Concurrency: Neste método, pode-se dizer que que, devido aos Processos, a simultaneidade é simples e confiável, isso se torna muito benéfico, considerando que o dimensionamento vertical pode ser limitado de acordo com a execução do servidor, ou seja, é sempre recomendado obter o dimensionamento horizontal.
9) Disposability: Aplicativos de 12 Factors devem ser iniciados ou parados o mínimo possível, pois assim evita erros e bugs que poderiam afetar todo o desempenho do sistema. Também deve-se fazer, sempre que possível, com que as solicitações HTTP sejam breves. Afinal, se a conexão cair no meio de uma troca de dados, isso fará com que dados sejam perdidos e fará com que o cliente tenha de se reconectar manualmente.
10) Dev/prod parity: Aplicativos 12 Factors são projetados para implantações contínuas, mantendo menos disparidades entre os ambientes de produção e desenvolvimento. Isso é feito para evitar problemas imprevistos quando o aplicativo estiver funcionando bem no ambiente de desenvolvimento. Isso não significa necessariamente ter o SO em ambos os ambientes. Portanto, o ambiente de teste e produção deve ser mantido o mais semelhante possível. É bem melhor para passar o desenvolvimento de uma alteração ou a implantação para o ambiente de produção.
11) Logs: Tratar logs como fluxo de eventos.Dessa forma é possível acompanhar os logs do sistema distribuído em tempo real e até criar alertas para monitoramento.
12) Admin Process: Executar tarefas de gerenciamento, como processos únicos (migração de banco de dados ou execução de scripts). Isso parece correto se realmente for uma tarefa única, mas e se a migração do banco de dados for uma tarefa periódica e você precisar lidar com agendadores e executá-la automaticamente. Então deve-se automatizar as tarefas administrativas, uma vez que a aplicação pode rodar em diversos servidores, contemplando diversos processos. Tarefas como limpar cache, carregar dados, atualizar bases de dados, precisam ser facilitadas.