-
Notifications
You must be signed in to change notification settings - Fork 12
Estrutura de pastas e arquivos
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
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. São controllers pensados para receber e responder em formato
JSON
, ou gRPC
que compõem nossa API pública.
Sào controllers que recebem requisições diretamente via browser, da plataforma interna e renderiza as páginas e adicona flash messages por exemplo.
É 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.
- Anúncio de Context no Phoenix
- How would you explain Phoenix Contexts to a newbie?
- The Core and the Interface
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.
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. 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. 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
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.
É 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.
- Anúncio de Context no Phoenix
- How would you explain Phoenix Contexts to a newbie?
- The Core and the Interface
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
.
Contrato que específica funções necessárias para executar uma requisição
HTTP. Exemplo: URL base, autenticação, headers, body, etc.
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
.