Есть стандартная структура данных:
user_id
user_name
user_...
-----
group_id
group_user
group_name
group_...
-----
item_id
item_group
item_name
item_...
Допустим вызываем метод GET items (скажем top N по дате). Результат должен быть:
items : [
{id : 1, name : 'Name 1', group : 1},
{id : 2, name : 'Name 2', group : 1},
{id : 3, name : 'Name 3', group : 2},
{id : 4, name : 'Name 4', group : 3}
]
или
items : [
{id : 1, name : 'Name 1', group : 1, user: 1},
{id : 2, name : 'Name 2', group : 1, user: 1},
{id : 3, name : 'Name 3', group : 2, user: 1},
{id : 4, name : 'Name 4', group : 3, user: 2}
]
или
items : [
{id : 1, name : 'Name 1', group : {id : 1, name: 'Group 1', user: 1}},
{id : 2, name : 'Name 2', group : {id : 1, name: 'Group 1', user: 1}},
{id : 3, name : 'Name 3', group : {id : 2, name: 'Group 2', user: 1}},
{id : 4, name : 'Name 4', group : {id : 3, name: 'Group 3', user: 2}}
]
или
items : [
{id : 1, name : 'Name 1', group : {id : 1, name: 'Group 1', user: {id: 1, name: 'User 1'}}},
{id : 2, name : 'Name 2', group : {id : 1, name: 'Group 1', user: {id: 1, name: 'User 1'}}},
{id : 3, name : 'Name 3', group : {id : 2, name: 'Group 2', user: {id: 1, name: 'User 1'}}},
{id : 4, name : 'Name 4', group : {id : 3, name: 'Group 3', user: {id: 2, name: 'User 2'}}}
]
или
{
items : [
{id : 1, name : 'Name 1', group : 1},
{id : 2, name : 'Name 2', group : 1},
{id : 3, name : 'Name 3', group : 2},
{id : 4, name : 'Name 4', group : 3}
],
groups : [
{id: 1, name: 'Group 1', user: 1},
{id: 2, name: 'Group 2', user: 1},
{id: 3, name: 'Group 3', user: 2}
],
users : [
{id: 1, name: 'User 1'},
{id: 2, name: 'User 2'}
]
}
Первый способ наиболее аскетичный, универсальный, но в 99.9% случаях потребует от клиента отправить еще кучу запросов для нормального отображения информации (получить все groups и users по их id). Из плюсов - простота запросов на стороне сервера (все по PRIMARY KEY), никаких JOIN.
spoilerОднако, в реальной жизни это далеко не так: например нужно исключить items "забаненных" users -> JOIN на groups и users.
Предпоследний способ наиболее полный, но информация сильно дублируется. Особенно не ясно что туда включать при наличии большого количества полей user_... и group_... Видел, что в некоторых API можно указать что именно получать, но имхо это как-то неудобно указывать в запросе кучу параметров. И откуда взять их состав, схема нужна?
Последний имхо самый оптимальный - в ответе есть все, что нужно для отображения именно этих items, данные не дублируются (во всяком случае в пределах этого запроса). А вот скажем с постраничным выводом будут вопросы: на "второй странице" опять вернутся уже (возможно) полученные users и groups, а возможно каких-то не было. Но все равно данных и дополнительных запросов будет значительно меньше, чем в остальных вариантах. И, если честно, я такого подхода нигде не видел. Это "нормально"?
Как вообще "правильно" возвращать связанные данные? Как понять что понадобится клиенту API?