Я пытаюсь склонить голову вокруг дизайна RESTful, и я хотел бы понять это с точки зрения социальной сети. Я прочитал REST API Design Rulebook, просмотрел некоторые другие книги и прочитал много онлайн-ресурсов. Тем не менее, при применении правил к реальным проблемам я понимаю, что я не полностью понимаю все. Я хочу знать, есть ли у меня правильное понимание REST, указав некоторые проблемы:
Иерархия против плоского дизайна
Предположим, что я идентифицирую конкретного пользователя с
/users/42
Теперь фотографии, загруженные этим пользователем, попадут в
/users/42/photos
и если он/она помечает своих друзей на фотографии, те теги окажутся в
/users/42/photos/1337/tags
Но это не дает возможности найти все фотографии, где отмечен определенный пользователь. Должен ли я придумать для этого другую иерархию? Это кажется немного неудобным. Могу ли я полностью игнорировать иерархию и предоставлять фотографии в сочетании с такими запросами?
/photos?owner=42
/photos?tagged=42
Кэширование, когда контент отличается для разных пользователей
Веб-служба должна быть предназначена для предоставления кэшируемых данных (чтобы клиент мог решить использовать локальную копию, если он считает, что ничего не изменилось), но как это влияет на настройки конфиденциальности для разных пользователей? Два пользователя, оба из которых вошли в систему, могут иметь права просматривать различную информацию, например. пользователь 42. Означает ли это, что мне как-то нужно запрашивать разные URI для разных пользователей, получающих доступ к информации профиля одного и того же пользователя, или кеширование не будет проблемой, если пользователи предоставляют разные учетные данные?
Предоставление HTML и JSON/XML из одного ресурса
В упомянутой книге указано правило, что API должен быть доступен в субдомене, начиная с api
, в их примере http://api.soccer.restapi.org
. Я планировал использовать один и тот же контроллер для доступа пользователей и доступа к машинам (например, мобильное приложение). Контроллер должен решить, какое представление предоставить (text/html
, application/json
или application/xml
) через поле Accept
в заголовке HTTP-запроса. Я полагаю, что по какой-то причине это было бы плохой идеей (поскольку пользователь ожидал увидеть субдомен www
, а не api
), но я не понимаю, почему. Может ли www
и api
указывать на один и тот же сервер, или я должен попытаться переместить вид HTML на другой виртуальный хост? Почему?
Я полагаю, что Ruby on Rails будет (Контекция по конфигурации) предоставлять как HTML, так и JSON от одного и того же контроллера, таким образом, разделяя мою идею о том, что HTML и JSON являются просто разными представлениями одних и тех же данных.
Другими словами, в моей книге говорится, что определенный ресурс должен иметь один и только один URI и что различные представления должны предоставляться на основе поля Accept
. Перенаправление пользователя между разными субдоменами нарушит правило о предоставлении какого-либо представления с одного и того же ресурса, а дублирование информации (т.е. Указание двух поддоменов на один и тот же виртуальный хост) нарушает правило о том, чтобы не предоставлять несколько URI для одного и того же ресурса. Не предоставление субдомена api
нарушает еще одно правило проектирования. Как я могу решить это без нарушения какого-либо правила?
Ограничение данных, отправленных обратно
Компонент запроса должен использоваться для разбивки на страницы, но могу ли я отказаться от соблюдения листинговых запросов, не имеющих критериев поиска, и ограничить количество элементов, не нарушая REST? Я хочу как уменьшить нагрузку на базу данных, так и избежать того, чтобы кто-то отображал весь каталог пользователей. Я хочу
/users
является незаконным запросом, а
/users?name=leet+hacker
будет действительным, но только вернется, например. 100 предметов.
Я также задаюсь вопросом, является ли законным возвращать подмножество столбцов базы данных и многое другое/все из них, только если они специально запрошены с использованием запроса.
Контроллеры, предоставляющие избыточные данные
Я считаю законным предоставлять контроллер, например
/users/me
но он должен предоставить ту же самую информацию, что и URI документа
/users/42
или должен ли он перенаправляться на него?
Расширенные права для некоторых пользователей
Каков RESTful способ предоставить дополнительные функции, например права администратора? Теперь я предполагаю, что администратор (фотографии, группы пользователей или всего сайта) сможет увидеть больше информации о конкретном объекте, чем другие пользователи. Должна ли эта информация храниться в точно таком же URI и автоматически отправляться администратору, но не кому-либо еще, должна ли она храниться в другом месте, если она запрашивается с использованием определенного запроса администратора или предоставляется каким-то другим способом?
Обновления локализации и настроек
Хотя большинство строк, видимых пользователю, должно быть предоставлено представлением, есть некоторые проектные решения, которые могут включать API. Наиболее очевидными являются имена. Социальные сети иногда позволяют пользователю вводить разные имена, которые должны отображаться в разных языковых контекстах. Имена на некоторых языках, например, на русском и арабском языках, не просто записываются автоматически. На других языках, таких как китайские, локальные и международные имена могут быть совершенно разными, без какого-либо сходства или связи. Каким был бы RESTful способ справиться с этим? У меня такое чувство, что ответом будет поле Accept-Language
, но кто-нибудь всерьез рассматривает это для переключения языков в социальной сети, к которой они принадлежат? Должна ли вся эта информация возвращаться вызывающему абоненту каждый раз или я могу полагаться на настройки? Будет ли это работать с кешем?