Mantenha a sua cozinha organizada: o case Monorepo no iFood

Ano após ano, os desenvolvedores falam sobre uma nova estrutura, arquitetura ou linguagem. Saiba mais.

Ano após ano, os desenvolvedores falam sobre uma nova estrutura, arquitetura ou linguagem. É algo que desperta tanta alegria na comunidade, que todos começam a falar sobre: em cada artigo, evento ou palestra.
Para nós, aqui no iFood, o ano de 2019 se resumia a monorepos e Clean Architecture.

Antes de entrar em detalhes, vamos dar alguns passos para trás para ter uma visão mais clara da equipe de desenvolvimento do iOS.

Uma equipe em expansão

O ano é 2015, e o time era enorme. Um bravo desenvolvedor. Um novo projeto foi criado e todo o código existente foi traduzido para Swift. Um ano depois, a equipe cresceria para cerca de três desenvolvedores. Mais recursos implementados, mais complexidade. Em 2018, a empresa atingiu novos patamares e a equipe mudou completamente: de cerca de 6 desenvolvedores para mais de 20 pessoas.

Isso nos colocou numa situação em que tínhamos que olhar cuidadosamente como estávamos fazendo as coisas. Tínhamos mais código entrando diariamente, mais recursos rodando simultaneamente, mais manutenção a ser feita. Se não organizássemos e criássemos padrões, acabaríamos em uma base de código caótica e muito complexa.

Eu gostaria de dizer que isso não aconteceu, mas…

O ponto de virada para nós foi quando um novo produto foi lançado por volta de dezembro de 2018. Ele tinha toneladas de código que podíamos compartilhar, de regras de negócios a estruturas de rede e componentes de UI. Mas tínhamos um monólito enorme, cheio de interdependência, mais de 10 minutos de tempo de build local, mais de 40 minutos de tempo de build no CI e alguns frameworks em seus próprios repositórios separados.

Foi horrível adicionar e testar novos recursos rapidamente. Começamos a ter cada vez mais código duplicado, conflitos de versões de framework em cada produto e assim por diante.

Na época, a solução era muito clara: vamos criar um monorepo – um repositório único. Assim, toda a base de código estaria em um único repositório, com estruturas diferentes para cada parte do código, e não teríamos mais problemas com duplicação ou controle de versão.

O início

Em primeiro lugar, tivemos que organizar o monorepo e determinar os donos de cada parte do código. Em fevereiro de 2019, fizemos uma reorganização básica das pastas, colocando cada recurso em subdiretórios de squads. Uma mudança com mais de dois mil arquivos alterados. Foi um movimento audacioso, com certeza, mas foi extremamente necessário e nos ajudou a seguir em frente.

Então, tivemos que trazer essas estruturas e bibliotecas compartilhadas de repositórios separados para o monorepo. Assim, na semana seguinte, criamos nossos dois primeiros módulos usando Cocoapods locais. Um era uma estrutura de camada de rede e o outro era uma funcionalidade de produto hoje conhecida como Loop, nosso recurso de lançamento. Descobrimos a necessidade de dar nomes às coisas e de criar um padrão de como os módulos foram criados. Foi então que as microfeatures entraram em cena.

Microfeatures: o que são?

Você provavelmente já ouviu o termo “microsserviço”. Está em alta, e os desenvolvedores de back-end estão empenhados em criar pequenos serviços individuais com uma única responsabilidade. Outro termo que está se tornando muito popular é “micro frontend”, que tem a mesma proposta, mas para desenvolvedores de frontend. Microfeature é apenas mais um termo para um pequeno módulo, com uma única responsabilidade que expõe uma interface para que outros módulos possam interagir com ela.

Gostamos muito da definição proposta pelo Tuist, pois ela vai um passo além e divide os módulos em dois tipos: base e produto.

Base µFeature

Módulos responsáveis ​​por uma tarefa específica, como chamadas HTTP ou componentes de UI, Remote Config e assim por diante.

Eles não têm nenhuma lógica de negócios envolvida, expõem um conjunto de classes ou protocolos e podemos importá-los e usá-los livremente em todo o aplicativo. Eles podem ser totalmente testados e o tempo de compilação é rápido.

Produto µFeature

São funcionalidades que seu usuário pode ver, como por exemplo um fluxo de login ou uma página de checkout, o menu de um restaurante etc.

Eles não têm apenas a lógica de negócios, mas também as telas, os roteadores, os casos de uso, os repositórios e todas as camadas Clean Swift e Clean Architecture.

Além disso, eles devem expor um aplicativo de exemplo para facilitar o desenvolvimento. Se você estiver trabalhando em uma µFeature de produto, só vai compilar todo o produto no momento da integração.

Gerenciando o monorepo

As coisas podem ficar muito complexas rapidamente num monorepo, especialmente quando você tem mais de 40 desenvolvedores iOS trabalhando nisso. Gerenciar todos os módulos com pods locais simplesmente não era mais adequado para nós, então tivemos que encontrar uma ferramenta para fazer esse trabalho. Foi então que o Buck entrou em cena.

Por volta de julho de 2019, decidimos usar Buck como a ferramenta de compilação para nosso projeto. Foi uma grande mudança, mas que apenas poucas pessoas já dominavam.

Aprendemos muito sobre como compartilhar o conhecimento durante um processo de migração e como não manter a maior parte do conhecimento focado em uma única pessoa. Aprendemos que temos que nos comunicar, ensinar e que precisamos de uma equipe para lidar com as operações do desenvolvedor.

Hoje, buscamos bastante informação no repositório do Airbnb, porque eles são muito ativos na comunidade e abrem a maioria de suas adaptações e ferramentas.

Dois anos depois … ainda está funcionando? Foi uma boa ideia?

Com certeza foi a decisão correta para continuar escalando nosso app. Continuamos melhorando nossa stack de CI, aplicando o uso de caches, automatizando a criação de µFeatures e criando diversos tipos de análises estáticas para detectar problemas antes de atingir a branch principal.

Hoje, temos uma equipe de cerca de 45 desenvolvedores iOS, mais de 200 µFeatures, 1 milhão de linhas de código Swift e 25 mil testes unitários. Se podemos tirar uma lição desse processo, é compartilhar e documentar tudo o que é feito. Dessa forma, você não só tem a história do que foi e deve ser feito, mas também uma nova pessoa pode entrar na equipe e se preparar para trabalhar no projeto com bastante rapidez.

Espero que você tenha gostado deste artigo e que tenha ajudado a ter uma ideia de como as coisas são feitas aqui no iFood — e que o incentive a fazer grandes mudanças em seu próprio projeto.

Cheers!

Texto original disponível em Medium | iFood Engineering – Keep your kitchen organized – por Yasmin Benatti, iOS Developer com colaboração de André Alves, Mobile Platform.

Esse conteúdo foi útil para você?
SimNão

Publicações relacionadas