Pergunta

Eu estou trabalhando na interface de uma aplicação de página única e eu tenho que lista um número de alunos.A cada estudante é anexado a um determinado user_id Isto é o que a API retorna para todas as funções de usuário (superadmin, administrador, professor, aluno) quando eu executar GET /students:

{
  address: null
  class_id: 184
  class_name: "I B"
  date_of_birth: null
  first_name: "first"
  gender: null
  grade: 1
  id: 192
  last_name: "last"
  nationality: null
  place_of_birth: null
  ranking_by_class: 0
  ranking_by_school: 0
  registration_number: null
  user_id: 238
}

Eu estou trabalhando o superadmin do papel no momento em que eu estou na necessidade de dados adicionais a partir de cada aluno (subscription_type), que só está disponível no GET /users/:id

Então, quando eu estou listagem de 20 a 30 alunos em uma página via GET /students/, a fim de obter a subscription_type, Eu vou também precisa fazer 20-30 extra pedidos, um para cada aluno.

Eu falei para a API de cara sobre isso e foi-me dito que a inclusão de dados adicionais em students "não é Tranquilo maneira de fazer isso", "isso vai diminuir os tempos de resposta até mais" e que "30 pedidos de pesar menos do que um pedaço grande".

Eu não sei nada sobre o trabalho de uma API, então eu realmente não posso ter uma palavra a dizer, mas estou louco para pensar que 30 pedidos de carregamento de uma página é ridícula?

Então, qual o próximo passo?Posso ir em frente e executar as solicitações extras?Ele deve separar as respostas para cada função de usuário e incluir apenas as coisas que eu preciso para cada função?O que é o forma correta de tratar isso?

Foi útil?

Solução

Embora estritamente falando, a API cara é correto, seguir Tranquilo evangelho de forma muito estrita, pode levar a ineficiências como 1+N problema criado pelo purista implementação.Um conceito-chave em design RESTful é que os recursos não têm para mapear diretamente para objetos de domínio.Quando a concepção de recursos deve-se olhar para as situações de uso.No super admin cenário, parece que quando o cliente solicita uma coleção de students e ele também normalmente ou sempre necessita de dados de users, especificamente subscription_type.O modelo de objeto é claramente normalizado como deve ser, mas que não dizem que os recursos devem ser, ou deve ser sempre.

Há um par de diferentes padrões de eu ter usado para fazer semelhante cenários mais eficiente.O que (se) aplicar depende de como os recursos são consumidos pelos clientes.

Composto De Recursos

Esta é a combinação de todos ou parte de dois ou mais objetos de domínio (por exemplo, student e user) em um único recurso.

Desde que todos os students são, presumivelmente, também users, você poderia incluir a totalidade ou parte dos dados do usuário no recurso do aluno, conforme apropriado.

GET /students

{
  address: null
  class_id: 184
  class_name: "I B"
  date_of_birth: null
  first_name: "first"
  gender: null
  grade: 1
  id: 192
  last_name: "last"
  nationality: null
  place_of_birth: null
  ranking_by_class: 0
  ranking_by_school: 0
  registration_number: null
  user_id: 238
  subscription_type: "foo"
}

Recursos Relacionados

(Semelhante a uma outra resposta) Esta é uma técnica onde o cliente pode indicar que quer relacionadas com o recurso incluído na resposta.Isto é particularmente útil no "tem um" tipo de relação em que o modelo de domínio.Ele permite que o cliente essencialmente carregamento lento ou carrega o recurso.

GET /students

{
  address: null
  class_id: 184
  class_name: "I B"
  date_of_birth: null
  first_name: "first"
  gender: null
  grade: 1
  id: 192
  last_name: "last"
  nationality: null
  place_of_birth: null
  ranking_by_class: 0
  ranking_by_school: 0
  registration_number: null
  user_id: 238
}

GET /students?include_user=true

{
  address: null
  class_id: 184
  class_name: "I B"
  date_of_birth: null
  first_name: "first"
  gender: null
  grade: 1
  id: 192
  last_name: "last"
  nationality: null
  place_of_birth: null
  ranking_by_class: 0
  ranking_by_school: 0
  registration_number: null
  user_id: 238
  user:
  {
   id: 238
   subscription_type: "foo"
   ...
  }
}

Outras dicas

Você tem dois problemas aqui, que não devem ser amarrados juntos - Uma é a dados retornados por cada usuário para que a chamada de índice (/alunos), e o outro é o processo de autorização, que deve determinar quais os dados de um determinado usuário pode ser exposto.

Sobre o problema de dados - eu não acho que há uma regra específica a seguir.Ele depende totalmente de seu aplicativo requisitos.Se o subscription_type campo é geralmente desnecessário, você pode considerar a passagem de um parâmetro de consulta ('include_extra_data=1", por exemplo) para indicar a necessidade na solicitação específica, onde por padrão, ele não será devolvido.

Sobre a autorização problema - Este deve ser totalmente desligado da data de sua perguntar sobre o seu pedido.O servidor deve ser capaz de determinar quais os dados que é visível para o usuário, de acordo com a id de usuário.(você pode verificar para fora do CanCan gem][1] como uma possível solução).

Assim, combinando as duas questões, a qualquer tipo de usuário deve ser capaz de fazer a '/pedido dos alunos, com ou sem o 'include_extra_data' bandeira.Se o servidor encontrar o usuário não-autorizado a ver os dados adicionais, você pode escolher uma das 2 opções - Ou retornar apenas os dados que o usuário tem permissão para ver, ou retornar um "401 não autorizado" de resposta.

Ambas as formas são válidas, e afetam a maneira como você lida com a resposta do seu aplicativo cliente.(Eu, pessoalmente, prefiro o mais tarde, como é mais descritivo para o cliente).

Espero que isso ajude :)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top