Formato de resposta padrão da API JSON?

Existem normas ou melhores práticas para estruturar respostas JSON a partir de uma API? Obviamente, os dados de cada aplicação são diferentes, pelo que não estou preocupado com isso, mas sim com o "boilerplate de resposta", Se você quiser. Um exemplo do que quero dizer:

pedido bem sucedido:

{
  "success": true,
  "payload": {
    /* Application-specific data would go here. */
  }
}

pedido mal-sucedido:

{
  "success": false,
  "payload": {
    /* Application-specific data would go here. */
  },
  "error": {
    "code": 123,
    "message": "An error occurred!"
  }
}
Author: Laurel, 2012-10-09

12 answers

Sim, surgiram algumas normas (embora algumas liberdades na definição de norma):
  1. a API JSON - a API JSON abrange também a criação e actualização de recursos, e não apenas respostas.
  2. JSend - simples e provavelmente o que já estás a fazer.
  3. Protocolo de OData JSON - Muito Complicado.
  4. HAL - Como OData, mas com o objectivo de ser HATEOAS como.

Também há JSON API formatos de descrição:

 498
Author: Adam Gent, 2016-05-26 10:13:51

Guia JSON do Google

Resposta de sucesso data
{
  "data": {
    "id": 1001,
    "name": "Wing"
  }
}
Resposta de erro retorno error
{
  "error": {
    "code": 404,
    "message": "ID not found"
  }
}

E se o seu cliente é JS, pode usar if ("error" in response) {} para verificar se há erro.

 129
Author: Steely Wing, 2017-02-27 09:55:03

Acho que um padrão de defacto não surgiu realmente (e talvez nunca). Mas, seja como for, Aqui está a minha opinião:

Pedido bem sucedido:

{
  "status": "success",
  "data": {
    /* Application-specific data would go here. */
  },
  "message": null /* Or optional success message */
}

Pedido mal-sucedido:

{
  "status": "error",
  "data": null, /* or optional error payload */
  "message": "Error xyz has occurred"
}

Vantagem: os mesmos elementos de topo nos casos de sucesso e de erro

Desvantagem: sem código de erro, mas se você quiser, você pode alterar o estado para ser um código (sucesso ou falha),- ou - você pode adicionar outro item de nível superior chamado "código".

 85
Author: trungly, 2012-10-19 18:05:34

Assumindo que a sua pergunta é sobre o design de webservices REST e mais precisamente sobre o sucesso/erro.

Acho que há três tipos diferentes de design.
  1. Utilize apenas o código de estado HTTP para indicar se houve um erro e tentar limitar-se aos padrões (normalmente deve ser suficiente).

      É um padrão independente da sua api.
  2. = = ligações externas = =
  3. Utilizar HTTP Status + JSON body (mesmo que seja um erro). Definir uma estrutura uniforme para erros (ex: código, mensagem, razão, tipo, etc) e usá-lo para erros, se for um sucesso, então apenas retornar a resposta json esperada.

    • prós: continua a ser o padrão à medida que usa os códigos de estado HTTP existentes e devolve um json a descrever o erro (fornece mais informações sobre o que aconteceu).
    • Cons: o JSON de saída irá variar dependendo se for um erro ou sucesso.
  4. Esqueça o http status (ex: sempre de status 200), sempre usar o json e adicionar na raiz da resposta de um booleano responseValid e um objeto de erro (código,mensagem,etc) que será preenchido se for um 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(?).

    • Cons: menos padrao.

Cabe-te a ti escolher:)

Dependendo da API eu escolheria 2 ou 3 (eu prefiro 2 para a API json rest). Outra coisa que eu experimentei em projetar a API de descanso é a importância da documentação para cada recurso (url): os parâmetros, o corpo, a resposta, os cabeçalhos etc + exemplos.

Também te recomendo que uses jersey (implementação jax-rs) + genson (biblioteca de dados java/json). Você só tem que cair genson + jersey no seu classpath e 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 só erros de negócios, o esforço inicial é mais importante, mas você ganha a longo prazo.

  • A Solução 3 é a mais fácil de implementar tanto no lado do servidor e no cliente, mas não é tão agradável como você terá que encapsular os objetos que você quer retornar em uma resposta objecto que contém também o erro responseValid+.

 63
Author: eugen, 2017-03-24 04:56:32

Não serei tão arrogante ao afirmar que este é um padrão, por isso vou usar o formulário "eu prefiro".

Eu prefiro resposta terse (ao solicitar uma lista de /artigos quero uma lista de artigos JSON).

Nos meus desenhos eu uso HTTP para o relatório de Estado, um 200 devolve apenas a carga.

400 retorna uma mensagem do que estava errado com o pedido:

{"message" : "Missing parameter: 'param'"}

Volta 404 se o modelo/controlador/URI não existir

Se houvesse erro com o processamento do meu lado, eu volto 501 com uma mensagem:
{"message" : "Could not connect to data store."}
Pelo que vi, alguns quadros de descanso tendem a ser assim.

Fundamentação:

O JSON é suposto ser um formato de carga útil , não é um protocolo de sessão. Toda a idéia de sessões verbosas-ish payloads vem do mundo XML / SOAP e várias escolhas equivocadas que criaram esses projetos inchados. Depois de percebermos que era uma enorme dor de cabeça., o objetivo do REST / JSON era beijá-lo, e aderir a HTTP. Eu não acho que haja nada remotamente [[36]}padrão em qualquer um dos JSend e especialmente não com o mais verboso entre eles. XHR irá reagir à resposta HTTP, se você usar jQuery para o seu AJAX (como a maioria) você pode usar try/catch e done()/fail() chamadas para capturar erros. Não vejo como encapsular relatórios de Estado na JSON é mais útil do que isso.

 17
Author: Bojan Markovic, 2014-04-16 05:40:25

A seguir está o formato json que o instagram está a usar

{
    "meta": {
         "error_type": "OAuthException",
         "code": 400,
         "error_message": "..."
    }
    "data": {
         ...
    },
    "pagination": {
         "next_url": "...",
         "next_max_id": "13872296"
    }
}
 15
Author: Muhammad Amin, 2013-03-13 08:19:54
Se vale de alguma coisa, faço isto de forma diferente. Uma chamada bem sucedida só tem os objectos JSON. Não preciso de um objeto JSON de nível superior que contenha um campo de sucesso indicando verdadeiro e um campo de carga útil que tenha o objeto JSON. Eu apenas devolvo 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) eu devolvo um objeto de erro JSON bem formado. Por exemplo, se o cliente está postando um usuário com um endereço de E-mail e número de telefone e um deles é malformado (ou seja, eu não posso inseri-lo na minha base de dados subjacente) eu vou retornar algo como isso:

{
  "description" : "Validation Failed"
  "errors" : [ {
    "field" : "phoneNumber",
    "message" : "Invalid phone number."
  } ],
}

Bits importantes aqui são que a propriedade "campo" deve corresponder ao campo JSON exactamente que não pôde ser validado. Isso permite que os clientes saibam exatamente o que correu mal com seu pedido. Além disso," mensagem " está no local do pedido. Se tanto o "emailAddress" e "phoneNumber" fossem inválidos, então o array "errors" conteria entradas para ambos. Um corpo de resposta JSON 409 (conflito) pode parecer assim:

{
  "description" : "Already Exists"
  "errors" : [ {
    "field" : "phoneNumber",
    "message" : "Phone number already exists for another user."
  } ],
}

Com o código de estado HTTP e este JSON o cliente tem tudo o que precisa para responder a erros de uma forma determinística e não cria um novo padrão de erro que tenta completar os códigos de estado HTTP. Note, estes só acontecem para o intervalo de 400 erros. Por qualquer coisa na faixa dos 200, Posso devolver o que for apropriado. Para mim é muitas vezes um JSON parecido com HAL. protesto, mas isso não importa aqui.

A única coisa que pensei em Adicionar era um código de erro numérico, quer nos itens da matriz de" erros " ou na raiz do objeto JSON em si. Mas até agora não precisamos.

 11
Author: robert_difalco, 2014-04-28 18:45:46

O RFC 7807: detalhes do problema para o HTTP APIs é no momento a coisa mais próxima que temos de um padrão oficial.

 8
Author: Berislav Lopac, 2016-04-03 20:39:32
A questão do JSON é que é completamente dinâmico e flexível. Dobre - o para qualquer capricho que você gostaria, porque é apenas um conjunto de objetos e arrays JavaScript serializados, enraizados em um único nó.

Qual é o tipo do rootnode depende de si, o que ele contém depende de si, se você envia metadados juntamente com a resposta depende de si, se você configura o tipo mime para application/json ou se o deixa como text/plain depende de si (desde que saiba como lidar com a aresta vez).

Construa um esquema leve de que goste.
Pessoalmente, eu descobri que o google analytics-acompanhamento e mp3/ogg servir e imagem-galeria de servir e de mensagens de texto e de rede-pacotes para jogos online, e o blog-posts e blog-comentários todos os tem muito diferentes requisitos de em termos do que é enviado e o que é recebido e como eles devem ser consumidos. Por isso, a última coisa que eu queria, ao fazer tudo isso, era tentar fazer com que cada um se conformasse. para o mesmo padrão boilerplate, que é baseado em XML2.0 ou somesuch. Dito isto, há muito a dizer sobre o uso de esquemas que fazem sentido. tu. e são bem pensados.
Basta ler algumas respostas API, anotar o que você gosta, criticar o que você não faz, escrever essas críticas para baixo e entender por que eles esfregam você da maneira errada, e então pensar em como aplicar o que você aprendeu para o que você precisa.
 7
Author: Norguard, 2012-10-09 19:06:53
[[1]] o seu não é um acordo sobre os formatos de Resposta da API de outros 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 da API podem diferir, é muito difícil colocar todos a bordo e concordar com algum formato. Se você tem milhões de usuários usando sua API, por que você mudaria seu formato de resposta?

Seguir é o meu assuma o formato de resposta inspirado no Google, Twitter, Amazon e alguns posts na internet:

Https://github.com/adnan-kamili/rest-api-response-format

Ficheiro Swagger:

Https://github.com/adnan-kamili/swagger-sample-template

 7
Author: adnan kamili, 2016-08-02 09:13:05

JSON-RPC 2.0 define um formato padrão de pedido e resposta, e é uma lufada de ar fresco após trabalhar com APIs de descanso.

 4
Author: dnault, 2014-06-11 22:09:18

A melhor resposta para as apis web que podem facilmente compreender pelos programadores móveis.

Isto é para a resposta de "sucesso"

{  
   "ReturnCode":"1",
   "ReturnMsg":"Successfull Transaction",
   "ReturnValue":"",
   "Data":{  
      "EmployeeName":"Admin",
      "EmployeeID":1
   }
}

Isto é para a resposta de "Erro"

{
    "ReturnCode": "4",
    "ReturnMsg": "Invalid Username and Password",
    "ReturnValue": "",
    "Data": {}
}
 0
Author: Manish Vadher, 2018-08-10 04:40:31