Як побудувати API REST, який бере масив ідентифікаторів для ресурсів


103

Я будую API REST для свого проекту. API для отримання інформації про даного користувача:

api.com/users/[USER-ID]

Я також хотів би дозволити клієнту перейти до списку ідентифікаторів користувачів. Як я можу побудувати API так, щоб він був RESTful і містив список ідентифікаторів користувача?


Найбільш загальну відповідь дає @Shuja, тому що інші відповіді від листонош не спрацювали і залежать від резервної бази даних. Однак ви можете мати кінцеву точку API, щоб запитувати кілька ідентифікаторів.
Eswar

Відповіді:


97

Якщо ви передаєте всі свої параметри за URL-адресою, то, ймовірно, кращі значення будуть розділені комами. Тоді ви матимете шаблон URL-адреси, наприклад:

api.com/users?id=id1,id2,id3,id4,id5

7
@uclajatt, REST є архітектурною моделлю, а не протоколом, і якщо ви вивчите основні API REST, доступні сьогодні, ви побачите, що існує кілька способів його реалізації. Підхід, який я пропоную, мабуть, є одним із найбільш близьких до концепції, оскільки він виконує всі обмеження, описані тут: en.wikipedia.org/wiki/… . Ви будете використовувати CSV лише для представлення масивів у запитах, тоді як відповіді на послуги повинні бути серіалізовані за допомогою XML або JSON. Чи є якісь конкретні причини, чому ви не вважаєте мій підхід REST?
Флорін Думітреску

10
Чому б не це? api.com/users?id=id1&id=id2&id=id3&id=id4&id=id5
senfo

7
@senfo, я віддаю перевагу id = id1, id2, id3, тому що він робить URI коротшим і простішим для читання (людиною, наприклад, під час операції налагодження). Окремі параметри для кожного значення ускладнюватимуть URI особливо складніше, якщо між ідентифікаторами є інші параметри: api.com/users?id=id1&id=id2&joined-after=2013-01-01&id=id3
Флорін Думітреску

12
Однак більшість веб-серверів підтримують довжину URL-адреси близько 2000 байт. Як зробити мою підтримку API до 5000 ідентифікаторів?
nicky_zs

6
@senfo В URL - адреси , як …?id=1&id=2&id=3, немає ніякої гарантії , що дублюючі параметри запиту будуть об'єднані в масив. За допомогою наведеної вище рядка запиту PHP трапляється сказати вам, що idдорівнює [1, 2, 3], але Ruby on Rails повідомляє, що вона дорівнює 3, а інші рамки також можуть діяти по-різному, наприклад, кажучи idрівними 1. Такі URL-адреси, як …?id=1,2,3уникнення цього потенціалу для плутанини.
Rory O'Kane

33
 api.com/users?id=id1,id2,id3,id4,id5
 api.com/users?ids[]=id1&ids[]=id2&ids[]=id3&ids[]=id4&ids[]=id5

IMO, вище дзвінки не виглядають RESTful, однак це швидке та ефективне вирішення (y). Але довжина URL-адреси обмежена веб-сервером, наприклад, tomcat .

Спроба вподобання:

POST http://example.com/api/batchtask

   [
    {
      method : "GET",
      headers : [..],
      url : "/users/id1"
    },
    {
      method : "GET",
      headers : [..],
      url : "/users/id2"
    }
   ]

Сервер відповість URI новоствореного ресурсу пакетної задачі .

201 Created
Location: "http://example.com/api/batchtask/1254"

Тепер клієнт може отримати відповідь партії або хід виконання завдання шляхом опитування

GET http://example.com/api/batchtask/1254


Ось як інші намагалися вирішити цю проблему:


7
Запит POST для отримання декількох результатів не є RESTful. Ваш приклад показує створення ресурсу, де це доречно для POST, але це зовсім інший випадок із початковим запитанням
Anentropic

2
Створення тимчасового ресурсу - ВИПУСК, чи не так? І я отримую ресурси, використовуючи GET, його знову ВІДБУДОВО.
Нілеш

так, але нічого з цього не було в початковому запитанні, яке просто запитує про отримання інформації для декількох ідентифікаторів користувачів
Anentropic

1
Дякую @Anentropic за вказівку. Я знову прочитав це запитання, в якому запитується Як побудувати API REST, який бере масив ідентифікаторів для ресурсів? і я згоден, моя відповідь інша. Вибачте за те, що не зрозуміли вашу думку.
Нілеш

Мені подобається ця відповідь, оскільки через цей механізм НАЙКРАЩИЙ спосіб отримати декілька користувачів.
Шейн Кортріль

20

Я знаходжу інший спосіб зробити те саме, використовуючи @PathParam. Ось зразок коду.

@GET
@Path("data/xml/{Ids}")
@Produces("application/xml")
public Object getData(@PathParam("zrssIds") String Ids)
{
  System.out.println("zrssIds = " + Ids);
  //Here you need to use String tokenizer to make the array from the string.
}

Зателефонуйте до служби за допомогою наступної URL-адреси.

http://localhost:8080/MyServices/resources/cm/data/xml/12,13,56,76

де

http://localhost:8080/[War File Name]/[Servlet Mapping]/[Class Path]/data/xml/12,13,56,76

5
Мені це подобається, оскільки GET є послідовним. У цьому прикладі можна використовувати одне число або багато. І це насправді не пошук (параметри), тому що ви надаєте задній кінець точні ідентифікатори, які ви хочете.
markthegrea

1
Я бачу, що найбільш відповідна відповідь не працює, і ваша відповідь, мабуть, є найбільш загальною. Слід прийняти як відповідь.
Eswar

18

Наскільки я віддаю перевагу такому підходу: -

    api.com/users?id=id1,id2,id3,id4,id5

Правильний шлях

    api.com/users?ids[]=id1&ids[]=id2&ids[]=id3&ids[]=id4&ids[]=id5

або

    api.com/users?ids=id1&ids=id2&ids=id3&ids=id4&ids=id5

Ось як це робить стійка . Ось як це робить php . Ось як це і вузол це робить ...


19
Я не впевнений, що посилання на стандарти PHP як настанову, яку слід дотримуватися, є найкращою порадою. eev.ee/blog/2012/04/09/php-a-fractal-of-bad-design
TREBOR

Це не так, як це робить колба.
jscul

0

Ви можете побудувати API відпочинку або спокійний проект, використовуючи ASP.NET MVC і повертаючи дані як JSON. Приклад функції контролера:

        public JsonpResult GetUsers(string userIds)
        {
           var values = JsonConvert.DeserializeObject<List<int>>(userIds);

            var users = _userRepository.GetAllUsersByIds(userIds);

            var collection = users.Select(user => new { id = user.Id, fullname = user.FirstName +" "+ user.LastName });
            var result = new { users = collection };

            return this.Jsonp(result);
        }
        public IQueryable<User> GetAllUsersByIds(List<int> ids)
        {
            return _db.Users.Where(c=> ids.Contains(c.Id));
        }

Тоді ви просто зателефонуєте до функції GetUsers за допомогою звичайної функції AJAX, що постачає масив ІД (у цьому випадку я використовую jQuery stringify для надсилання масиву як рядка та дематеріалізації його назад у контролері, але ви можете просто надіслати масив ints та отримати це як масив int's в контролері). Я будую цілий API Restful за допомогою ASP.NET MVC, який повертає дані як міждоменний json, який може бути використаний у будь-якому додатку. Звичайно, якщо ви можете використовувати ASP.NET MVC.

function GetUsers()
    {
           var link = '<%= ResolveUrl("~")%>users?callback=?';
           var userIds = [];
            $('#multiselect :selected').each(function (i, selected) {
                userIds[i] = $(selected).val();
            });

            $.ajax({
                url: link,
                traditional: true,
                data: { 'userIds': JSON.stringify(userIds) },
                dataType: "jsonp",
                jsonpCallback: "refreshUsers"
            });
    }

3
Вибачте, я не запитував, як реалізувати API. Я просто запитував, як побудувати URI API, щоб клієнт міг отримати доступ до інформації про масив користувачів. Я можу передавати ідентифікатори за допомогою параметрів запиту, але я вважаю, що це не дуже спокійно.
uclajatt

@uclajatt Чому ти вважаєш, що це НЕ ВІДПОВІДНО?
Даррел Міллер

1
Я вважаю, що передача id або будь-яких інших значень за допомогою параметрів запиту - це справді спокійний підхід взаємодії з системою. Як ти конструюєш Урі, це залежить від тебе. Будь то користувачі / всі, користувачі / масив, масив / користувачі або будь-яка інша умова іменування, ви вважаєте, що це має сенс. Беручи до уваги, як MVC працює дуже просто, використовувати її для створення спокійного API, оскільки ви можете організувати та побудувати вам Uris так само, як вам потрібно. Коли у вас буде Uris, ви зможете передавати вам параметри, використовуючи AJAX як одну струну, або як декілька значень, якщо ви використовуєте форму та виконайте публікацію до дії MVC.
Василь Лаур

1
@uclajatt Thats двічі вас запитали в цьому пості, чому ви вважаєте, що передача відокремленого комою списку в параметрі запиту не є RESTful, і ви навіть не намагаєтесь відповісти на нього, не кажучи вже про те, щоб прийняти будь-яке з цих дуже правдоподібних рішень !? ! Не круто.
Саміс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.