Eu tenho um ponto de extremidade da API que retorna algumas estatísticas. Atualmente, a resposta se parece com:
Opção 1:
{
"stats": [
{
"name": "some-stats-key1",
"value": 10
},
{
"name": "some-stats-key2",
"value": 20
}
],
... other keys
}
Mas isso parece um pouco complexo e eu como fazê-lo:
Opção 2:
{
"stats": {
"some-stats-key1": 10,
"some-stats-key2": 20
}
... other keys
}
Entendo que a opção 1 é mais fácil de ser estendida, mas menos confortável para os usuários. Que outros problemas posso enfrentar usando uma dessas opções? Ou devo criar uma solução híbrida como:
Opção 3:
{
"stats": {
"some-stats-key1": {
"name": "some-stats-key1",
"value": 10
},
"some-stats-key2": {
"name": "some-stats-key2",
"value": 20
},
},
... other keys
}
As chaves "some-stats-key1" e "some-stats-key2" são apenas valores internos e espera-se que o usuário da API as mapeie em nomes legíveis usando a documentação. Todas as chaves são únicas.
A ordem das "estatísticas" não é importante.
O caso de uso típico é apenas para obter todas as estatísticas, combinar chaves com nomes legíveis e mostrar como uma tabela em uma página da web. Mas atualmente não posso dizer se ninguém precisará apenas de uma parte das estatísticas posteriormente.
Existe uma prática recomendada para esse problema?
Array.forEach
e outrasArray
funções. Seus outros exemplos adicionarão complexidade extra a operações do tipo array, o que poderia dificultar a vida de seus clientesRespostas:
Eu optaria pela opção 2. Se o consumidor da API se converter
some-stats-key1
em algo legível, isso provavelmente significa que ele / ela tem uma lista de valores nos quais está interessado (digamossome-stats-key1
esome-stats-key3
) e iterará sobre essa lista. Ao escolher um objeto JSON, ele será desserializado como um dicionário / mapa que fornece uma consulta conveniente para o consumidor da API.Isso será mais complicado com a opção 1, onde o consumidor precisa iterar sobre a matriz JSON ou pré-criar seu próprio dicionário com chaves interessantes.
A opção 3 é um pouco detalhada demais para mim, a duplicação dos nomes das chaves simplesmente não me agrada.
Se a extensibilidade for uma preocupação, você sempre poderá publicar uma v2 da sua API retornando algo como
e mantenha a v1 para compatibilidade com versões anteriores. Manter a compatibilidade com versões anteriores em uma única versão da API pode ser uma PITA real, se você não tiver controle completo sobre como a API é consumida. Vi um consumo de uma API da minha 'quebra' quando adicionei um par de valor-chave extra (opcional) (ou seja, não alterei a estrutura).
fonte
As duas opções têm as vantagens clássicas da Lista versus Mapa.
1) A lista permite entradas duplicadas e mantém a ordem. Se esses recursos forem importantes, use a Lista, mesmo que seja mais desajeitada.
2) O mapa não permite duplicatas. A manutenção da ordem é possível com um pouco de trabalho extra. A grande vantagem é mais simplicidade no formato dos dados, e a busca por um elemento específico é trivial.
Minha escolha padrão é sempre o mapa mais simples, mas YMMV.
fonte
Quando obtenho dados de uma API, sempre verifico se tudo está como eu esperava. Portanto, meu esforço para processar seus dados consiste na verificação e no processamento real.
No caso 1, tenho que verificar: a. Existe uma matriz. b. Todos os itens da matriz são dicionários. c. Todo dicionário tem uma chave "nome". d. Todos os valores para a chave "nome" são exclusivos.
No caso 3, tenho que verificar: a. Existe um dicionário. b. Todos os valores no dicionário são dicionários. c. Cada dicionário possui uma chave "nome" com um valor que corresponde à chave no dicionário externo. Um pouco melhor.
No caso 2, tenho que verificar: a. Existe um dicionário.
(Claro que tenho que verificar os valores também). Portanto, o seu caso 2 requer a menor quantidade de verificação do meu lado. Na verdade, recebo uma estrutura de dados que é imediatamente utilizável.
O único problema com 2 é que não é extensível. Portanto, em vez de enviar o valor como um número, você pode enviar {value: 10}, que pode ser estendido de forma compatível com versões anteriores.
Redundância é ruim. A única coisa que a redundância atinge é me fazer escrever mais código e me forçar a pensar no que devo fazer se os bits redundantes não concordarem. A versão 2 não possui redundância.
fonte
Desde que você solicitou boas práticas para o design da API:
Portanto, dadas as estruturas que você propôs, a estrutura que eu implementaria seria semelhante a esta
fonte
re:overly complex
parece muito simples para mim. Sigo o ponto 1 porque faz com que toda a lógica de serialização mantenha convenções consistentes. O número de itens em um conjunto de respostas é um detalhe de implementação da interface de serviço. Para comunicar itens "3" em um conjunto, esses três itens são agrupados de maneira mais conveniente em uma matriz. "1" é um número.re: example from a well known web API
google.comre: example from a framework
qualquer coisa que fala ANSI SQL