Existem padrões ou práticas recomendadas para estruturar respostas JSON a partir de uma API? Obviamente, os dados de cada aplicativo são diferentes, de modo que não estou preocupado com isso, mas com o "modelo de resposta", se preferir. Um exemplo do que quero dizer:
Pedido bem sucedido:
{
"success": true,
"payload": {
/* Application-specific data would go here. */
}
}
Pedido com falha:
{
"success": false,
"payload": {
/* Application-specific data would go here. */
},
"error": {
"code": 123,
"message": "An error occurred!"
}
}
Respostas:
Sim, existem alguns padrões (embora algumas liberdades na definição de padrão) surgiram:
Existem também formatos de descrição da API JSON:
fonte
Guia JSON do Google
Retorno de resposta de sucesso
data
Retorno de resposta a erro
error
e se seu cliente for JS, você poderá
if ("error" in response) {}
verificar se há um erro.fonte
error
, a página do Google dá um exemplo dissoEu acho que um padrão defacto realmente não surgiu (e pode nunca). Mas, independentemente, aqui está a minha opinião:
Pedido bem sucedido:
Pedido com falha:
Vantagem: Os mesmos elementos de nível superior nos casos de sucesso e erro
Desvantagem: nenhum código de erro, mas se você quiser, pode alterar o status para ser um código (de êxito ou falha) ou pode adicionar outro item de nível superior chamado "código".
fonte
messages
que é uma matriz de mensagens em vez de uma única string.fail
para problemas típicos de validação, enquantoerror
são usados apenas com fatais, como erros de banco de dados.200
nos cabeçalhos, por que você precisa de umstatus
campo? basta retornar o objeto de dados diretamente. Você sabe que isso pode causar problemas adicionais em linguagens FE digitadas como o TypeScript.Supondo que sua pergunta seja sobre o design de serviços da Web REST e mais precisamente sobre sucesso / erro.
Eu acho que existem 3 tipos diferentes de design.
Use apenas o código de status HTTP para indicar se houve um erro e tente limitar-se aos códigos padrão (geralmente deve ser suficiente).
Use HTTP Status + json body (mesmo que seja um erro). Defina uma estrutura uniforme para erros (ex: código, mensagem, motivo, tipo, etc) e use-a para erros, se for um sucesso, basta retornar a resposta json esperada.
Esqueça o status http (ex: sempre status 200), sempre use json e adicione na raiz da resposta um responseValid booleano e um objeto de erro (código, mensagem, etc.) que será preenchido se houver algum erro, caso contrário, os outros campos (sucesso) são preenchidos.
Prós: O cliente lida apenas com o corpo da resposta que é uma string json e ignora o status (?).
Contras: O menos padrão.
Cabe a você escolher :)
Dependendo da API, eu escolheria 2 ou 3 (eu prefiro 2 para json rest apis). Outra coisa que experimentei ao projetar a API REST é a importância da documentação para cada recurso (url): os parâmetros, o corpo, a resposta, os cabeçalhos etc + exemplos.
Também recomendo que você use jersey (implementação de jax-rs) + genson (biblioteca de ligação de dados java / json). Você só precisa soltar genson + jersey no seu caminho de classe e o json é automaticamente suportado.
EDITAR:
A solução 2 é a mais difícil de implementar, mas a vantagem é que você pode lidar bem com exceções e não apenas com erros de negócios; o esforço inicial é mais importante, mas você vence a longo prazo.
A solução 3 é fácil de implementar no lado do servidor e no cliente, mas não é tão agradável quanto você terá que encapsular os objetos que deseja retornar em um objeto de resposta que também contenha o erro responseValid +.
fonte
O RFC 7807: Detalhes do Problema para APIs HTTP é no momento a coisa mais próxima que temos de um padrão oficial.
fonte
A seguir está o formato json que o instagram está usando
fonte
Não serei tão arrogante em afirmar que esse é um padrão, então usarei o formulário "Prefiro".
Prefiro resposta concisa (ao solicitar uma lista de / articles, quero uma matriz de artigos JSON).
Nos meus projetos, eu uso o HTTP para o relatório de status, um 200 retorna apenas a carga útil.
400 retorna uma mensagem do que estava errado com a solicitação:
Retorne 404 se o modelo / controlador / URI não existir
Se houver um erro no processamento do meu lado, retornarei 501 com uma mensagem:
Pelo que vi, algumas estruturas REST-ish tendem a seguir essa linha.
Fundamentação da petição :
JSON deve ser um formato de carga útil , não é um protocolo de sessão. Toda a idéia de cargas úteis detalhadas de sessão vem do mundo XML / SOAP e de várias opções equivocadas que criaram esses designs inchados. Depois que percebemos que tudo era uma grande dor de cabeça, o ponto principal do REST / JSON era beijá-lo e aderir ao HTTP. Eu não acho que exista algo remotamente padrão no JSend e, especialmente, não entre os mais detalhados entre eles. O XHR reagirá à resposta HTTP, se você usar o jQuery para o seu AJAX (como a maioria faz), poderá usar
try
/catch
edone()
/fail()
callbacks para capturar erros. Não vejo como os relatórios de status encapsulantes no JSON são mais úteis do que isso.fonte
Pelo que vale a pena, faço isso de maneira diferente. Uma chamada bem-sucedida apenas possui os objetos JSON. Não preciso de um objeto JSON de nível superior que contenha um campo de sucesso indicando true e um campo de carga útil que tenha o objeto JSON. Acabo de retornar o objeto JSON apropriado com um 200 ou o que for apropriado no intervalo 200 para o status HTTP no cabeçalho.
No entanto, se houver um erro (algo na família 400), retornarei um objeto de erro JSON bem formado. Por exemplo, se o cliente estiver postando um usuário com um endereço de e-mail e número de telefone e um deles estiver malformado (ou seja, não posso inseri-lo no meu banco de dados subjacente), retornarei algo como isto:
Os bits importantes aqui são que a propriedade "field" deve corresponder exatamente ao campo JSON que não pôde ser validado. Isso permite que os clientes saibam exatamente o que deu errado com sua solicitação. Além disso, "message" está no local da solicitação. Se os "emailAddress" e "phoneNumber" forem inválidos, a matriz "errors" conterá entradas para ambos. Um corpo de resposta 409 (Conflict) JSON pode ter a seguinte aparência:
Com o código de status HTTP e esse JSON, o cliente tem tudo o que precisa para responder a erros de maneira determinística e não cria um novo padrão de erro que tenta concluir a substituição dos códigos de status HTTP. Observe que isso ocorre apenas no intervalo de 400 erros. Para qualquer coisa na faixa de 200, posso apenas retornar o que for apropriado. Para mim, geralmente é um objeto JSON do tipo HAL, mas isso realmente não importa aqui.
A única coisa que pensei em adicionar foi um código de erro numérico nas entradas da matriz "errors" ou na raiz do próprio objeto JSON. Mas até agora não precisamos disso.
fonte
Eles não concordam com os demais formatos de resposta da API de grandes gigantes de software - Google, Facebook, Twitter, Amazon e outros, embora muitos links tenham sido fornecidos nas respostas acima, onde algumas pessoas tentaram padronizar o formato de resposta.
Como as necessidades das APIs podem diferir, é muito difícil envolver todos e concordar com algum formato. Se você tem milhões de usuários usando sua API, por que alteraria seu formato de resposta?
A seguir, é minha opinião sobre o formato de resposta inspirado no Google, Twitter, Amazon e algumas postagens na Internet:
https://github.com/adnan-kamili/rest-api-response-format
Arquivo Swagger:
https://github.com/adnan-kamili/swagger-sample-template
fonte
O ponto do JSON é que ele é completamente dinâmico e flexível. Dobre-o como quiser, porque é apenas um conjunto de objetos e matrizes JavaScript serializados, enraizados em um único nó.
Qual é o tipo do nó raiz, depende de você, se você envia os metadados junto com a resposta, depende de você definir o tipo MIME
application/json
ou deixá-lo comotext/plain
é seu ( desde que você saiba como lidar com os casos extremos).Crie um esquema leve que você gosta.
Pessoalmente, eu descobri que a análise de rastreamento e mp3 / ogg servir e imagem-gallery servir e de mensagens de texto e de rede-pacotes para jogos online e de blog-posts e blogue-comenta todos têm requisitos muito diferentes em termos do que é enviado e o que é recebido e como eles devem ser consumidos.
Portanto, a última coisa que eu gostaria, ao fazer tudo isso, é tentar fazer com que cada um esteja em conformidade com o mesmo padrão padrão, que é baseado no XML2.0 ou algo assim.
Dito isto, há muito a ser dito sobre o uso de esquemas que fazem sentido para você e são bem pensados.
Basta ler algumas respostas da API, anotar o que você gosta, criticar o que não gosta, anotar essas críticas e entender por que elas o atrapalham da maneira errada e depois pensar em como aplicar o que aprendeu ao que você precisa.
fonte
O JSON-RPC 2.0 define um formato padrão de solicitação e resposta e é uma lufada de ar fresco depois de trabalhar com APIs REST.
fonte
code
campo fosse uma String. Felizmente, a especificação nos permite inserir as informações que queremos nodata
campo do erro . Nos meus projetos JSON-RPC, normalmente uso um código numérico único para todos os erros da camada de aplicativo (em oposição a um dos erros de protocolo padrão). Em seguida, coloquei as informações detalhadas do erro (incluindo um código de sequência indicando o tipo de erro real) nodata
campo.Para aqueles que virão mais tarde, além da resposta aceita que inclui a API HAL, JSend e JSON, eu adicionaria algumas outras especificações que vale a pena examinar:
fonte
A estrutura básica sugerida parece bem, mas o objeto de erro conforme definido é muito limitado. Geralmente, não se pode usar um único valor para expressar o problema e, em vez disso, é necessária uma cadeia de problemas e causas .
Eu fiz uma pequena pesquisa e descobri que o formato mais comum para retornar erros (exceções) é uma estrutura deste formulário:
Esse é o formato proposto pelo padrão de dados OASIS Oata OData e parece ser a opção mais padrão existente no mercado, no entanto, neste momento, não parece haver altas taxas de adoção de nenhum padrão. Este formato é consistente com a especificação JSON-RPC.
Você pode encontrar a biblioteca de código aberto completa que implementa isso em: Mendocino JSON Utilities . Esta biblioteca suporta os objetos JSON, bem como as exceções.
Os detalhes são discutidos na minha postagem no blog sobre Tratamento de erros na API REST JSON
fonte
Não existe outro padrão de infracção à lei ou fora da lei que não seja o senso comum. Se abstrairmos isso como duas pessoas conversando, o padrão é a melhor maneira de entenderem-se com precisão em palavras mínimas e em tempo mínimo. No nosso caso, 'palavras mínimas' está otimizando a largura de banda para a eficiência do transporte e 'entendido com precisão' é a estrutura da eficiência do analisador; que acaba por acabar com os menos dados e a estrutura comum; para que ele possa atravessar um orifício e ser analisado através de um escopo comum (pelo menos inicialmente).
Quase todos os casos sugeridos, vejo respostas separadas para os cenários 'Sucesso' e 'Erro', o que é uma ambiguidade para mim. Se as respostas são diferentes nesses dois casos, por que realmente precisamos colocar um sinalizador de 'Sucesso' lá? Não é óbvio que a ausência de 'Erro' seja um 'Sucesso'? É possível ter uma resposta em que 'Sucesso' é VERDADEIRO com um conjunto de 'Erro'? Ou a propósito, 'Sucesso' é FALSO sem 'Erro' definido? Apenas uma bandeira não é suficiente? Eu preferiria ter apenas o sinalizador 'Erro', porque acredito que haverá menos 'Erro' do que 'Sucesso'.
Além disso, devemos realmente fazer do 'Erro' uma bandeira? E se eu quiser responder com vários erros de validação? Portanto, acho mais eficiente ter um nó 'Erro' com cada erro como filho desse nó; onde um nó 'Erro' vazio (conta com zero) denota um 'Sucesso'.
fonte
Melhor resposta para APIs da Web que podem ser facilmente compreendidas pelos desenvolvedores de dispositivos móveis.
Isto é para resposta "Sucesso"
Isto é para resposta "Erro"
fonte