The Twelve-Factor App

II. Dependências

Declare e isole explicitamente as dependências

A maioria das linguagens de programação oferecem um sistema de pacotes para a distribuição de bibliotecas de apoio, como o CPAN para Perl ou Rubygems para Ruby. Bibliotecas instaladas por meio de um sistema de pacotes podem ser instaladas em todo o sistema (conhecidas como “site packages”) ou com escopo dentro do diretório contendo a aplicação (conhecidas como “vendoring” ou “building”).

Uma aplicação doze-fatores nunca confia na existência implícita de pacotes em todo o sistema. Ela declara todas as dependências, completa e exatamente, por meio de um manifesto de declaração de dependência. Além disso, ela usa uma ferramenta de isolamento de dependência durante a execução para garantir que não há dependências implícitas “vazamento” a partir do sistema circundante. A completa e explícita especificação de dependências é aplicada de maneira uniforme tanto para produção quanto para desenvolvimento.

Por exemplo, Bundler para Ruby oferece o formato de manifesto Gemfile para declaração de dependência e bundle exec para isolamento das mesmas. Em Python existem duas ferramentas separadas para estas etapas – Pip é utilizado para declaração e Virtualenv para isolamento. Mesmo C tem Autoconf para declaração de dependência, e vinculação estática pode fornecer o isolamento. Não importa qual o conjunto de ferramentas, declaração de dependência e isolamento devem ser sempre usados juntos – apenas um ou o outro não é suficiente para satisfazer doze-fatores.

Um dos beneficios da declaração de dependência explícita é que simplifica a configuração da aplicação para novos desenvolvedores. O novo desenvolvedor pode verificar a base de código do aplicativo em sua máquina de desenvolvimento, exigindo apenas runtime da linguagem e gerenciador de dependência instalado como pré-requisitos. Eles serão capazes de configurar tudo o que é necessário para rodar o código da aplicação com um determinístico comando de build. Por exemplo, o comando de build para Ruby/Bundler é bundle install, enquanto que para Clojure/Leiningen é lein deps.

Aplicações doze-fatores também não contam com a existência implícita de todas as ferramentas do sistema. Exemplos incluem executar algum comando externo como do ImageMagick ou curl. Embora possam existir essas ferramentas em muitos ou mesmo na maioria dos sistemas, não há garantia de que eles vão existir em todos os sistemas em que a aplicação pode rodar no futuro, ou se a versão encontrada em um futuro sistema será compatível com a aplicação. Se a aplicação precisa executar alguma ferramenta do sistema, essa ferramenta deve ser vendorizada na aplicação.