Вопрос API REST о том, как обращаться с коллекциями настолько эффективно, насколько это возможно, но все еще соответствует принципам REST
Im довольно новый для REST, но насколько я понял, я понимаю, что следующий URL-адрес соответствует принципам REST. Где ресурсы распределяются следующим образом:
/user/<username>/library/book/<id>/tags
^ ^ ^ ^
|---------|-----------|---|- user resource with username as a variable
|-----------|---|- many to one collection (books)
|---|- book id
|- many to one collection (tags)
GET /user/dave/library/book //retrieves a list of books id's
GET /user/dave/library/book/1 //retrieves info on book id=1
GET /user/dave/library/book/1/tags //retrieves tags collection (book id=1)
Однако как можно оптимизировать этот пример API? Скажем, например, у меня есть 10K книг в моей библиотеке, и я хочу получить детали каждой книги в своей библиотеке. должен ли я действительно заставить http-вызов /library/book/<id>
для каждого идентификатора, указанного в /library/book
? Или я должен включить несколько идентификаторов в качестве параметров? /library/book/<id1>,<id2>...
и делать то же самое, что и массовое извлечение со 100 id за раз?
Что говорят принципы REST об этой ситуации? и каковы ваши мнения?
Еще раз спасибо.
Ответы
Ответ 1
Это строго вопрос дизайна.
Я мог бы определить ресурс bookc
и использовать его так:
GET /user/dave/library/book?bookList=...
как вы далее указываете аргумент bookList
, это действительно вопрос того, какое использование вы планируете использовать для этого ресурса. У вас может быть, например:
GET /user/dave/library/book?bookList=1-10
GET /user/dave/library/book?bookList=1,2,5,20-25
или вы можете просто просмотреть все книги:
GET /user/dave/library/book?page=7&pagesize=50
Но, на мой взгляд, особенно форма с длинным списком "случайных" идентификаторов кажется довольно непригодной. Возможно, я бы вместо этого определил параметр filter
, чтобы указать:
GET /user/dave/library/book?filter=key,value&filter=key,value
Что касается вашего вопроса об ограничении длины URL-адреса HTTP, стандарт не устанавливает никаких параметров. Но браузер может меняться... посмотрите на это S.O. тема
Чтобы быть более строго RESTful, параметр запроса может быть указан через HTTP-заголовки, но общая идея, которую я хотел передать, не изменяется.
Надеюсь, это вам подходит...
Ответ 2
Выше выглядит хорошо, но я бы изменил на множественные имена, он читает лучше:
/users/{username}/books/{bookId}
То, что я не понимаю, является прецедентом передачи списка идентификаторов, разделенных запятыми. Вопрос в том, как вы добираетесь до идентификаторов? Я думаю, что за списком идентификаторов есть семантика, т.е. Они представляют собой результат фильтра. Поэтому вместо прохождения идентификаторов я бы поискал api. Упрощенный пример:
/users/dave/books?puchasedAfter=2011-01-01
Если вы хотите перебирать свою коллекцию книг в 10K, используйте параметры поискового вызова.
Ответ 3
Это только мое мнение:
GET /user/dave/library/book/IDList //retrieves a list of books id's
or
GET /user/dave/library/bookID //retrieves a list of books id's
GET /user/dave/library/book //retrieves a list of books
GET /user/dave/library/book/1 //retrieves info on book id=1
GET /user/dave/library/book/1-3 //retrieves info on book id>=1 and id <=3
GET /user/dave/library/book/1/tags //retrieves tags collection (book id=1)
Ответ 4
Вы можете использовать paginator
Некоторый успокоительный API работает с paginator для огромных ресурсов, таких как:
http://example.org/api/books?page=2
Сервер обеспечивает, например, 100 записей (в данном случае книг) на страницу. И вы можете сортировать книги, используя sortby
в своем запросе на получение. С вышеуказанным запросом вы получите книги 101-200 (если их так много в базе данных). Ответ может рассказать вам что-то о количестве книг и количестве страниц, что является следующей страницей и предыдущей страницей, но затем вы больше переходите к HATEOAS.
В противном случае, если вы хотите получить определенный id, я бы сделал это следующим образом:
http://example.org/books?id=[]2&id=[]5&id=[]7&id=[]21
Запрос get с массивом id (id = [2,5,7,21]), который возвращает книги с соответствующими идентификаторами