API - Множественные запросы против разделения ролей пользователей

StackOverflow https://stackoverflow.com//questions/25062443

Вопрос

Я работаю над интерфейсом одностраничного приложения, и мне нужно перечислить несколько студентов.Каждый студент привязан к определенному user_id Это то, что API возвращает для всех ролей пользователей (суперадмин, администратор, профессор, студент), когда я выполняю 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), который доступен только на GET /users/:id

Итак, когда я перечисляю 20-30 студентов на странице через GET /students/, для того , чтобы получить subscription_type, Мне также нужно будет выполнить 20-30 дополнительных запросов, по одному для каждого студента.

Я поговорил об этом с разработчиком API, и мне сказали, что включение дополнительных данных в students "это не самый надежный способ сделать это", "это еще больше замедлит время отклика" и что "30 дополнительных запросов весят меньше, чем большой кусок".

Я ничего не знаю о работе с API, поэтому не могу ничего сказать, но неужели я сумасшедший, думая, что 30 запросов при загрузке страницы - это смехотворно?

Так что же дальше?Должен ли я идти дальше и выполнять дополнительные запросы?Должен ли он разделить ответы для каждой роли пользователя и включить только то, что мне нужно для каждой роли?Что такое правильный способ о том, чтобы справиться с этим?

Это было полезно?

Решение

Хотя, строго говоря, специалист по API прав, слишком строгое следование евангелию RESTful может привести к неэффективности, подобной проблеме 1 + N, созданной реализацией purist.Ключевая концепция в RESTful design заключается в том, что ресурсы не обязательно должны напрямую соотноситься с объектами домена.При проектировании ресурсов необходимо учитывать сценарии использования.В сценарии super admin это звучит так, как если бы клиент запрашивал коллекцию students и ему также обычно или всегда нужны данные из users, в частности subscription_type.Объектная модель явно нормализована, как и должно быть, но это не говорит о том, что ресурсы должны быть или должны быть всегда.

Есть пара различных шаблонов, которые я использовал, чтобы сделать подобные сценарии более эффективными.Какие из них (если таковые имеются) применяются, зависит от того, как ресурсы потребляются клиентами.

Составной ресурс

Это комбинация всех или части двух или более объектов домена (например, student и user) в единый ресурс.

Поскольку все students предположительно , также users, вы могли бы включить все или часть пользовательских данных в студенческий ресурс по мере необходимости.

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"
}

Связанные Ресурсы

(Аналогично другому ответу) Это метод, при котором клиент может указать, что он хочет, чтобы связанный ресурс был включен в ответ.Это особенно полезно в отношении типа "имеет" в модели предметной области.Это позволяет клиенту существенно отложенная нагрузка или нетерпеливая нагрузка ресурс.

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"
   ...
  }
}

Другие советы

Здесь у вас есть две проблемы, которые не должны быть связаны друг с другом - Один - это данные, возвращаемые для каждого пользователя при индексном вызове (/students), а другой - процесс авторизации, который должен определить, к каким данным может быть открыт определенный пользователь.

Что касается проблемы с данными - я не думаю, что существует какое-то конкретное правило, которому следует следовать.Это полностью зависит от требований вашего приложения.Если поле subscription_type обычно не требуется, вы можете рассмотреть возможность передачи параметра запроса (например, 'include_extra_data=1'), чтобы указать, что оно вам нужно в конкретном запросе, где по умолчанию оно не будет возвращено.

Что касается проблемы с авторизацией - это должно быть полностью отключено от данных, которые вы запрашиваете в своем запросе.Сервер должен быть в состоянии определить, какие данные видны пользователю, в соответствии с идентификатором пользователя.(вы можете ознакомиться с Драгоценный камень КанКан][1] в качестве возможного решения).

Таким образом, объединяя эти две проблемы, пользователь любого типа должен иметь возможность отправлять запрос '/ students' с флагом 'include_extra_data' или без него.Если сервер обнаружит, что пользователь не имеет права просматривать дополнительные данные, вы можете выбрать один из 2 вариантов - либо вернуть только те данные, которые пользователю разрешено видеть, либо вернуть ответ "401 несанкционированный".

Оба способа допустимы и влияют на то, как вы обрабатываете ответ в вашем клиентском приложении.(Лично я предпочитаю более поздний вариант, поскольку он более нагляден для клиента).

Надеюсь, это поможет :)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top