Подтвердить что ты не робот

Как структурировать иерархию ресурсов REST?

Я новичок в веб-разработке на стороне сервера, и недавно я много читал о внедрении API RESTful. Один из аспектов REST API, который я все еще придерживаюсь, заключается в том, как организовать структурирование иерархии URI, которая идентифицирует ресурсы, с которыми клиент может взаимодействовать. В частности, я застрял в решении, как подробно сделать иерархию и что делать, если ресурсы состоят из других типов ресурсов.

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

Для пользователей:

/users
      /{id}
           /location
           /about
           /name
           /seller_rating
           /bought
           /sold

Для продуктов:

/products
         /{id}
              /name
              /category
              /description
              /keywords
              /buyer
              /seller

В обоих случаях объекты в каждой иерархии ссылаются на подмножество объектов в другой иерархии. Например, /users/{id}/bought - это список продуктов, которые купил пользователь, который является подмножеством /products. Кроме того, /products/{id}/seller ссылается на пользователя, продающего определенный продукт.

Поскольку эти URI ссылаются на другие объекты или подмножества других объектов, API должен поддерживать такие вещи: /users/{id}/bought/id/description и /products/{id}/buyer/location? Потому что, если поддерживаются эти типы URI, что бы остановить что-то вроде этого /users/{id}/bought/{id}/buyer/bought/{id}/seller/name или что-то столь же запутанное? Кроме того, в этом случае, как бы вы обрабатывали маршрутизацию, так как маршрутизатор на сервере должен был интерпретировать URI произвольной длины?

4b9b3361

Ответ 1

Цель состоит в том, чтобы создавать удобные идентификаторы ресурсов, не пытайтесь перекрестно ссылаться на все. Вам не нужно повторять свои отношения с базой данных в представлении URL-адреса:)

Связи, такие как /product/{id}/buyer, никогда не должны существовать, поскольку для этого ресурса уже есть идентификатор: /user/{id}

Хотя это нормально, если /product/{id}/buyers-list, потому что список покупателей является свойством продукта, которого нет в других контекстах.

Ответ 2

Вы должны думать об этом в режиме CRUD, где каждый объект поддерживает создание, чтение, обновление и удаление (обычно используя GET, POST, PUT и DELETE HTTP-глаголы соответственно).

Это означает, что ваши конечные точки обычно будут идти только на один уровень. Например,

Пользователи

GET    /users       - Return a list of all users (you may not want to make this publically available)
GET    /users/:id   - Return the user with that id
POST   /users      - Create a new user. Return a 201 Status Code and the newly created id (if you want)
PUT    /users/:id   - Update the user with that id
DELETE /users/:id  - Delete the user with that id

Более подробно, например /users/:id/about, скорее всего, не требуется. Хотя это может сработать, возможно, он немного ограничен.

Возможно, в вашем случае вы можете добавить:

GET    /users/:id/bought - Array of products that the user bought
GET    /users/:id/sold   - Array of products that the user sold

где вы можете вернуть список идентификаторов (которые могут быть получены через API продуктов), или вы можете заполнить Продукты перед их отправкой, если хотите. Если вы хотите их заполнить, вы, вероятно, не должны заполнять пользователей, на которые ссылается каждый продукт. Это приведет к включению кругового кода и не соответствует действительности.

И для продуктов, в вашем выборе я бы использовал:

GET    /products- Return a list of all products
GET    /products/:id   - Return the products with that id
POST   /products- Create a new product. Return a 201 Status Code and the newly created id (if you want)
PUT    /products/:id   - Update the product with that id
DELETE /products/:id  - Delete the product with that id

GET    /products/:id/buyers     - Array of who bought the product
GET    /products/:id/sellers    - Array of everyone selling the product