Class AbstractCrudController<E,D,ID,FD extends GenericFilterDTO>

java.lang.Object
org.praxisplatform.uischema.controller.base.AbstractCrudController<E,D,ID,FD>
Type Parameters:
E - Tipo da Entidade JPA
D - 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

public abstract class AbstractCrudController<E,D,ID,FD extends GenericFilterDTO> extends Object

🏗️ Controller Base com Auto-Detecção de Path e Integração OpenAPI

✨ O que vem pronto (por números)

GET /{id}
GET /all
POST /filter
POST /filter/cursor
POST /locate
GET /by-ids
POST /options/filter
GET /options/by-ids
POST /option-sources/{sourceKey}/options/filter
GET /option-sources/{sourceKey}/options/by-ids
POST /stats/group-by
POST /stats/timeseries
POST /stats/distribution
POST /
PUT /{id}
DELETE /{id}
DELETE /batch
GET /schemas/schemas/filtered

26 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:

  1. Sem parâmetro sort: Aplica ordenação de @DefaultSortColumn na entidade
  2. Com parâmetro sort: Usa ordenação específica, ignora @DefaultSortColumn
  3. 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:
 @Entity
 public 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

  1. @ApiResource.value[] / path[]: primeira prioridade
  2. @RequestMapping.value[] / path[]: segunda prioridade
  3. Configuração obrigatória: emite warning se não encontrar anotações e marca o path como pendente
See Also:
  • 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):

      1. 🎯 @ApiResource.value[] / path[]: Extrai o primeiro path declarado na meta-anotação
      2. 📋 @RequestMapping.value[] / path[]: Extrai o primeiro path declarado no controller
      3. ⚠️ 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 @RequestMapping ou @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 @RequestMapping ou @ApiResource. Não há fallback automático para evitar configurações implícitas.

    • getService

      protected abstract BaseCrudService<E,D,ID,FD> getService()
      Retorna o serviço base (CRUD) que será usado internamente.
      Returns:
      instância do serviço CRUD
    • toDto

      protected abstract D toDto(E entity)
      Converte uma entidade JPA em seu DTO correspondente.
      Parameters:
      entity - a entidade a ser convertida
      Returns:
      o DTO correspondente
    • toEntity

      protected abstract E toEntity(D dto)
      Converte um DTO em sua entidade JPA correspondente.
      Parameters:
      dto - o DTO a ser convertido
      Returns:
      a entidade correspondente
    • getControllerClass

      protected Class<? extends AbstractCrudController<E,D,ID,FD>> 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

      protected abstract ID getEntityId(E entity)
      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

      protected abstract ID getDtoId(D dto)
      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

      protected String 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

      protected String 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
    • setBasePath

      protected void setBasePath(String basePath)
      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 includeIds na primeira página sem duplicar itens nas seguintes.

      Como funciona internamente

      Parameters:
      filterDTO - DTO contendo os critérios de filtro
      page - número da página (inicia em 0)
      size - quantidade de registros por página
      includeIds - 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âmetro size excede o limite configurado (422)

      Erros comuns

      • 422: size acima do limite configurado.
      • 400: validação do body (campos inválidos).
    • 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

      Parameters:
      filterDTO - critérios de filtro
      after - cursor para avançar
      before - cursor para retroceder
      size - quantidade de registros
      queryParams - parâmetros de query adicionais (ex.: sort)
      Returns:
      página baseada em cursor
      Throws:
      org.springframework.web.server.ResponseStatusException - quando size excede o limite (422) ou a operação não é suportada (501)

      Erros comuns

      • 501: service não implementa keyset.
      • 422: size acima 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

      Parameters:
      filterDTO - critérios de filtro
      id - identificador do registro de interesse
      size - tamanho de página utilizado para derivar a página a partir do índice absoluto
      queryParams - parâmetros de query adicionais (ex.: sort)
      Returns:
      resposta com LocateResponse contendo índice e página
      Throws:
      org.springframework.web.server.ResponseStatusException - quando size excede o limite (422) ou a operação não é suportada (501)

      Erros comuns

      • 501: service não implementa localização.
      • 422: size acima 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 - 400 quando o request e invalido ou 501 quando 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 - 400 quando o request e invalido ou 501 quando 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 - 400 quando o request e invalido ou 501 quando 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 sizepraxis.pagination.max-size.
      • Aplica fallback de ordenação do service quando sort ausente.
      • Label resolvido por @OptionLabel ou heurísticas do BaseCrudService.getOptionMapper().

      Uso em DTOs (@UISchema)

      Para referenciar este endpoint em um campo de seleção, anote o DTO com @UISchema configurando endpoint, valueField e displayField:

      
       // 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 endpoint suporta interpolação de parâmetros com ${campo}.

      Parameters:
      filterDTO - critérios de filtro
      page - número da página (0‑based)
      size - tamanho da página
      queryParams - parâmetros adicionais (ex.: sort)
      Returns:
      página de OptionDTO
      Throws:
      org.springframework.web.server.ResponseStatusException - quando size excede 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 em option-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 registrada
      filterDTO - filtro principal do recurso
      search - busca textual opcional aplicada pela implementacao da fonte
      includeIds - IDs que devem ser preservados no resultado para reidratacao de selecao
      page - pagina atual
      size - tamanho da pagina
      queryParams - parametros adicionais, como sort
      Returns:
      pagina de OptionDTO
      Throws:
      org.springframework.web.server.ResponseStatusException - 404 quando a fonte nao existe, 422 quando o tamanho excede o limite ou 501 quando 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/filter para 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 OptionDTO na 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 em option-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/label na mesma ordem da selecao original.

      Parameters:
      sourceKey - chave da fonte canonica registrada
      ids - identificadores a reidratar
      Returns:
      lista de OptionDTO na ordem solicitada
      Throws:
      org.springframework.web.server.ResponseStatusException - 404 quando a fonte nao existe, 422 quando a quantidade de IDs excede o limite ou 501 quando 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 Created com header Location apontando para o recurso criado. O corpo segue o envelope canonico RestApiResponse, alinhado ao restante da API.

      Parameters:
      dto - DTO de entrada validado
      Returns:
      201 Created com Location derivado 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 atualizar
      dto - 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 Request para evitar sucesso silencioso de uma operacao vazia.

      Parameters:
      ids - lista de IDs a excluir
      Returns:
      204 No Content quando a exclusao em lote e aceita
    • getSchema

      @GetMapping("/schemas") public org.springframework.http.ResponseEntity<Void> 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/filtered com 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 Found com Location apontando para o schema do recurso
    • toEntityModel

      protected org.springframework.hateoas.EntityModel<D> toEntityModel(D dto)
    • toResourceModel

      protected RestApiResource<D> toResourceModel(D dto)
    • linkToSelf

      protected org.springframework.hateoas.Link linkToSelf(ID id)
      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

      protected org.springframework.hateoas.Link linkToUpdate(ID id)
      Link para PUT /{id}.
    • linkToDelete

      protected org.springframework.hateoas.Link linkToDelete(ID id)
      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) ou request.

      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 Link contendo 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 o methodPath estiver vazio ou malformado.
      IllegalStateException - Se ocorrer um erro ao construir a URL para a documentação filtrada.
      See Also:
      • Link
      • UriComponentsBuilder