Как создать REST API, который принимает массив идентификаторов для ресурсов

103

Я создаю REST API для своего проекта. API для получения ИНФОРМАЦИИ о данном пользователе:

api.com/users/[USER-ID]

Я также хотел бы разрешить клиенту передавать список идентификаторов пользователей. Как я могу построить API, чтобы он был RESTful и принимал список идентификаторов пользователей?

Uclajatt
источник
Самый общий ответ дает @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позволяют избежать путаницы.
Рори О'Кейн
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 .

RESTful попытка:

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, но это совершенно другой случай по
сравнению
2
Создание временного ресурса - это RESTful, не так ли? И я получаю ресурсы с помощью GET, снова RESTful.
Nilesh
да, но ничего из этого не было в исходном вопросе, который просто спрашивает о получении информации для нескольких идентификаторов пользователей
Anentropic
1
Спасибо @Anentropic за указание. Я снова прочитал вопрос, который задает. Как создать REST API, который принимает массив идентификаторов для ресурсов? и я согласен, мой ответ другой. Извините, что не поняли вашей точки зрения.
Nilesh 01
Мне нравится этот ответ, так как RESTful способ получить несколько пользователей - через этот механизм.
Shane Courtrille
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 . Вот как это делает node ...

Киристофер
источник
19
Я не уверен, что ссылка на стандарты PHP в качестве руководства - лучший совет. eev.ee/blog/2012/04/09/php-a-fractal-of-bad-design
trebor
Это не то, как это делает Flask.
jscul 04
0

Вы можете создать Rest 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 для отправки массива в виде строки и дематериализации его обратно в контроллер, но вы можете просто отправить массив целых чисел и получить это как массив int в контроллере). Я создал полный Restful API с использованием 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. Я просто спрашивал, как создать API URI, чтобы клиент мог получить доступ к информации о массиве пользователей. Я могу передавать идентификаторы через параметры запроса, но я считаю, что это не очень успокаивает.
uclajatt
@uclajatt Как вы думаете, почему это не RESTful?
Даррел Миллер,
1
Я считаю, что передача идентификаторов или любых других значений через параметры запроса действительно является спокойным подходом к взаимодействию с системой. Как построить свой Ури, решать только вам. Будучи пользователями / всеми, пользователями / массивом, массивом / пользователями или любым другим соглашением об именах, которое, по вашему мнению, имеет смысл. Принимая во внимание, как работает платформа MVC, ее очень легко использовать для создания спокойного API, поскольку вы можете организовать и построить Uris так, как вам нужно. Как только у вас есть Uris, вы можете передавать вам параметры с помощью AJAX в виде одной строки, или как несколько значений, если вы используете форму и публикуете сообщение для действия MVC.
Василе Лаур
1
@uclajatt Вот уже дважды вас спрашивали в этом посте, почему вы думаете, что передача списка, разделенного запятыми, в параметре запроса не является RESTful, и вы даже не удосужились ответить на него, не говоря уже о том, чтобы принять любое из этих очень правдоподобных решений !? ! Не круто.
samis