1
resposta

[Sugestão] Warning - Serialização do PageImpl

Os endpoints do projeto que estão retornando instâncias da classe Page do Spring Data estão disparando a seguinte mensagem de warning:

Serializing PageImpl instances as-is is not supported, meaning that there is no guarantee about the stability of the resulting JSON structure!
For a stable JSON structure, please use Spring Data's PagedModel (globally via @EnableSpringDataWebSupport(pageSerializationMode = VIA_DTO)) or Spring HATEOAS and Spring Data's PagedResourcesAssembler as documented in https://docs.spring.io/spring-data/commons/reference/repositories/core-extensions.html#core.web.pageables.

A partir do Spring Data 3.1 essa mensagem foi inserida para alertar e desencoragajar os desenvolvedores de continuarem renderizando, com a biblioteca Jackson, diretamente o Page com sua implementação PageImpl pois é um tipo de domínio da API e pode ser alterado por qualquer razão afetando sua representação em JSON e consequentemente quebrar aplicações clientes em uma atualização de versão do framework.

A atual versão possui a seguinte complexa estrutura:

{
    "content": [
        {
            "id": 4,
            "nome": "xpto",
            "email": "xpto@xpto.com",
            "cpf": "56778124040",
            "telefone": "22222"
        }
    ],
    "pageable": {
        "pageNumber": 0,
        "pageSize": 1,
        "sort": {
            "empty": false,0
            "sorted": true,
            "unsorted": false
        },
        "offset": 0,
        "paged": true,
        "unpaged": false
    },
    "last": true,
    "totalPages": 1,
    "totalElements": 1,
    "size": 1,
    "number": 0,
    "sort": {
        "empty": false,
        "sorted": true,
        "unsorted": false
    },
    "numberOfElements": 1,
    "first": true,
    "empty": false
}

Essa estrutura já foi alterada em diversas ocasiões.

A documentação do Spring sugere a utilização do Spring HATEOAS, porém aponta duas soluções convenientes empregando somente o Spring Data para esse aviso:

I) Utilizar o org.springframework.data.web.PagedModel do Spring Data que encapsula o as instâncias de Page em uma representação simplificada da Spring HATEOAS, mas omitindo links de navegação.

Ex:

@GetMapping
    public ResponseEntity<PagedModel<PacienteListagemDTO>> listar(@PageableDefault(sort = {"nome"}) Pageable pageable) {
        PagedModel<PacienteListagemDTO> pacientesPage = new PagedModel<>((pacienteRepository.findAll(pageable)).map(PacienteListagemDTO::new));
        return ResponseEntity.ok(pacientesPage);
    }

Dessa forma a instância Page é embutida em uma PagedModel, e a estrutura do JSON possui um campo page expondo apenas os metadados essenciais para a paginação:

{
    "content": [
        {
            "id": 4,
            "nome": "xpto",
            "email": "xpto@xpto.com",
            "cpf": "56778124040",
            "telefone": "22222"
        }
    ],
    "page": {
        "size": 1,
        "number": 0,
        "totalElements": 1,
        "totalPages": 1
    }
}

II) Criar uma classe de configuração global que traduz PageImpl em PagedModel simplesmente habilitando o @EnableSpringDataWebSupport.

Ex:

package med.voll.api.webinfra;

import org.springframework.context.annotation.Configuration;
import org.springframework.data.web.config.EnableSpringDataWebSupport;

@Configuration
@EnableSpringDataWebSupport(pageSerializationMode = EnableSpringDataWebSupport.PageSerializationMode.VIA_DTO)
public class JacksonConfiguration {
}

Dessa forma não é necessário qualquer intervenção sobre os controllers ficando o processo de tradução totalmente automático e transparente ao desenvolvedor.

1 resposta

Oi,

Excelente observação sobre o warning de serialização do PageImpl! 👍

Você identificou um ponto crucial para a estabilidade da sua API.

A mensagem de aviso, introduzida no Spring Data 3.1, realmente nos alerta sobre a fragilidade de expor diretamente a estrutura interna do PageImpl no JSON, pois ela pode mudar entre versões do framework e quebrar a compatibilidade com clientes. 🤔

Para saber mais: Documentação oficial do Spring Data sobre paginação e serialização.

Continue explorando e aprofundando seus conhecimentos! 💪