Должен ли RESTful API предоставлять данные для всей формы?

13

Допустим, у меня есть веб-приложение на JavaScript, которое полностью использует RESTful API для данных.

Допустим, у этого приложения есть форма данных, и предположим, что я редактирую запись в / product / 12345. При создании формы я делаю RESTful-запрос к / product / 12345 и получаю данные JSON:

{
  "id": 12345,
  "name": "Some Product",
  "active": true,
  "sales_user_id": 27
}

Итак, моя форма, очевидно, может иметь выпадающий список для выбора продавца. Мне нужно заполнить этот список. Откуда должны поступать данные? Какой самый распространенный подход?

Имеет ли смысл включать его в ответ на запрос / product / 12345?

{
  "id": 12345,
  "name": "Some Product",
  "active": true,
  "sales_user_id": 27,
  "sales_users": [
    {"id": 1, "name": "Anna Graham"},
    {"id": 2, "name": "Dick Mussell"},
    {"id": 3, "name": "Ford Parker"},
    {"id": 4, "name": "Ferris Wheeler"},
    {"id": 5, "name": "Jo King"}
  ]
}

А как насчет создания новой записи? Должен ли мой API также отвечать GET / product / new со следующим?

{
  "sales_users": [
    {"id": 1, "name": "Anna Graham"},
    {"id": 2, "name": "Dick Mussell"},
    {"id": 3, "name": "Ford Parker"},
    {"id": 4, "name": "Ferris Wheeler"},
    {"id": 5, "name": "Jo King"}
  ],
  "categories": [
    {"id": 1, "name": "Category 1"},
    {"id": 2, "name": "Category 2"},
    {"id": 3, "name": "Category 3"},
    {"id": 4, "name": "Category 4"},
    {"id": 5, "name": "Category 5"}
  ],
  "etc": [ ... ]
}
Чед Джонсон
источник
пожалуйста, никогда не используйте запрос GET для создания чего-либо. Ваша конечная точка должна быть / продукт не / продукт / новый . Для создания нового продукта вы должны отправить запрос PUT на эту конечную точку.
Керем Байдоган
Это ничего не создает. Это просто запрос существующих данных или шаблон для новой, еще не сохраненной записи.
Чед Джонсон
о, извините, теперь я понимаю, что вы имеете в виду. В любом случае конечная точка продукта не должна отвечать за предоставление шаблона продукта или списка значений для выпадающих форм создания продукта. как говорит @Dan, просто создайте отдельные конечные точки и используйте заголовки кэширования, чтобы ваш браузер мог кэшировать раскрывающиеся значения для производительности.
Керем Байдоган

Ответы:

6

Я склоняюсь к очень простым, узко сфокусированным конечным точкам. Я ожидал бы запрос в каком-то месте, например / sales_users, который возвращает всех пользователей продаж.

GET / sales_users:

[
    {"id": 1, "name": "Anna Graham"},
    {"id": 2, "name": "Dick Mussell"},
    {"id": 3, "name": "Ford Parker"},
    {"id": 4, "name": "Ferris Wheeler"},
    {"id": 5, "name": "Jo King"}
]

Точно так же, если у вас будет список категорий, я бы добавил для этого отдельную конечную точку.

GET / категории:

[
    {"id": 1, "name": "Category 1"},
    {"id": 2, "name": "Category 2"},
    {"id": 3, "name": "Category 3"},
    {"id": 4, "name": "Category 4"},
    {"id": 5, "name": "Category 5"}
]

Я бы не стал строить GET / product / new. Скорее, я бы построил форму в вашем приложении для обработки добавления новых продуктов, которая знает соответствующие запросы для заполнения своих списков (например, GET / category, GET / sales_users и т. Д.).

Дэн Лайонс
источник
3

Предполагая, что список продавцов относительно статичен, я думаю, что вы хотели бы отдельный вызов API /salesusers который вы могли бы вызвать один раз (при загрузке формы и т. Д.) И сохранить, чтобы вам не приходилось повторно запрашивать эти данные каждый время. Помните, что в REST вы организуете свой API вокруг ресурсов, а продавцы логически отделяют ресурсы от продуктов.

Аналогичным образом, при вызове /product/newвы бы хотели отправлять данные только для нового продукта, который может включать идентификатор sales_user, но не более того. Изменения в самом sales_user будут отдельным вызовом.

Dan1701
источник