A partir de 2019, a LIB do Protheus passou a assumir que a transmissão de grandes volumes de dados ( > 1Mbyte ) em resposta às requisições ao REST Server, devem ser feitos via chunked e de preferência de forma compactada.
Quando o conteúdo for compactado, sempre deve ser enviado chunked para evitar o cálculo do tamanho do pacote após a compactação.
Esse tipo de envio consiste em dar respostas parciais para que o client não fique aguardando por muito tempo e também que ele tenha a possibilidade de ir processando de forma parcial.
Como ativar o chunked:
Ao requisitar um conteúdo que tenha mais de 1 Mbyte, automaticamente* o envio será chunked.
*Obs.: Para que o envio possa ser feito de forma parcial, a classe tipo WSRESTFUL criada no desenvolvimento da API deve ir executando o método SetResponse() também de forma parcial, conforme o conteúdo é gerado. Caso o conteúdo seja todo armazenado em uma string e apenas no final ser executado o SetResponse(), o envio não será chunked.
Exemplo de uso correto para possibilitar o chunked:
::SetResponse('{"id": "' + cId + '", "items": [')
For i := 1 To 100
If ! lFirst
::SetResponse(',')
EndIf
::SetResponse('{"sub_id":"' + Str(i) + '"}')
lFirst := .F.
Next
::SetResponse(']}')
Como ativar o gzipped:
Para que a requisição utilize o recurso do gzip, basta enviar o seguinte header na requisição: Accept-Encoding: gzip
Obs.: A resposta é realizada em partes e de forma compactada, porém não é percebido pelo usuário pois os clients, como o cURL por exemplo, recebem, descompactam e juntam a informação antes da exibição.
Como funciona:
Ao responder uma requisição de forma tradicional, é enviado o cabeçalho Content-Length que informa o tamanho total do body de resposta.
No modo chunked esse cabeçalho com tamanho não é enviado e no lugar dele é enviado o Transfer-Encoding: chunked.
Quando a mensagem está compactada é enviado o header Content-Encoding: gzip.
Além desses cabeçalhos, o body é iniciado com o tamanho (em hexadecimal) do pedaço (chunk) que está sendo enviado e uma quebra de linha (CRLF) e aí então o conteúdo parcial do body.
Esse envio pode ser repedido inúmeras vezes e quando a resposta completa já tiver sido transmitida, é enviada uma última parte zerada (tamanho zero e quebra de linha) para indicar o fim.