Какова лучшая структура URL RESTful для рекурсивного ресурса?

10

Я создаю сервис RESTfull для древовидной структуры ресурсов, и мне было интересно, какой будет лучшая структура URL?

У меня есть три требования:

  1. быть в состоянии получить коллекцию корневых ресурсов
  2. быть в состоянии получить индивидуальный ресурс
  3. быть в состоянии получить коллекцию дочерних ресурсов

Моя текущая мысль:

/rest/documents
/rest/documents/{id}
/rest/documents/{id}/documents

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

У кого-нибудь есть мысли по поводу вышесказанного? или есть другой / лучший способ структурирования этого?

Мэтт Брэйлсфорд
источник
Возможно, я неправильно понимаю вопрос, но когда мы говорим о URL, является ли SEO проблемой?
Джон Хопкинс
SEO не проблема, нет. Я в основном спрашиваю лучшую логическую структуру URL для ресурса, ссылающегося на себя.
Мэтт Брэйлсфорд
Это кажется довольно прямым для меня.
Тим Пост
Насколько глубока эта структура?
Мартейн Вербург
@ Martijn глубина не ограничена
Мэтт Брэйлсфорд

Ответы:

11

Что мне приходит в голову: не позволяйте RESTful API отражать рекурсивность в самом URL. Если подумать, ваш ресурс - это только документы.

Если ваши документы хранятся физически в соответствии с рекурсивной структурой, создайте сопоставление с уникальным идентификатором и используйте идентификатор в URL:

/rest/documents/{id}

Теперь, если у вас есть такие документы:

| DocumentName | DocumentPath | DocumentID |
--------------------------------------------
| abc | / abc | 1 |
| ASD | / abc / asd | 2 |
| ASD | / ASD | 3 |
| бу | / abc / asd / boo | 4 |
| эй | / abc / asd / hey | 5 |

запрос свяжется с этим URL для /abc/asdдокумента

GET /rest/documents/2

Итак, теперь вы должны предоставить пользователям вашего API средства для обхода вашей структуры без особых усилий. Это можно сделать, обернув вашу ответную полезную нагрузку (документ) в объект, содержащий дополнительную информацию о прохождении, например:

{
   data: { /* your document goes here */ },
   parent: {"abc": 1 },
   children: [ { "boo": 4 }, { "hey": 5} ]
}

при условии, что вы ожидаете, что пользователи не будут создавать слишком много документов на одном уровне, вы можете включить в ответ список детей. Если это не так, вы можете предложить пользователю получить идентификаторы дочерних документов следующим образом, например, для подкачки результатов с помощью параметров строки запроса:

GET /rest/documents/2/children?page=2&size=50

Наконец, говоря о параметрах строки запроса, вы также можете указать информацию о пути непосредственно через параметры строки запроса:

GET /rest/documents?path=somepath&page=1&size=42

Все упомянутые подходы предполагают, что равнина GET /rest/documentsвозвращает только корневые документы.

netchkin
источник
1
Хорошая идея. Однако связь с дочерними документами не ясна из API, если дочерние документы включены в ответ для документа. Если у документов также есть другой подресурс, например, комментарии, вы, как правило, получаете доступ к вопросам для документа, используя / documents / {id} / questions. Чтобы быть последовательными и прояснить отношения с дочерними документами в API, я бы предложил, чтобы к дочерним документам обращались из / documents / {id} / child-documents. Возвращенные представления были бы Документами точно так же как / documents / {id}. Итак, остальная часть того, что вы описали здесь, все еще работает.
Натан Уорд
2

Возможно, что-то вроде этого:

/rest/{rootEntity}/Item/{leafEntity}/{id}
/rest/{entity}/ItemList
/rest/{entity}/ItemList/{leafEntity}

где {rootEntity} - отправная точка вашей коллекции, {leafEntity} - любой именованный листовой узел в вашем дереве.

Вы можете добавить несколько параметров к любому из вышеперечисленных, чтобы выбрать, скажем, Последний или Все или что-то еще.

Гэри Роу
источник