Skip to content

Estrutura de pastas e arquivos

Zoey de Souza Pessanha edited this page Mar 11, 2022 · 3 revisions

Estrutura que pensamos inicialmente e a responsabilidade de cada pasta:

project_name
├── context
│   ├── adapters
│   ├── logic
│   ├── models
│   ├── queries
│   └── schemas
├── context.ex
├── database.ex
├── http_behaviour.ex
└── http_client.ex
├── context_web
└── controllers
    ├── api
    └── browser

controllers

Lida com os dados da request, autenticação, dispara a validação dos dados, realizada chamadas ao banco através do contexto específico, renderiza a resposta baseado no retorno da função.

api

São controllers pensados para receber e responder em formato JSON, ou gRPC que compõem nossa API pública.

browser

Sào controllers que recebem requisições diretamente via browser, da plataforma interna e renderiza as páginas e adicona flash messages por exemplo.


context

É o nome do nosso contexto fictício deste exemplo. É a pasta onde vai conter tudo relacionado a “context” dentro do projeto. Idealmente devemos separar bem os contexto da aplicação para que um contexto não possua muitas responsabilidade e acabe ficando extenso demais.
adapters

De forma exemplificável […], o padrão Adapter converte a interface de uma classe para outra interface que o cliente espera encontrar, “traduzindo” solicitações do formato requerido pelo usuário para o formato compatível […]

Contém módulos e funções adaptadoras (de-para) que serão utilizadas quando existir a necessidade de transformar um schema A e B em um novo schema C. Esses arquivos ficarão contidos dentro da pasta do seu respectivo contexto.

logic
Contém as regras de negócio como funções puras separadas por contexto. Conceitualmente, uma função pura é aquela que dado um input produz o mesmo output, sem nenhum efeito colateral. Ou seja, a mesma entrada gera a mesma saída.
models
Os módulos contidos nesta pasta são a representação do nosso banco de dados e as entidades que usaremos para buscar, incluir, editar ou remover algum dado.
queries
Contém módulos e funções com as representações das queries a serem aplicadas no banco de dados. Não realiza nenhuma ação propriamente dita no banco dados, apenas declara como uma consulta deve acontecer, por exemplo.

Exemplo de um módulo de queries:

defmodule ProjectName.Context.Queries.Boleto do
  import Ecto.Query

  def list_available_billets do
    from b in Billet,
      where: b.active? == true,
      select: b
  end
end
schemas
São schemas internos que inicialmente serão embedded schemas utilizados para representar o input e o output de uma função. Usaremos embedded schemas pois já existe dentro do Ecto e podemos adicionar validações ao módulo.

Pensando no exemplo onde exista uma função responsável por pagar um boleto. Ao invés de passarmos para a função três parâmetros

def pay_billet(billet, customer, payment_date) do
  ...
end

Passamos um schema que contém todas as informações necessárias para realizar o pagamento do boleto

def pay_billet(%Schema.PaymentBillet{billet: _billet, customer: _customer, payment_date: _date}) do
  ...
end

Desta forma conseguimos definir muito bem qual é a interface da função evitando confusão ao enviar algum parâmetro para a função.


context.ex

É a API pública do nosso contexto. Todas as chamadas fora do contexto de context, precisam passar por esse arquivo. Desde requisição ao banco, regra de negócio, validação, etc. Em outra wiki explicamos melhor sobre a fronteira entre módulos da aplicação.

Esse arquivo é responsável por manter as funções impuras da aplicação. Com side effect, escrita em disco, gravação em banco, etc. Ela organiza o fluxo de execução de alguma funcionalidade.

database.ex

Módulo genérico para interagir com o banco de dados recebendo as queries como parâmetro e implementa Repo.one, Repo.all, etc. O mesmo para inclusão de dados. Vai existir, por exemplo, uma função insert que recebe uma entidade e um mapa de parâmetros e interage com o banco através de Repo.insert.

http_behaviour.ex

Contrato que específica funções necessárias para executar uma requisição HTTP. Exemplo: URL base, autenticação, headers, body, etc.

http_client.ex

Módulo genérico para requisições de API implementando os métodos get, post, put e delete. Recebe como parâmetro alguma implementação do behaviour http_behaviour.ex.