Convenções
Nas convenções a seguir, ${aplicacao} é o nome da aplicação e ${subdominio} é o nome de um subdomínio.
Maven
| Módulo | artifactId |
Diretório |
|---|---|---|
| Projeto raiz | ${aplicacao}-pai |
${aplicacao} |
| Domínio compartilhado | ${aplicacao}-dominio-compartilhado |
${aplicacao}/dominio-compartilhado |
| Domínio de um subdomínio | ${aplicacao}-dominio-${subdominio} |
${aplicacao}/dominio-${subdominio} |
| Infraestrutura | ${aplicacao}-infraestrutura |
${aplicacao}/infraestrutura |
| Aplicação | ${aplicacao}-aplicacao |
${aplicacao}/aplicacao |
| UI — backend | ${aplicacao}-ui-backend |
${aplicacao}/ui-backend |
| UI — frontend | ${aplicacao}-ui-frontend |
${aplicacao}/ui-frontend |
Dependências entre módulos de domínio
O domínio compartilhado contém apenas os conceitos que não pertencem a nenhum subdomínio específico e são comuns a todos eles — como os papéis de autorização. Ser usado por mais de um subdomínio não basta: um conceito que pertence a um subdomínio fica no módulo dele, mesmo que outros subdomínios o usem.
Todo módulo de subdomínio depende do domínio compartilhado. Um módulo de subdomínio pode depender também de outro, quando seus conceitos referenciam os do outro, desde que as dependências entre os módulos de subdomínio não formem um ciclo.
Pacotes
Nesta seção, ${groupId} é o groupId do projeto raiz e de seus módulos. Já ${agregado} é o nome de um agregado em minúsculas, com as palavras juntas, sem separador — por exemplo, unidadefederativa.
| Elemento | Módulo | Pacote |
|---|---|---|
Agregado ${agregado} e seus objetos de valor |
${aplicacao}-dominio-${subdominio} |
${groupId}.${aplicacao}.dominio.${subdominio}.${agregado} |
Interface do repositório de um agregado ${agregado} |
${aplicacao}-dominio-${subdominio} |
${groupId}.${aplicacao}.dominio.${subdominio}.${agregado}.spi |
| Papéis de autorização, compartilhados por todos os subdomínios | ${aplicacao}-dominio-compartilhado |
${groupId}.${aplicacao}.dominio |
Projeção, ordenação, consulta e serviço de aplicação de um agregado ${agregado} |
${aplicacao}-aplicacao |
${groupId}.${aplicacao}.aplicacao.${subdominio}.${agregado} |
Interface do repositório de aplicação de um agregado ${agregado} |
${aplicacao}-aplicacao |
${groupId}.${aplicacao}.aplicacao.${subdominio}.${agregado}.spi |
Implementação do repositório, entidade JPA e interface Spring Data JPA de um agregado ${agregado} |
${aplicacao}-infraestrutura |
${groupId}.${aplicacao}.infraestrutura.${subdominio}.${agregado} |
Implementação do repositório de aplicação de um agregado ${agregado} |
${aplicacao}-infraestrutura |
${groupId}.${aplicacao}.infraestrutura.${subdominio}.${agregado} |
Controlador REST de um agregado ${agregado} |
${aplicacao}-ui-backend |
${groupId}.${aplicacao}.ui.backend.${subdominio}.${agregado} |
| Configuração de segurança, controlador de autenticação e recurso de autenticação | ${aplicacao}-ui-backend |
${groupId}.${aplicacao}.ui.backend.seguranca |
Classe com o main da aplicação Spring Boot |
${aplicacao}-ui-backend |
${groupId}.${aplicacao} |
| Suíte do Cucumber de um subdomínio | ${aplicacao}-dominio-${subdominio}, em src/test/java |
${groupId}.${aplicacao}.dominio.${subdominio} |
Step definitions de um agregado ${agregado} |
${aplicacao}-dominio-${subdominio}, em src/test/java |
${groupId}.${aplicacao}.dominio.${subdominio}.${agregado} |
Testes do repositório e do repositório de aplicação de um agregado ${agregado} |
${aplicacao}-infraestrutura, em src/test/java |
${groupId}.${aplicacao}.infraestrutura.${subdominio}.${agregado} |
| Configuração Spring Boot dos testes de infraestrutura | ${aplicacao}-infraestrutura, em src/test/java |
${groupId}.${aplicacao}.infraestrutura |
Os pacotes spi contêm as interfaces que uma camada usa e que outra camada implementa; veja Inversão de dependência e pacotes spi.
Caminhos
Nesta seção, ${agregado-hifenizado} é o nome de um agregado em minúsculas, com as palavras separadas por hífen — por exemplo, unidade-federativa.
| Elemento | Caminho |
|---|---|
| Controlador REST de um agregado | @RequestMapping(Backend.PREFIXO + "${subdominio}/${agregado-hifenizado}") |
| Controlador de autenticação | @RequestMapping(Backend.PREFIXO + "autenticacao") |
| Cenários Gherkin de um agregado | ${aplicacao}/dominio-${subdominio}/src/test/resources/features/${agregado-hifenizado}.feature |
Nomenclatura
Nesta seção, ${Agregado} é o nome de um agregado, em PascalCase.
| Elemento | Nome |
|---|---|
| Interface | Prefixo I — I${Agregado}Repositorio |
| Classe abstrata | Sufixo Abstrato/Abstrata — AgregadoServicoAbstrato |
| Agregado | ${Agregado} |
| Serviço de domínio | ${Agregado}Servico |
| Repositório de domínio (interface e implementação) | I${Agregado}Repositorio e ${Agregado}Repositorio |
| Serviço de aplicação | ${Agregado}AplicacaoServico |
| Repositório de aplicação (interface e implementação) | I${Agregado}AplicacaoRepositorio e ${Agregado}AplicacaoRepositorio |
| Consulta | ${Agregado}Consulta |
| Ordenação | ${Agregado}Ordenacao |
| Projeção | ${Agregado}Projecao |
| Entidade JPA | ${Agregado}Jpa |
| Repositório Spring Data JPA | I${Agregado}RepositorioJpa |
| Controlador | ${Agregado}Controlador |
Papéis de autorização (enum) |
Autorizacao |
| Configuração de segurança | SegurancaConfiguracao |
| Controlador de autenticação | AutenticacaoControlador |
| Recurso de autenticação | AutenticacaoRecurso |
Classe com o main da aplicação Spring Boot |
BackendAplicacao |
| Suíte do Cucumber | CucumberTests |
| Step definitions | ${Agregado}StepDefinitions |
| Testes do repositório e do repositório de aplicação | ${Agregado}RepositorioTest e ${Agregado}AplicacaoRepositorioTest |
| Configuração Spring Boot dos testes de infraestrutura | InfraestruturaTesteAplicacao |
Entidades JPA
As restrições de uma coluna que o Bean Validation consegue expressar são declaradas com suas anotações — @NotNull em vez de nullable = false e @Size(max = ...) em vez de length —, e a @Column declara apenas o que elas não expressam, como name, unique e updatable. Assim, o Hibernate usa as mesmas anotações para gerar o esquema e para validar a entidade antes de gravá-la; veja Validação das entidades JPA.
Essas anotações expressam apenas restrições da persistência, como o tamanho de uma coluna. Regras do domínio — como um nome não poder estar em branco ou um código seguir um formato — ficam no agregado e em seus objetos de valor e não são repetidas na entidade JPA.
Quando o tamanho de uma coluna é o de um objeto de valor, @Size usa a constante do objeto de valor — por exemplo, @Size(max = UnidadeFederativaSigla.TAMANHO). Os demais tamanhos são escritos diretamente na anotação, sem constante.