RESTful API дизайн URL с аутентификацией - PullRequest
0 голосов
/ 03 мая 2020

Моя модель данных выглядит следующим образом:

User: id, email, hashed_password
Item: id, name, color
UserItem: user_id, item_id, rating

, и я хочу написать RESTful API для получения этих ресурсов. Аутентификация обеспечивается через OAuth 2 с токеном JWT (который содержит идентификатор зарегистрированного пользователя).

Первый подход

Конечные точки

Первая идея для структуры URL - это ( тот, который я выбрал, когда еще не было аутентификации):

/items/{item_id}
/users/{user_id}
/users/{user_id}/items/{item_id}

В этом случае пользователь с идентификатором 1 может использовать:

  • GET /users/1 для получения своей собственной информации;
  • GET /users/1/items для получения собственных предметов (с рейтингом);
  • GET /items для получения всех предметов, которые они могут добавить в свою коллекцию.

Анализ

Я думаю, что это решение довольно простое, но также нелегкое.

Хорошо:

  • Вы можете легко получить информацию о других пользователях (если они им доступны) ;
  • 1-к-1 отношения между конечными точками и моделями данных.

Плохо:

  • Более длинные URL;
  • Существует избыточность (почему GET /users/1/items, когда в токене у вас уже есть информация об идентификаторе 1?).

Второй подход

Конечные точки

Учитывая, что вы можете извлечь идентификатор пользователя из токена, структура также может быть более простой:

/items/{item_id}
/users/{user_id}

В этом случае пользователь с идентификатором 1 может использовать:

  • GET /users/me для получения собственной информации;
  • GET /items?class=owned для получения собственных элементов (с рейтингом);
  • GET /items?class=all для получения всех элементов, которые они могут добавить в свою коллекцию .

Анализ

Это решение немного грязное, но, возможно, более элегантное.

Хорошо:

  • Короткие URL;
  • Меньше избыточности (GET /items для получения своих предметов).

Плохо:

  • Представлена ​​только модель UserItem (хотя в данном случае это вероятно, почти бессмысленно получать элемент без его рейтинга, который может быть установлен в ноль, если пользователь еще не добавил его);
  • Непросто получить элементы других пользователей (возможно, что-то вроде GET /items?user=3?) .

Выводы

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

Как бы вы организовали такую ​​модель?

1 Ответ

1 голос
/ 04 мая 2020

Вы можете посмотреть в формате, как HAL. HAL дает вам возможность описать определенные c ресурсы (элементы) и позволяет создавать несколько коллекций, которые указывают на эти ресурсы.

Это означает, что отдельные элементы могут быть размещены на /items/xyz, но элементы могут быть частью коллекций /user/a/items и /items.

Я вложил много работы в гипермедиа-клиент: https://github.com/badgateway/ketting. Хотя это не просто реклама, есть альтернативы, но этот подход к разработке API может нам подойти.

Но независимо от того, какой клиент вы используете, подобные системы могут избежать проблемы получения один и тот же элемент через несколько конечных точек. Один элемент имеет канонический URL-адрес, и если система спроектирована правильно, вам нужно извлечь элемент только один раз.

Коллекция - это просто список ссылок на ресурсы (элементы), которые принадлежат этой коллекции. Они указывают на элемент, но не содержат его, как обычная гиперссылка.

...