REST - Tradeoffs entre negociação de conteúdo via Accept header versus extensions

40

Estou trabalhando no design de uma API RESTful. Sabemos que queremos retornar JSON e XML para qualquer recurso fornecido. Eu estava pensando que faríamos algo assim:

GET /api/something?param1=value1
Accept:  application/xml (or application/json)

No entanto, alguém excluiu o uso de extensões para isso, assim:

GET /api/something.xml?parm1=value1 (or /api/something.json?param1=value1)

Quais são as compensações com essas abordagens? É melhor confiar no cabeçalho de aceitação quando uma extensão não é especificada, mas honrar extensões quando especificado? Existe uma desvantagem nessa abordagem?

    
por Brandon Linton 14.03.2012 / 03:50
fonte

4 respostas

38

Isto, "No entanto, filosoficamente - a primeira abordagem é a única abordagem.", e esta "A abordagem RESTful oficial apropriada é usar Accept: header." são amplamente percebidos para ser o caso, mas também são absolutamente incorretos .

Aqui está um pequeno trecho de Roy Fielding (que definiu REST) ...

"seção 6.2.1 não diz que a negociação de conteúdo deve ser usado o tempo todo. " cite

Essa conversa em particular está no contexto do cabeçalho 'Accept-Language:', mas o mesmo se aplica igualmente ao cabeçalho 'Accept:', como ficou claro mais tarde em sua resposta ...

"Não tenho ideia de por que as pessoas não podem ver o segundo e terceiro link na primeira página

link

que apontam para as duas edições do PDF. "

O que ele quer dizer é que não há problema em usar diferentes endpoints para diferentes representações dos mesmos dados de origem. (Nesse caso, um endpoint .html e dois endpoints .pdf diferentes.)

Também em uma discussão semelhante, desta vez sobre as virtudes do uso de parâmetros de consulta versus o uso de extensões de arquivos para diferentes tipos de mídia ...

"É por isso que eu sempre prefiro extensões. Nenhuma das opções tem nada a ver com o REST. " cite

Novamente, isso é um pouco diferente das extensões Aceitar vs. nome do arquivo, mas a posição de Fielding ainda é clara.

Resposta - isso realmente não importa muito. Os trade-offs entre os dois não são muito significativos e ambos são estilos aceitáveis.

    
por 18.10.2012 / 16:59
fonte
9

A abordagem RESTful oficial apropriada é usar Accept: header.

No entanto, você deve tomar cuidado para não quebrar a capacidade de armazenamento em cache, que é um dos requisitos do REST. Você precisa ter Vary: Accept header e cache que o entenda. No mundo ideal você o teria, mas na vida real sua milhagem pode variar. Então a segunda solução não é tão limpa, mas pode ser mais prática.

Além disso, observe que alguns navegadores muito antigos costumavam ignorar os cabeçalhos, contando com a extensão.

    
por 14.03.2012 / 15:25
fonte
9

Tecnicamente, isso realmente não importa - o seu servidor web poderá passar o processo apropriadamente como parece. (Eu estou supondo isso, mas não parece um showstopper).

No entanto, filosoficamente - a primeira abordagem é a única abordagem. No REST, a URL na verdade aponta apenas para um URI - que é apenas um recurso. Pense por um momento nesse recurso como objeto em programação orientada a objetos. Você fala com este recurso através de apenas 4 métodos (também conhecidos como GET / POST / PUT / DELETE - ou se qualquer coisa que o transporte permitir), mas esse método não se torna descrição do objeto . Da mesma forma, os aspectos que o valor de retorno não é o URI. O objeto ainda é algo e não algo.xml ou algo.json

Suponha que se você não quiser usar o cabeçalho Accept, mas se você ainda quiser ser verdadeiramente REST filosoficamente, não me importarei com algo como:

GET /api/something?parm1=value1&return_type=xml

ao contrário de

GET /api/something.xml?parm1=value1 (or /api/something.json?param1=value1)

Mas como eu disse, essa diferença é apenas filosófica.

    
por 14.03.2012 / 15:26
fonte
0

@vartec: acho que você está errado

O princípio RESTful oficial apropriado diz que nada deve ser escondido nos cabeçalhos HTTP, pois é o URI que é exposto ou referenciado, qualquer detalhe sobre o pedido / resposta deve ser fornecido como parte do URI

Por isso, é altamente recomendável evitar o uso do cabeçalho para detalhes sobre o pedido & resposta, e ater a

 GET /api/something.xml?parm1=value1 (or /api/something.json?param1=value1)

Não consigo encontrar as referências rapidamente, mas vou postar de volta com elas (na verdade, você pode consultar o manual de publicação do O'reilly "Serviços Web RESTful" ( link ) que confirma o mesmo

    
por 16.03.2012 / 11:42
fonte