É bom retornar HTML de uma API JSON?


25

No meu projeto atual, sou responsável pela implementação de um serviço que envolve o consumo de APIs RESTful recém-criadas, documentadas como suportando apenas o JSON.

O cliente faz solicitações consistentemente com o cabeçalho de aceitação de 'application / json' e o tipo de conteúdo de 'application / json'. No entanto, alguns pontos de extremidade enviam uma resposta com um tipo de conteúdo HTML, mesmo um corpo HTML. Para mim, essa é claramente a abordagem errada e nunca pode ser justificada.

Ao longo do projeto, essa mesma prática foi aplicada a dois fornecedores diferentes e a dois serviços diferentes. Eu me vi justificando por que os serviços precisavam ser alterados. Os fornecedores declararam que o cliente deve lidar com isso e até minha biblioteca REST de escolha foi questionada (RestEasy) porque não lida com isso por padrão 'pronto para uso'.

Este tem sido um grande ponto de frustração. Não consigo encontrar muitas referências para apoiar meu argumento, presumo que isso seja porque o ponto é discutível, pois é tão óbvio.

A questão é: estou perdendo alguma coisa? eu estou sendo pedante sobre isso? É bom ter uma API JSON que não tenha um tipo de conteúdo de application / json nesse cenário? Referências seriam apreciadas. Como você resolve essa situação do ponto de vista comercial?


1
Por tipo de contexto, você quer dizer o cabeçalho HTTP do tipo de conteúdo?
Marjan Venema

Sim, estou me referindo ao cabeçalho do tipo de conteúdo HTTP. Editado.
Phillip.darley

Bem, pelo menos eles não devem chamá-lo de "API REST JSON" quando é uma API REST HTML.
Bergi

Respostas:


28

Quando você está enviando um acceptcabeçalho solicitando um tipo de mídia específico, o servidor não deve enviar outra coisa e, certamente, não com um código de status 200 OK

Partida Restpatterns.org :

Se nenhum campo de cabeçalho Aceitar estiver presente, presume-se que o cliente aceite todos os tipos de mídia. Se um campo de cabeçalho Accept estiver presente, e se o servidor não puder enviar uma resposta aceitável de acordo com o valor combinado do campo Accept, o servidor DEVE enviar uma resposta 406 (não aceitável).

(Ênfase minha)

O Restpatterns.org utiliza isso do padrão HTTP real: Definições de campo do cabeçalho - Aceitar

Em resumo: você não está sendo pedante. Os serviços não estão seguindo o padrão HTTP se estiverem retornando HTML quando o cabeçalho de aceitação diz especificamente para eles retornarem application/jsone nada mais.


1
+1. Concordo com esta resposta, mas infelizmente a palavra shouldé usada repetidamente nas especificações HTTP. Temos que iniciar uma petição online para que essas palavras sejam alteradas must.
Reactgular

3
@MarjanVenema "should" está correto porque na seção 10 do mesmo rfc há uma observação: "Servidores HTTP / 1.1 têm permissão para retornar respostas que não são aceitáveis ​​de acordo com os cabeçalhos de aceitação enviados na solicitação. Em alguns casos, isso pode até seja preferível enviar uma resposta 406 ".
Imel96

1
Se um cliente solicitar um recurso que realmente não tenha uma representação JSON, não importa o quanto ele queira JSON, talvez seja melhor receber outra coisa definitiva; você não tem garantia de obter um 406. O importante é que o servidor descreva qual é realmente o tipo de conteúdo da resposta.
Donal Fellows

6
@DonalFellows: Não, seria melhor serem informados do que realmente é o caso. O servidor não deve apenas enviar de volta algo que considere adequado, mas enviar uma resposta 406 Não aceitável, conforme declarado no padrão. Lembre-se de que, quando o cliente solicita especificamente um tipo de mídia e não especifica nenhum fallback, provavelmente não há como processar qualquer outro tipo de mídia.
Marjan Venema

2
@ imel96: o fato de a internet nunca ter sido rigorosa é exatamente o que levou às dificuldades de tentar oferecer suporte a vários navegadores e aos servidores que agora são forçados a permanecer compatíveis com o html inválido, pois há muito disso por aí (e infelizmente ainda está sendo criado).
Marjan Venema

9

O que você quer dizer com "API JSON RESTful" - acho que o primeiro problema aqui é que você está misturando conceitos (ou possivelmente alguém entre você e seus colegas técnicos em seus "fornecedores").

Uma API RESTful (se você não está falando realmente no nível 1 ou algo no nível 3 ou acima, cf http://martinfowler.com/articles/richardsonMaturityModel.html ) é sobre a maneira como você interage com a API, e não sobre o formato do conteúdo enviado ou recebido de. Nem sequer se trata de protocolos ou mecanismos de transporte ...

Da mesma forma, uma API JSON é uma API que suporta o uso de JSON como um formato de dados - pode ou não ser tranqüila, pode ou não ser implementada usando HTTP e (e este é o ponto principal) pode ou não ser compatível com JSON exclusivamente.

Uma boa API executando sobre HTTP (é razoável supor que, no contexto, você esteja falando de uma API exposta por HTTP) deve permitir que você solicite conteúdo em vários formatos, e esses formatos podem (e possivelmente deveriam) incluir HTML e também JSON e XML. Por quê? Bem, isso tornaria o aprendizado da API muito mais fácil, conceitualmente fornece um UX instantâneo baseado em navegador para qualquer finalidade e assim por diante ...

A questão interessante se torna se minha API, que suporta uma variedade de formatos de conteúdo, é chamada sem ser informado sobre o formato que o cliente espera e que formato deve retornar ...? Isso tende a um argumento religioso - mas o HTML oferece ao provedor a opção de incluir informações úteis (como "lembre-se de definir o cabeçalho de aceitação de conteúdo").

Para responder à pergunta de uma API, uma que seja tranqüila e outra que suporte json deve absolutamente poder retornar HTML se esse for o conteúdo solicitado.


1
Aceito os dois pontos e editei minha pergunta de acordo. O fato de o serviço ser RESTful não é relevante e eu detalhei que o cliente aceita 'application / json' em cada solicitação.
Phillip.darley

Eu diria que "API JSON RESTful" tem um significado muito óbvio.
gnasher729

1
Eu diria que os meus professores colocar uma enorme quantidade de esforço para ter certeza que entendi por que "nunca assumir" era uma parte fundamental de ser um bom programador
Murph

5

O cliente faz solicitações consistentemente com o cabeçalho de aceitação de 'application / json' e o tipo de conteúdo de 'application / json'

Sim, é a coisa certa a fazer, mas não significa que o fornecedor se importe. Embora eu compreenda totalmente sua frustração, porque também acho que um serviço JSON sempre deve dar uma resposta JSON, mas há muitos exemplos em que esse não é o caso.

Ao longo do projeto, essa mesma prática foi aplicada a dois fornecedores diferentes e a dois serviços diferentes. Eu me vi justificando por que os serviços precisavam ser alterados. Os fornecedores declararam que o cliente deve lidar com isso e até minha biblioteca REST de escolha foi questionada (RestEasy) porque não lida com isso por padrão 'pronto para uso'.

Bem, eu tenho que concordar com o fornecedor. É o serviço deles e, desde que documentem claramente os casos especiais para usá-lo, não será possível impor que eles o alterem. É uma desvantagem para eles, pois os desenvolvedores demoram a adotar sua API e, se ouvissem o que os desenvolvedores precisam, eles a alterariam, mas, infelizmente, não há regra de que eles devem seguir os padrões.

A questão é: estou perdendo alguma coisa?

Os cabeçalhos de solicitação não significam nada, a menos que sejam interrompidos corretamente na outra extremidade. Eu sei que, se eu desenvolver uma API da web usando PHP, vá para o inferno com os cabeçalhos de solicitação. Eu posso responder com o que eu quiser. Visto que um serviço configurado no IIS com C # oferece um tratamento muito mais fácil dos cabeçalhos de solicitação, seu tipo e o tipo de resposta. Tem muito a ver com as ferramentas que o fornecedor usou para criar a API.

Eu estou sendo pedante sobre isso?

Sim e não. Tenho amigos de desenvolvedores que não conseguiriam superar isso. Eles ficariam tão fixados pelo problema e incapazes de prosseguir com outras tarefas até que a API funcionasse da maneira que eles esperavam. Agora isso está sendo pedante.

É um problema porque o fornecedor criou "mais trabalho" para concluir suas tarefas. Qualquer um ficaria frustrado com isso. Eu sei que seria.

É bom ter uma API JSON que não tenha um tipo de conteúdo de application / json nesse cenário?

Absolutamente, mas não é uma boa prática.

Um cliente pode apenas dizer ao servidor qual é o tipo de contexto de um request. Não tem capacidade de impor um tipo de conteúdo para o response. O cliente pode apenas informar ao servidor que fará acceptuma coleção de possíveis tipos de conteúdo.

Definições de campo de cabeçalho

O campo Aceitar cabeçalho da solicitação pode ser usado para especificar certos tipos de mídia aceitáveis ​​para a resposta. Os cabeçalhos de aceitação podem ser usados ​​para indicar que a solicitação é especificamente limitada a um pequeno conjunto de tipos desejados, como no caso de uma solicitação de uma imagem em linha.

É possível que um cliente solicite uma imagem de image/jpeg, mas o servidor responde com text/htmle um código de status 404se a imagem não foi encontrada. Os servidores também podem responder incorretamente. Existem muitos sites Wordpress por aí que respondem com text/htmle código de status 200para arquivos não encontrados.

Agora, essa é toda a prática MAU por parte do servidor. O que estou tentando lhe dizer é que é absolutamente possível e acontece com frequência. As pessoas não sabem o que estão fazendo quando configuram essas coisas.

Referências seriam apreciadas. Como você resolve essa situação do ponto de vista comercial?

Eu já tive esse problema em alguns projetos. Você postenvia dados JSON para o servidor e ele retorna uma resposta JSON ou HTML.

Realmente não é grande coisa saber que tipo estava na resposta. Se o primeiro caractere for {ou [você pode assumir JSON. Se for, <você pode assumir HTML. É assim que eu lidei com isso no passado. Às vezes, o programador que escreveu a API sabe tudo sobre os cabeçalhos HTTP. Tudo volta como text/htmlrespostas. Se você tiver sorte, eles têm o Apache configurado como padrão, o text/plainque às vezes pode ajudar.

Esses problemas existem e continuarão a existir no futuro. A comunicação entre servidores é de longe uma atividade não regulamentada. Não existe um órgão de administração que expulse um fornecedor de uma união para um servidor que fornece respostas HTTP incorretas.


Isso está alinhado com a resposta de @Marjan Venema, mas outro ponto importante que você menciona é a documentação desse comportamento. Para aumentar minha frustração, o fornecedor não documentou esse comportamento. O tipo de conteúdo varia dependendo do estado da sessão, mas apenas a resposta JSON está documentada.
Phillip.darley
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.