Em seu novo post – Slow REST Tim Bray tenta responder a seguinte questão:
Em um contexto RESTful, como se lida as operações de mudança de estado (POST, PUT, DELETE) que possuem latência substancial e imprescindível?
Tim descreve três abordagens diferentes para esta situação, desenvolvidas como parte do Project Kenai na forma de uma proposta – Trabalhando Operações de Requisições Assíncronas. Estas abordagens incluem:
- Abordagem baseada em recursos que têm:
Um novo modelo de recurso "Status "..., com os seguintes campos:
Este objeto de recurso pode ser usado da seguinte forma:- "uri "– URI no qual o cliente pode executar operações GET para sondar para conclusão. Cada operação assíncrona aceita receberá um único status URI, então múltiplas operações podem ser iniciadas e acompanhadas em uma vez.
- "status" – Código integer descrevendo o status de conclusão (0=sucesso, nonzero= código de erro), devolvido apenas quando “progresso” retorna 100.
- "message" – Mensagem ajustado para relatar o estado de conclusão para o usuário humano, retornado somente quando o “progress” retorna 100.
- "progress" – Indicador de percentual complet, o qual deve retornar 100 somente quando a operação foi completada (com ou sem o sucesso).
Para toda e qualquer operação PUT/POST/DELETE, devolvemos “202 em andamento” e um objeto “Status” ,... designado para possibilitar que desenvolvedores tornem fácil de monitorar.
- Implementação relâmpago – mantendo o canal HTTP aberto para o tempo de um request de longa duração.
- A resposta HTTP inicial DEVE conter o status 202 (“Accepted”)... e todo o corpo contendo o objeto Status inicial para esta operação. Neste objeto, os campos “uri” e “progress” DEVEM ser populados, e o campo “progresso” DEVE conter o valor 0 (zero) indicando que a operação está começando.
- O valor URI devolvido na resposta inicial DEVEM responder para requisições GET devolvendo uma versão alterada do objeto Status. Normalmente, o campo “progress” crescerá até 100, porém, NÃO PODE ser definido como 100 até que a operação termine.
- Quando a operação terminar (com ou sem sucesso), uma representação final do objeto Status DEVE ser retornada, com o campo “progress” igual a 100, e o campo “status” igual 0 (zero) para término com sucesso ou um outro valor para término sem sucesso.
- "Web hooks" – usando duas invocações de uma via independente – uma para iniciar uma operação de longa duração e outra para notificar o requisitante que está terminada.
- A representação de entrada da requisição da operação PODE conter um campo “webhook”, cujo valor é um URI onde o cliente espera uma chamada de volta. Se este campo não está presente, nenhum retorno “webhook” será executado.
- Quando a operação termina (com ou sem sucesso), o servidor executará uma requisição POST para o URI do “webhook”, com... um entity que contém o objeto Status final desta operação
- O cliente pode comparar o aviso de término com a requisição original, comparando o valor do campo “uri” com o retornado no Status inicial, ou provendo um webhook URI único para cada requisição assíncrona.
Tim finaliza seu post abordando:
… “Slow REST” é um padrão que aparecerá demais novamente no futuro quando deveríamos pensar em uma receita padronizada para abordá-lo.
Seu post ocasionou diversas respostas, uma em particular de William Vambenepe ,compara os problemas e soluções propostos por Tim com os definidos nos padrões WS*, especificamente WSRF e WS-Notifications. De acordo com William:
WSFR chega a cobrir este caso de uso (slow create), mas entre WS-ResourceLifetime e WS-Notification se vê alguns casos de uso similares no trabalho (qual BTW você poderá executar na seqüência). Soma-se este WS-MakeConnection (parte do WS-RX), sua idéia de “webhooks” se torna muito mais prática... Eu sempre tive a intuição que “REST” e “WS-(Death)Star” se tornariam mais próximas.
Apesar das muitas diferenças (algumas reais, algumas “religiosas”) entre REST e WS*, ambos miram em resolver problemas reais do dia-a-dia e, conseqüentemente, enfrentam os mesmos desafios. Aprendendo experiências e implementações uma da outra irá definitivamente melhorar ambas.