Class AbstractCrudController<E,D,ID,FD extends GenericFilterDTO>
- Type Parameters:
E- Tipo da Entidade JPAD- Tipo do DTO (Data Transfer Object)ID- Tipo do identificador (Long, String, UUID, etc.)FD- Tipo do DTO de filtro (deve estender GenericFilterDTO)
- Direct Known Subclasses:
AbstractReadOnlyController
🏗️ Controller Base com Auto-Detecção de Path e Integração OpenAPI
✨ O que vem pronto (por números)
/{id}/all/filter/filter/cursor/locate/by-ids/options/filter/options/by-ids/option-sources/{sourceKey}/options/filter/option-sources/{sourceKey}/options/by-ids/stats/group-by/stats/timeseries/stats/distribution//{id}/{id}/batch/schemas → /schemas/filtered26 operações de filtro: texto (like/not/starts/ends), comparações (>, ≥, <, ≤), listas (in/not), intervalos (between/…), datas relativas (últimos/próximos), tamanho de coleções, nulidade/booleanos.
Documentação viva: OpenAPI por grupo + cache + ETag, com metadados de UI (x‑ui).
🎯 Problema Resolvido
Antes desta implementação, era necessário implementar manualmente o método getBasePath()
em cada controller, causando duplicação de código e possibilidade de inconsistências.
Agora o base path é detectado automaticamente via anotações.
🔄 Fluxo de Auto-Detecção
1. @PostConstruct initializeBasePath() é executado após construção do bean 2. AnnotationUtils.findAnnotation() detecta @RequestMapping/@ApiResource 3. Extrai path das anotações (value[] ou path[]) 4. Se não encontrar anotações, emite warning e marca a configuração como pendente 5. Base path disponível para HATEOAS links e documentação
🚀 Benefícios da Auto-Detecção
- Zero Boilerplate: Elimina necessidade de implementar getBasePath()
- Consistência: Garante que path usado é o mesmo das anotações
- Flexibilidade: Funciona com @RequestMapping, @ApiResource e variações
- Integração: DynamicSwaggerConfig usa mesma lógica para grupos OpenAPI
- HATEOAS: Links automáticos baseados no path detectado
- Ordenação Inteligente: Aplica @DefaultSortColumn automaticamente
📊 Ordenação Padrão Automática
Todos os endpoints de listagem aplicam automaticamente ordenação padrão quando nenhuma ordenação específica é fornecida via parâmetros de requisição.
🔄 Como Funciona:
- Sem parâmetro sort: Aplica ordenação de @DefaultSortColumn na entidade
- Com parâmetro sort: Usa ordenação específica, ignora @DefaultSortColumn
- Sem @DefaultSortColumn: Usa ordenação padrão do banco (imprevisível)
📋 Endpoints Afetados:
- GET /{resource}/all: Lista completa com ordenação padrão
- POST /{resource}/filter: Lista filtrada com ordenação padrão
🌐 Exemplos de Uso:
// Entidade com ordenação padrão:@Entitypublic class Funcionario {@DefaultSortColumn(priority = 1)private String departamento;@DefaultSortColumn(priority = 2)private String nomeCompleto; } // URLs suportadas: GET /api/funcionarios/all → ORDER BY departamento ASC, nomeCompleto ASC GET /api/funcionarios/all?sort=salario,desc → ORDER BY salario DESC POST /api/funcionarios/filter?page=0&size=10 → ORDER BY departamento ASC, nomeCompleto ASC POST /api/funcionarios/filter?page=0&size=10&sort=nome,asc → ORDER BY nome ASC
📋 Exemplos de Uso
💚 RECOMENDADO - Com Constantes e Meta-Anotações:
// Criar constantes no projeto da aplicação:
public final class ApiPaths {
public static final class HumanResources {
public static final String FUNCIONARIOS = "/api/human-resources/funcionarios";
}
}
import static com.example.project.constants.ApiPaths.HumanResources.FUNCIONARIOS;
@ApiResource(FUNCIONARIOS) // Meta-anotação: @RestController + @RequestMapping
@ApiGroup("human-resources") // Grupo OpenAPI personalizado
public class FuncionarioController extends AbstractCrudController<
Funcionario, FuncionarioDTO, Long, FuncionarioFilterDTO> {
@Autowired
private FuncionarioService service;
@Override
protected FuncionarioService getService() { return service; }
// ✅ getBasePath() NÃO é necessário - detectado automaticamente
// ✅ Grupo OpenAPI "recursos-humanos" criado automaticamente
// ✅ Links HATEOAS gerados com path correto
}
💛 TRADICIONAL - Com Anotações Padrão:
@RestController
@RequestMapping("/api/human-resources/funcionarios")
public class FuncionarioController extends AbstractCrudController<...> {
// ✅ getBasePath() detectado automaticamente como "/api/human-resources/funcionarios"
// ✅ Grupo OpenAPI "api-human-resources-funcionarios" criado automaticamente
}
⚙️ Integração com Sistema
- DynamicSwaggerConfig: Escaneia controllers que estendem esta classe
- ApiDocsController: Resolve grupos baseado nos paths detectados
- HATEOAS: Links automáticos para self, create, update, delete
- OpenAPI: Documentação organizada por grupos específicos
🔍 Estratégias de Detecção
- @ApiResource.value[] / path[]: primeira prioridade
- @RequestMapping.value[] / path[]: segunda prioridade
- Configuração obrigatória: emite warning se não encontrar anotações e marca o path como pendente
- See Also:
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionprotected booleanprotected booleanprotected booleanorg.springframework.http.ResponseEntity<RestApiResponse<D>> Cria um novo registro a partir do DTO informado.org.springframework.http.ResponseEntity<Void> Exclui um registro pelo seu identificador.org.springframework.http.ResponseEntity<Void> deleteBatch(List<ID> ids) Exclui multiplos registros pelos seus identificadores.org.springframework.http.ResponseEntity<RestApiResponse<DistributionStatsResponse>> distributionStats(DistributionStatsRequest<FD> request) Calcula distribuicoes agregadas sobre o conjunto filtrado do recurso.org.springframework.http.ResponseEntity<RestApiResponse<org.springframework.data.domain.Page<org.springframework.hateoas.EntityModel<D>>>> filter(FD filterDTO, int page, int size, List<ID> includeIds, org.springframework.util.MultiValueMap<String, String> queryParams) Endpoint para filtrar entidades com paginação.org.springframework.http.ResponseEntity<RestApiResponse<CursorPage<org.springframework.hateoas.EntityModel<D>>>> filterByCursor(FD filterDTO, String after, String before, int size, org.springframework.util.MultiValueMap<String, String> queryParams) Endpoint para paginação baseada em cursor (keyset), oferecendo resultados estáveis durante listas longas.filterOptions(FD filterDTO, int page, int size, org.springframework.util.MultiValueMap<String, String> queryParams) Retorna opções paginadas para popular selects.filterOptionSourceOptions(String sourceKey, FD filterDTO, String search, List<String> includeIds, int page, int size, org.springframework.util.MultiValueMap<String, String> queryParams) Retorna opcoes paginadas a partir de uma fonte canonica registrada emoption-sources.org.springframework.http.ResponseEntity<RestApiResponse<List<org.springframework.hateoas.EntityModel<D>>>> getAll()Lista todos os registros aplicando @DefaultSortColumn quando nenhum sort é enviado.protected StringRetorna o base path do controller.org.springframework.http.ResponseEntity<RestApiResponse<D>> Recupera um registro pelo seu identificador.Recupera múltiplos registros pelos seus identificadores em uma única chamada.Retorna a classe concreta do controller (ex.: TipoTelefoneController.class) para uso no método methodOn(...) do HATEOAS.protected abstract IDExtrai o identificador do DTO para construção de links HATEOAS.protected abstract IDgetEntityId(E entity) Extrai o identificador da entidade para construção de links HATEOAS.protected StringReturns the primary key field name used by the resource DTO.getOptionsByIds(List<ID> ids) Retorna opções (id/label) para uma coleção de IDs, preservando a ordem solicitada.getOptionSourceOptionsByIds(String sourceKey, List<String> ids) Reidrata opcoes por IDs a partir de uma fonte canonica registrada emoption-sources.org.springframework.http.ResponseEntity<Void> Redireciona para o endpoint de schemas filtrados do recurso atual.protected abstract BaseCrudService<E, D, ID, FD> Retorna o serviço base (CRUD) que será usado internamente.org.springframework.http.ResponseEntity<RestApiResponse<GroupByStatsResponse>> groupByStats(GroupByStatsRequest<FD> request) Calcula agregacoes de group-by sobre o conjunto filtrado do recurso.protected void🔍 Auto-Detecção do Base Pathprotected booleanIndica se o recurso é somente leitura.protected org.springframework.hateoas.LinkLink para GET /all.protected org.springframework.hateoas.LinkLink para POST /.protected org.springframework.hateoas.LinklinkToDelete(ID id) Link para DELETE /{id}.protected org.springframework.hateoas.LinkLink para documentação (ex.: Swagger UI).protected org.springframework.hateoas.LinkLink para GET /filter.protected org.springframework.hateoas.LinkLink para POST /filter/cursor.protected org.springframework.hateoas.LinklinkToSelf(ID id) Link para GET /{id}.protected org.springframework.hateoas.LinklinkToUiSchema(String methodPath, String operation, String schemaType) Gera um link HATEOAS para a documentação filtrada de um schema específico da API, baseado no caminho e na operação HTTP fornecidos.protected org.springframework.hateoas.LinklinkToUpdate(ID id) Link para PUT /{id}.org.springframework.http.ResponseEntity<LocateResponse> locate(FD filterDTO, ID id, int size, org.springframework.util.MultiValueMap<String, String> queryParams) Localiza a posição de um registro considerando filtro e ordenação.protected voidsetBasePath(String basePath) Permite definir manualmente o base path, sobrescrevendo a detecção automática.org.springframework.http.ResponseEntity<RestApiResponse<TimeSeriesStatsResponse>> timeSeriesStats(TimeSeriesStatsRequest<FD> request) Calcula serie temporal agregada sobre o conjunto filtrado.protected abstract DConverte uma entidade JPA em seu DTO correspondente.protected abstract EConverte um DTO em sua entidade JPA correspondente.protected org.springframework.hateoas.EntityModel<D> toEntityModel(D dto) protected RestApiResource<D> toResourceModel(D dto) org.springframework.http.ResponseEntity<RestApiResponse<D>> Atualiza um registro existente.
-
Constructor Details
-
AbstractCrudController
public AbstractCrudController()
-
-
Method Details
-
initializeBasePath
@PostConstruct protected void initializeBasePath()🔍 Auto-Detecção do Base Path
Este método detecta automaticamente o base path do controller através das anotações @RequestMapping ou @ApiResource, executado pelo Spring após a construção do bean (@PostConstruct).
🎯 Estratégias de Detecção (ordem de prioridade):
- 🎯 @ApiResource.value[] / path[]: Extrai o primeiro path declarado na meta-anotação
- 📋 @RequestMapping.value[] / path[]: Extrai o primeiro path declarado no controller
- ⚠️ Configuração obrigatória: Emite warning se não encontrar e usa um placeholder explícito
🔄 Exemplos de Detecção:
@RequestMapping("/api/human-resources/funcionarios")→ detectedBasePath = "/api/human-resources/funcionarios"@ApiResource("/api/human-resources/eventos-folha")→ detectedBasePath = "/api/human-resources/eventos-folha" FuncionarioController sem anotações → ⚠️ WARNING: Controller precisa usar@RequestMappingou@ApiResource🔗 Integração Sistêmica:
O path detectado é usado pelo DynamicSwaggerConfig para criar grupos OpenAPI e pelo sistema HATEOAS para gerar links automaticamente. Esta consistência garante que toda a documentação e navegação fique sincronizada.
🚨 Importante:
Controllers que estendem AbstractCrudController DEVEM usar
@RequestMappingou@ApiResource. Não há fallback automático para evitar configurações implícitas. -
getService
Retorna o serviço base (CRUD) que será usado internamente.- Returns:
- instância do serviço CRUD
-
toDto
Converte uma entidade JPA em seu DTO correspondente.- Parameters:
entity- a entidade a ser convertida- Returns:
- o DTO correspondente
-
toEntity
Converte um DTO em sua entidade JPA correspondente.- Parameters:
dto- o DTO a ser convertido- Returns:
- a entidade correspondente
-
getControllerClass
Retorna a classe concreta do controller (ex.: TipoTelefoneController.class) para uso no método methodOn(...) do HATEOAS.Fornece uma implementação padrão baseada em
Object.getClass(), mas pode ser sobrescrito caso o comportamento padrão não seja adequado. -
getEntityId
Extrai o identificador da entidade para construção de links HATEOAS.- Parameters:
entity- a entidade da qual extrair o ID- Returns:
- o identificador da entidade
-
getDtoId
Extrai o identificador do DTO para construção de links HATEOAS.- Parameters:
dto- o DTO do qual extrair o ID- Returns:
- o identificador do DTO
-
getIdFieldName
Returns the primary key field name used by the resource DTO. Default is "id". Override in resource controllers when the identifier property has a different name (e.g., "codigo"). -
isReadOnlyResource
protected boolean isReadOnlyResource()Indica se o recurso é somente leitura. Subclasses podem sobrescrever. -
getBasePath
Retorna o base path do controller.Por padrão, este método detecta automaticamente o path a partir das anotações @RequestMapping ou @ApiResource. Pode ser sobrescrito se necessário um comportamento customizado.
Detecção automática:
- Prioridade 1: valor/path da anotação
@ApiResource - Prioridade 2: valor/path da anotação
@RequestMapping - Sem fallback implícito por naming convention; ausência de anotação gera warning e placeholder explícito
- Returns:
- o base path do controller
- Prioridade 1: valor/path da anotação
-
setBasePath
Permite definir manualmente o base path, sobrescrevendo a detecção automática.- Parameters:
basePath- o novo base path
-
filter
@PostMapping("/filter") public org.springframework.http.ResponseEntity<RestApiResponse<org.springframework.data.domain.Page<org.springframework.hateoas.EntityModel<D>>>> filter(@RequestBody FD filterDTO, @RequestParam(name="page",defaultValue="0") int page, @RequestParam(name="size",defaultValue="20") int size, @RequestParam(name="includeIds",required=false) List<ID> includeIds, @RequestParam org.springframework.util.MultiValueMap<String, String> queryParams) Endpoint para filtrar entidades com paginação.Problema que resolve
- Prover paginação tradicional com ordenação consistente por padrão quando nenhum
sorté enviado. - Permitir injetar registros via
includeIdsna primeira página sem duplicar itens nas seguintes.
Como funciona internamente
- Valida
size≤praxis.pagination.max-size; 422 quando excede. - Monta
PageablecomPageableBuildere fallback de sort viaBaseCrudService.getDefaultSort(). - Constrói
SpecificationviaGenericSpecificationsBuildera partir do DTO. - Enriquece cada item com links HATEOAS através de
toEntityModel(Object)quando habilitado. - Adiciona links de documentação de schema (request/response) e
X-Data-Versionse disponível.
- Parameters:
filterDTO- DTO contendo os critérios de filtropage- número da página (inicia em 0)size- quantidade de registros por páginaincludeIds- IDs adicionais que devem aparecer no topo da primeira página (repetir nas páginas subsequentes para evitar duplicação, sem nova injeção)queryParams- parâmetros de query adicionais (ex.:sort)- Returns:
- página de entidades filtradas com links HATEOAS
- Throws:
org.springframework.web.server.ResponseStatusException- quando o parâmetrosizeexcede o limite configurado (422)Erros comuns
- 422:
sizeacima do limite configurado. - 400: validação do body (campos inválidos).
- 422:
- Prover paginação tradicional com ordenação consistente por padrão quando nenhum
-
filterByCursor
@PostMapping("/filter/cursor") public org.springframework.http.ResponseEntity<RestApiResponse<CursorPage<org.springframework.hateoas.EntityModel<D>>>> filterByCursor(@RequestBody FD filterDTO, @RequestParam(name="after",required=false) String after, @RequestParam(name="before",required=false) String before, @RequestParam(name="size",defaultValue="20") int size, @RequestParam org.springframework.util.MultiValueMap<String, String> queryParams) Endpoint para paginação baseada em cursor (keyset), oferecendo resultados estáveis durante listas longas.Problema que resolve
- Evitar saltos/itens repetidos entre navegações quando dados mudam.
Como funciona internamente
- Valida
size≤praxis.pagination.max-size. - Monta
SortcomSortBuildere fallback do service. - Delegado para
BaseCrudService.filterByCursorMapped(GenericFilterDTO, org.springframework.data.domain.Sort, String, String, int, java.util.function.Function). - Mapeia conteúdo para
EntityModel<D>e preservanext/prev/size.
- Parameters:
filterDTO- critérios de filtroafter- cursor para avançarbefore- cursor para retrocedersize- quantidade de registrosqueryParams- parâmetros de query adicionais (ex.:sort)- Returns:
- página baseada em cursor
- Throws:
org.springframework.web.server.ResponseStatusException- quandosizeexcede o limite (422) ou a operação não é suportada (501)Erros comuns
- 501: service não implementa keyset.
- 422:
sizeacima do limite.
-
locate
@PostMapping("/locate") public org.springframework.http.ResponseEntity<LocateResponse> locate(@RequestBody FD filterDTO, @RequestParam("id") ID id, @RequestParam(name="size",defaultValue="20") int size, @RequestParam org.springframework.util.MultiValueMap<String, String> queryParams) Localiza a posição de um registro considerando filtro e ordenação.Problema que resolve
- Permitir que a UI navegue diretamente até a página onde um ID aparece.
Como funciona internamente
- Valida
size≤praxis.pagination.max-size. - Calcula
Sorte chamaBaseCrudService.locate(GenericFilterDTO, org.springframework.data.domain.Sort, Object). - Monta
LocateResponsecom índice absoluto e página (index/size).
- Parameters:
filterDTO- critérios de filtroid- identificador do registro de interessesize- tamanho de página utilizado para derivar a página a partir do índice absolutoqueryParams- parâmetros de query adicionais (ex.:sort)- Returns:
- resposta com
LocateResponsecontendo índice e página - Throws:
org.springframework.web.server.ResponseStatusException- quandosizeexcede o limite (422) ou a operação não é suportada (501)Erros comuns
- 501: service não implementa localização.
- 422:
sizeacima do limite.
-
groupByStats
@PostMapping("/stats/group-by") public org.springframework.http.ResponseEntity<RestApiResponse<GroupByStatsResponse>> groupByStats(@RequestBody GroupByStatsRequest<FD> request) Calcula agregacoes de group-by sobre o conjunto filtrado do recurso.Este endpoint e a superficie canonica para contagens e metricas agregadas por buckets, sem exigir que cada aplicacao exponha rotas ad hoc para analytics basicos. Ele reaproveita o mesmo vocabulário de filtro do recurso principal e retorna buckets normalizados para consumo por tabelas analiticas, cards de resumo e graficos.
- Parameters:
request- request canonico contendo filtro, campo de agrupamento e metrica agregada- Returns:
- envelope com
GroupByStatsResponse - Throws:
org.springframework.web.server.ResponseStatusException-400quando o request e invalido ou501quando o recurso nao suporta stats
-
timeSeriesStats
@PostMapping("/stats/timeseries") public org.springframework.http.ResponseEntity<RestApiResponse<TimeSeriesStatsResponse>> timeSeriesStats(@RequestBody TimeSeriesStatsRequest<FD> request) Calcula serie temporal agregada sobre o conjunto filtrado.A resposta segue a superficie canonica de time-series da plataforma, permitindo dashboards e componentes metadata-driven sem reimplementar contratos por dominio. O filtro principal do recurso continua valendo, e a agregacao e controlada por granularidade, campo temporal e metrica.
- Parameters:
request- request canonico com filtro, campo temporal, granularidade e metrica- Returns:
- envelope com
TimeSeriesStatsResponse - Throws:
org.springframework.web.server.ResponseStatusException-400quando o request e invalido ou501quando o recurso nao suporta stats
-
distributionStats
@PostMapping("/stats/distribution") public org.springframework.http.ResponseEntity<RestApiResponse<DistributionStatsResponse>> distributionStats(@RequestBody DistributionStatsRequest<FD> request) Calcula distribuicoes agregadas sobre o conjunto filtrado do recurso.Esta operacao cobre cenarios como histogramas, faixas e distribuicoes quantitativas usando o contrato estatistico canonico da plataforma. Ela evita proliferacao de endpoints customizados e mantém a mesma semantica de filtro do restante da superficie do recurso.
- Parameters:
request- request canonico com filtro, campo numerico e definicao da distribuicao- Returns:
- envelope com
DistributionStatsResponse - Throws:
org.springframework.web.server.ResponseStatusException-400quando o request e invalido ou501quando o recurso nao suporta stats
-
getAll
@GetMapping("/all") public org.springframework.http.ResponseEntity<RestApiResponse<List<org.springframework.hateoas.EntityModel<D>>>> getAll()Lista todos os registros aplicando @DefaultSortColumn quando nenhum sort é enviado.- Returns:
- envelope de resposta com a lista de entidades como
RestApiResource
-
getByIds
@GetMapping("/by-ids") public org.springframework.http.ResponseEntity<List<D>> getByIds(@RequestParam(name="ids",required=false) List<ID> ids) Recupera múltiplos registros pelos seus identificadores em uma única chamada.Ideal para interfaces corporativas que precisam pré-carregar registros selecionados. Retorna uma lista vazia quando nenhum ID é informado e preserva a ordem dos parâmetros recebidos. O número máximo de IDs permitidos pode ser configurado pela propriedade
praxis.query.by-ids.max(padrão: 200).- Parameters:
ids- lista de identificadores a serem buscados- Returns:
- lista de DTOs na mesma ordem dos IDs solicitados
- Throws:
org.springframework.web.server.ResponseStatusException- se a quantidade de IDs exceder o limite configurado
-
filterOptions
@PostMapping("/options/filter") public org.springframework.http.ResponseEntity<org.springframework.data.domain.Page<OptionDTO<ID>>> filterOptions(@RequestBody FD filterDTO, @RequestParam(name="page",defaultValue="0") int page, @RequestParam(name="size",defaultValue="20") int size, @RequestParam org.springframework.util.MultiValueMap<String, String> queryParams) Retorna opções paginadas para popular selects.Problema que resolve
- Fornecer payload leve (id/label) com filtros e paginação para componentes de seleção.
Como funciona internamente
- Valida
size≤praxis.pagination.max-size. - Aplica fallback de ordenação do service quando
sortausente. - Label resolvido por
@OptionLabelou heurísticas doBaseCrudService.getOptionMapper().
Uso em DTOs (@UISchema)
Para referenciar este endpoint em um campo de seleção, anote o DTO com
@UISchemaconfigurandoendpoint,valueFieldedisplayField:// 1) Consumindo OptionDTO diretamente (payload leve) @UISchema( controlType = FieldControlType.SELECT, endpoint = ApiPaths.Catalog.CATEGORIAS + "/options/filter", valueField = "id", // OptionDTO.id displayField = "label" // OptionDTO.label (via @OptionLabel/heurísticas) ) private Long categoriaId; // 2) Alternativa: usar /filter do recurso (DTO completo) e mapear os campos @UISchema( controlType = FieldControlType.SELECT, endpoint = ApiPaths.Catalog.CATEGORIAS + "/filter", // ✅ sempre /filter valueField = "id", displayField = "nome" ) private Long categoriaId;Dica: para combos dependentes, a propriedade
endpointsuporta interpolação de parâmetros com${campo}.- Parameters:
filterDTO- critérios de filtropage- número da página (0‑based)size- tamanho da páginaqueryParams- parâmetros adicionais (ex.:sort)- Returns:
- página de
OptionDTO - Throws:
org.springframework.web.server.ResponseStatusException- quandosizeexcede o limite (422)
-
filterOptionSourceOptions
@PostMapping("/option-sources/{sourceKey}/options/filter") public org.springframework.http.ResponseEntity<org.springframework.data.domain.Page<OptionDTO<Object>>> filterOptionSourceOptions(@PathVariable String sourceKey, @RequestBody FD filterDTO, @RequestParam(name="search",required=false) String search, @RequestParam(name="includeIds",required=false) List<String> includeIds, @RequestParam(name="page",defaultValue="0") int page, @RequestParam(name="size",defaultValue="20") int size, @RequestParam org.springframework.util.MultiValueMap<String, String> queryParams) Retorna opcoes paginadas a partir de uma fonte canonica registrada emoption-sources.Diferentemente de
filterOptions(GenericFilterDTO, int, int, MultiValueMap), aqui a origem das opcoes nao precisa coincidir com a entidade principal do recurso. Isso permite compor combos e seletores derivados sem quebrar a semantica canonica da plataforma.A consulta suporta filtro do recurso atual, busca textual opcional, inclusao de IDs previamente selecionados e ordenacao paginada.
- Parameters:
sourceKey- chave da fonte canonica registradafilterDTO- filtro principal do recursosearch- busca textual opcional aplicada pela implementacao da fonteincludeIds- IDs que devem ser preservados no resultado para reidratacao de selecaopage- pagina atualsize- tamanho da paginaqueryParams- parametros adicionais, comosort- Returns:
- pagina de
OptionDTO - Throws:
org.springframework.web.server.ResponseStatusException-404quando a fonte nao existe,422quando o tamanho excede o limite ou501quando a capacidade nao e suportada
-
getOptionsByIds
@GetMapping("/options/by-ids") public org.springframework.http.ResponseEntity<List<OptionDTO<ID>>> getOptionsByIds(@RequestParam(name="ids",required=false) List<ID> ids) Retorna opções (id/label) para uma coleção de IDs, preservando a ordem solicitada.Uso em DTOs (@UISchema)
Use em conjunto com
/options/filterpara reidratar valores já salvos quando a UI precisa montar o valor inicial de selects multivalorados:// Busca dinâmica enquanto o usuário digita endpoint = ApiPaths.Catalog.CATEGORIAS + "/options/filter" valueField = "id" displayField = "label" // Reidratação (IDs → id/label) ao abrir a tela GET ApiPaths.Catalog.CATEGORIAS + "/options/by-ids?ids=10&ids=7"- Parameters:
ids- lista de identificadores (opcional)- Returns:
- lista de
OptionDTOna mesma ordem dos IDs - Throws:
org.springframework.web.server.ResponseStatusException- quando a quantidade de IDs excede o limite configurado (422)
-
getOptionSourceOptionsByIds
@GetMapping("/option-sources/{sourceKey}/options/by-ids") public org.springframework.http.ResponseEntity<List<OptionDTO<Object>>> getOptionSourceOptionsByIds(@PathVariable String sourceKey, @RequestParam(name="ids",required=false) List<String> ids) Reidrata opcoes por IDs a partir de uma fonte canonica registrada emoption-sources.O endpoint e voltado principalmente para carregamento inicial de selects e multiselects quando a UI possui apenas os IDs persistidos e precisa recuperar os pares
id/labelna mesma ordem da selecao original.- Parameters:
sourceKey- chave da fonte canonica registradaids- identificadores a reidratar- Returns:
- lista de
OptionDTOna ordem solicitada - Throws:
org.springframework.web.server.ResponseStatusException-404quando a fonte nao existe,422quando a quantidade de IDs excede o limite ou501quando a capacidade nao e suportada
-
getById
@GetMapping("/{id}") public org.springframework.http.ResponseEntity<RestApiResponse<D>> getById(@PathVariable ID id) Recupera um registro pelo seu identificador.Alem do payload principal, o endpoint pode anexar links HATEOAS para navegacao entre leitura, filtros, atualizacao e exclusao, de acordo com as capacidades habilitadas pelo recurso. Isso torna a resposta adequada tanto para integradores HTTP quanto para consumidores metadata-driven.
- Parameters:
id- identificador do registro- Returns:
- envelope de resposta com o DTO e links relevantes
- Throws:
jakarta.persistence.EntityNotFoundException- quando o registro nao e encontrado
-
create
@PostMapping public org.springframework.http.ResponseEntity<RestApiResponse<D>> create(@Valid @RequestBody D dto) Cria um novo registro a partir do DTO informado.O fluxo converte o DTO em entidade, delega a persistencia ao service e retorna
201 Createdcom headerLocationapontando para o recurso criado. O corpo segue o envelope canonicoRestApiResponse, alinhado ao restante da API.- Parameters:
dto- DTO de entrada validado- Returns:
201 CreatedcomLocationderivado da entidade persistida e envelope de resposta contendo o DTO salvo
-
update
@PutMapping("/{id}") public org.springframework.http.ResponseEntity<RestApiResponse<D>> update(@PathVariable ID id, @Valid @RequestBody D dto) Atualiza um registro existente.O endpoint reutiliza o mesmo mapeamento DTO → entidade do fluxo de criacao, mas delega a persistencia ao service com o identificador explicito do recurso. Em respostas bem-sucedidas, o cliente recebe o DTO atualizado dentro do envelope padronizado da plataforma.
- Parameters:
id- identificador do registro a atualizardto- DTO com os novos dados, sujeito a validacao- Returns:
- envelope de resposta com o DTO atualizado
- Throws:
jakarta.persistence.EntityNotFoundException- quando o registro nao e encontrado
-
delete
@DeleteMapping("/{id}") public org.springframework.http.ResponseEntity<Void> delete(@PathVariable ID id) Exclui um registro pelo seu identificador.A semantica segue o padrao REST classico da plataforma: em caso de sucesso retorna
204 No Content; em caso de ausencia do recurso, a implementacao do service pode sinalizar o erro apropriado para a camada HTTP.- Parameters:
id- identificador do registro a excluir- Returns:
204 No Content
-
deleteBatch
@DeleteMapping("/batch") public org.springframework.http.ResponseEntity<Void> deleteBatch(@RequestBody List<ID> ids) Exclui multiplos registros pelos seus identificadores.O endpoint e util para operacoes de selecao em massa vindas de grids e listas administrativas. A lista de IDs deve ser enviada no corpo da requisicao; quando nula ou vazia, a resposta e
400 Bad Requestpara evitar sucesso silencioso de uma operacao vazia.- Parameters:
ids- lista de IDs a excluir- Returns:
204 No Contentquando a exclusao em lote e aceita
-
getSchema
Redireciona para o endpoint de schemas filtrados do recurso atual.Em vez de duplicar a logica de resolucao de schema em cada controller, esta operacao calcula a URL correta para
/schemas/filteredcom base no path e na operacao representativa do recurso, preservando a semantica metadata-driven canonica da plataforma.Isso permite que consumidores descubram o contrato x-ui do recurso diretamente a partir da superficie do proprio controller, sem precisar reconstruir manualmente query parameters.
- Returns:
- resposta
302 FoundcomLocationapontando para o schema do recurso
-
toEntityModel
-
toResourceModel
-
linkToSelf
Link para GET /{id}. -
linkToAll
protected org.springframework.hateoas.Link linkToAll()Link para GET /all. -
linkToFilter
protected org.springframework.hateoas.Link linkToFilter()Link para GET /filter. -
linkToFilterCursor
protected org.springframework.hateoas.Link linkToFilterCursor()Link para POST /filter/cursor. -
linkToCreate
protected org.springframework.hateoas.Link linkToCreate()Link para POST /. -
linkToUpdate
Link para PUT /{id}. -
linkToDelete
Link para DELETE /{id}. -
allowCreate
protected boolean allowCreate() -
allowUpdate
protected boolean allowUpdate() -
allowDelete
protected boolean allowDelete() -
linkToDocs
protected org.springframework.hateoas.Link linkToDocs()Link para documentação (ex.: Swagger UI). -
linkToUiSchema
protected org.springframework.hateoas.Link linkToUiSchema(String methodPath, String operation, String schemaType) Gera um link HATEOAS para a documentação filtrada de um schema específico da API, baseado no caminho e na operação HTTP fornecidos.Este método constrói uma URL relativa que aponta para o endpoint de documentação filtrada, permitindo que os consumidores da API acessem a descrição detalhada do schema correspondente a uma operação específica em um determinado caminho.
Exemplo de Uso:
// Gerar link para a operação GET no caminho "/dados-pessoa-fisica/all" Link docsLink = linkToUiSchema("/all", "get", "response");- Parameters:
methodPath- O caminho específico do método dentro da API para o qual a documentação do schema é necessária. Deve começar com "/" e representar um dos endpoints existentes (por exemplo, "/filter", "/all", "/{id}").Exemplos:
"/filter"para a operação de filtro de registros."/all"para listar todos os registros."/{id}"para operações específicas de um registro identificado por ID.
operation- A operação HTTP associada ao caminho fornecido. Deve ser um dos métodos válidos do HTTP, como"get","post","put","delete", etc.schemaType- Tipo de schema desejado:response(padrão) ourequest.Exemplos:
"get"para operações de leitura."post"para operações de criação."put"para operações de atualização."delete"para operações de exclusão.
- Returns:
- Um objeto
Linkcontendo a URL relativa para a documentação filtrada do schema correspondente à operação e caminho fornecidos. O rel deste link é definido como"schema", indicando que ele aponta para a documentação do schema. - Throws:
IllegalArgumentException- Se omethodPathestiver vazio ou malformado.IllegalStateException- Se ocorrer um erro ao construir a URL para a documentação filtrada.- See Also:
-