Почему небольшой фиксированный словарь рассматривается как преимущество для служб RESTful?

13

Итак, сервис RESTful имеет фиксированный набор глаголов в своем словаре. Веб-служба RESTful берет их из методов HTTP. Есть некоторые предполагаемые преимущества для определения фиксированного словарного запаса, но я не совсем понимаю суть. Может быть, кто-то может это объяснить.

Почему фиксированный словарь, описанный REST, лучше, чем динамическое определение словаря для каждого состояния? Например, объектно-ориентированное программирование является популярной парадигмой. RPC описывается для определения фиксированных интерфейсов, но я не знаю, почему люди предполагают, что RPC ограничен этими ограничениями. Мы могли бы динамически указывать интерфейс точно так же, как сервис RESTful динамически описывает его структуру контента.

Предполагается, что REST имеет преимущество в том, что он может расти без расширения словарного запаса. Службы RESTful растут динамически, добавляя больше ресурсов. Что плохого в расширении службы путем динамического определения словаря для каждого объекта? Почему бы нам просто не использовать методы, которые определены в наших объектах в качестве словаря, и чтобы наши службы описывали клиенту, что это за методы и есть ли у них побочные эффекты?

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

Действительно ли фиксированный словарь развязывает проблемы клиента с проблемами сервера? Я, конечно, должен быть обеспокоен некоторой конфигурацией сервера, обычно это расположение ресурсов в службах RESTful. Жаловаться на использование динамического словаря кажется несправедливым, потому что мы все равно должны динамически рассуждать, как каким-то образом понимать эту конфигурацию. Сервис RESTful описывает переходы, которые вы можете сделать, идентифицируя структуру объекта через гипермедиа.

Я просто не понимаю, что делает фиксированный словарь лучше, чем любой динамический словарь с самоописанием, который может очень хорошо работать в RPC-подобном сервисе. Это просто плохая аргументация в пользу ограниченного словарного запаса протокола HTTP?

отражение

Просто чтобы уточнить мои мысли немного лучше, чем я сделал. Предположим, вы разрабатываете какой-либо API общего назначения, может быть, даже не веб-интерфейс. Будете ли вы счастливы, если кто-то скажет, что вы можете использовать эти имена методов только для своих объектов? REST не ограничивается HTTP, но рассмотрим ситуацию, когда каждый API, который вы пишете, обращаетесь к веб-сайту или иным образом, просто состоит из объектов, содержащих методы GET POST PUT и DELETE. Так что метод object.foo, который вы хотели определить, не возможен. Вы должны определить новый объект с именем foo и вызвать его метод GET. По сути, так работает REST, и мне немного неудобно об этом думать. У вас нет лучшего общего понимания того, что делает foo, вы просто были вынуждены создать новый объект для того, что по сути является методом родительского объекта. Кроме того, ваш API не менее сложен, Вы только что скрыли сложность интерфейса, создав больше объектов. Веб-сервисы RESTful вынуждают нас использовать интерфейс, который может быть или не быть достаточным в контексте предоставляемого нами API. Возможно, есть хорошая причина сделать это с API, обращенными к сети, но хорошая причина не использовать стандартные интерфейсы для каждого объекта в каждом API общего назначения. Практический пример будет оценен.

Мэтт Эш
источник
Чтобы помочь пользователям быстро разобрать ваш вопрос и ответы, вы можете добавить «Обновления» в виде отдельных ответов (в частности, в разделе «Другое обновление»). Это приветствуется
Иоганн
@Johann спасибо, дальнейшие обновления теперь существуют как принятый ответ на этот вопрос.
Мэтт Эш

Ответы:

9

Терминология "глагол" и "существительное" здесь несколько неудачна. Как вы уже упоминали, вы можете легко создать объект для функции. Все объектно-ориентированные языки, кроме Java, имеют встроенное преобразование, и в Java вы все равно делаете это все время, заканчивая множеством объектов с одним методом, который часто называется "invoke", "execute", "apply" или somesuch (так что это языки программирования, где различие между «глаголом» и «существительным» на самом деле не имеет смысла).

«Глаголы» REST больше похожи на классификацию ваших методов для методов получения, установки (удаления; могут рассматриваться как виды установки) и других. И пытаюсь сделать все с добытчиками и сеттерами. Причиной этого является:

  1. Более простая семантика перед лицом сбоя связи, поскольку и геттеры, и сеттеры являются идемпотентами. Двойное получение ресурса не имеет никакого дополнительного эффекта, равно как и установка значения, которое он уже имеет.
  2. Определение некоторой семантики, которую можно использовать, возможно, кешируя прокси, который не понимает конкретный интерфейс. Получатели кэшируются, и известно, что установщики делают кэш недействительным.

HTTP был спроектирован с самого начала с учетом как кэшей, так и отказоустойчивости, поэтому эти два момента приводят к четырем основным методам:

  • GETэто добытчик. Предполагается, что не нужно изменять состояние сервера и каждый раз возвращать одно и то же значение с возможностью указать политику истечения срока действия и повторной проверки.
  • PUTи DELETEявляются установщиком и удалителем (= установщик с нулем). Они обычно не используются в контексте обычной сети, но имеют смысл для REST.
  • POST это универсальная кухонная раковина "invoke", для которой кеш ничего не может предполагать.

REST - это шаблон проектирования, описывающий, как использовать необработанный HTTP или аналогичные сетевые протоколы для реализации интерфейса, который позволяет легко обрабатывать сбои путем простой повторной попытки и прекрасно работает с прокси-серверами кэширования.

Это не соответствует легко обычному объектно-ориентированному программированию API. Я думаю, что это на самом деле хорошая вещь. Проблемы взаимодействия по сети, которые по своей природе ненадежны и в которых обходы выполняются гораздо медленнее, чем передача даже умеренного объема данных, требуют другого подхода к проектированию, чем внутрипроцессный API, поэтому, когда он выглядит иначе, люди не пытаются применять слишком много недопустимого опыта в другом домене (это ужас SOAP, XML-RPC и т. д .; он выглядит как вызовы процедур, но не работает так, как надо, и в конечном итоге становится болью в работе).

Ян Худек
источник
2

Основная идея заключается в том, что сложность выражается через представление ресурса, поэтому дополнительные глаголы не нужны. Как говорят некоторые: «В REST существительные хорошие, глаголы плохие».

Если вы посмотрите на четыре глагола REST, они могут быть сопоставлены с основными операциями CRUD, что позволяет вам делать с вашими ресурсами все, что вы хотите. То есть -

POST - Создать ресурс

GET - Читать ресурс

PUT - обновить ресурс

УДАЛИТЬ - Удалить ресурс

Что еще тебе нужно?

Крейг Шварц
источник
Я могу облегчить глагол в RESTful-сервисе, создав ресурс для этого. Как вы говорите, мне не нужны дополнительные глаголы, просто больше ресурсов. Я просто не понимаю, почему лучше притворяться, что любой абстрактный глагол - это существительное, когда то, что я хочу сделать, - это действительно глагол. Кажется, что глаголы насильно ограничены без причины, и я избегаю проблемы, создавая существительные, которые выполняют необходимые действия при доступе с небольшим набором глаголов. Почему бы это лучше сделать? Для этого должна быть веская причина, которую я могу определить в качестве практического примера.
Мэтт Эш
4
Получить список всех ресурсов, получить список всех ресурсов с заданными ограничениями, обновить или удалить кучу ресурсов одновременно, создать два разных типа ресурсов вместе атомарно (так, чтобы оба создания провалились или преуспели), удалить все ресурсы удовлетворение заданного состояния ... Список вещей, которые можно захотеть сделать, довольно длинный. Можно вписать их в REST API, но это не всегда естественно. Также не помогает то, что GET не допускает тела, поэтому сложные условия фильтрации становятся неудобными.
Андреа
Патчинг ресурсов тоже очень круто.
Уайетт Барнетт
2

Рассмотрим язык, в котором все конструкции (например, функции) являются объектами. Тогда глаголы RESTful просто вызывают соглашения и операторы присваивания. Для JavaScript вы можете определить фиксированный синтаксис глаголов, такой как INVOKE для вызова функции, DELETE (то же самое, что delete в js) для удаления объекта в другом объекте, SET для присвоения значения и RETURN для возврата значения. Мы могли бы использовать глаголы HTTP для обозначения эквивалентной функции POST - вызова, PUT - присвоить значение, GET - вернуть значение, - DELETE - удалить объект. Я был захвачен идеей, что методы HTTP на самом деле описывают методы объекта, реальные интерфейсы объекта, что я не смог увидеть, что он действительно может описывать гораздо более низкоуровневые концепции, такие как базовые языковые конструкции, которые четко фиксированы и конечны во всех вменяемые языки.

И, конечно, для маршрутизации / прокси полезно иметь фиксированный словарный запас для размышлений.

Мэтт Эш
источник
1
  • Потому что в противном случае профессиональный программист ожидает сотни, если не тысячи имен методов. То, что кажется бесполезным в маленьком маленьком, может быть очень большим делом, когда приложение становится больше.

  • Потому что нет необходимости в стандартах для имен методов, когда они уже определены.

  • Потому что основная цель кода - быть читабельным без таких дополнительных переводов.

  • Потому что это поощряет и помогает в определении «когда» должен быть разорван другой класс.

  • Когда вы берете код на себя, это разумно и действительно возможно понять, что и как он делает это намного быстрее.

  • Он обеспечивает общий словарный запас и, следовательно, уровень абстракции, так что вы можете сосредоточиться на других деталях и увидеть шаблоны.

  • Это облегчает поиск ошибок, так как общий код и подходы легко проверяются.

  • Когда вы работаете с несколькими «слоями», такими как один в веб-разработке, знание того, какие URL-адреса совпадают с именами действий, очень удобно для отладки.

В общем, это не всегда нужно, но, как и большинство стандартов, имеет смысл попытаться использовать его!

Майкл Даррант
источник
Адресовано по порядку 1) Значит, программист предвидит сотни, если не тысячи ресурсов, в противном случае? Мы уже ожидаем методы в библиотеках, которые мы используем. 2) Итак, нам нужны стандарты для имен методов, но не для имен ресурсов? Я не могу следовать этой логике. 3) Не уверен, что вы подразумеваете под переводами. Если вы скажете мне, что ресурс существует, я должен его понять. Если я скажу вам, что метод существует, вы должны его понять. Единственное, что меня действительно волнует, это то, какие из моих действий будут иметь побочные эффекты 4) Не могли бы вы расширить
Мэтт Эш
5) опять расширишь. Я программист. Я привык работать с четко определенными объектными структурами. Почему бы нам не использовать этот же механизм для определения всех наших API, если он действительно лучше? 6) Ни один уровень абстракции не стоит рассматривать без обоснования. 7) Опять вы не могли бы расширить. Если мы выиграем таким образом, мы, конечно, должны кодировать все наши API, как это. 8) Я ожидал бы, что любой объект выставит свои методы напрямую. / объект / метод не может быть перепутан. Мы определяем стандарты, выбирая их принятие. Мне не хватает мотивации в данный момент.
Мэтт Эш
Мэтт, кажется, вы немного спорите, но я скажу, что для 2) я не говорил, что ресурс не будет нуждаться в стандартах 3) вам не нужно будет понимать метод, такой как «обновление» или «новый» или «создать», потому что вы точно знаете что они делают в соответствии со стандартами. Однако как насчет MsgToPrimary, что это делает? Создать сообщение? Обновить статус? Отправить письмо? 7) Да, большинство API могли бы извлечь выгоду из этого, и многие делают. Я постараюсь сосредоточиться на понятии стандартов и соглашений, которые полезны, и я вижу, что ваши обновления показывают это.
Майкл Даррант
Я просто стараюсь понять преимущества. Сильные контраргументы должны быть рассмотрены, чтобы прояснить проблему. Тем не менее я понимаю, что фиксированный набор глаголов является своего рода описанием языка, но я не совсем согласен, что это облегчает понимание. Вы не можете убрать выразительный набор глаголов и сказать «эй», теперь мы понимаем все глаголы, когда мы не понимаем все ресурсы. Ресурсы заменяют глаголы. Мы заменим произвольный глагол foo ресурсом под названием foo. Наше понимание foo не более ясно, чем это было, когда foo был глаголом.
Мэтт Эш
1

Альтернативой является нечто ужасное: WSDL (он же язык определения веб-служб), который является (неуклюжим) способом программного описания (в некоторой степени) произвольного APIS.

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

Есть подкаст, в котором Стефан Тилков хорошо объясняет REST .

cbare
источник
1

Да, api rest имеет фиксированный набор глаголов, но он не должен быть ограничен (или включает GET, POST, PUT, DELETE). Я бы посмотрел на GET, POST, PUT, DELETE как реализацию REST по умолчанию, которая работает для 80% всех систем.

Другие системы, которые реализуют больше, чем просто операции, могут (и делают) реализовывать свои собственные глаголы для своих API REST. Глаголы, такие как «Опубликовать», «Потреблять», «Оценить», «Комментарий», «Поиск», «Обзор», могут быть добавлены и внедрены в систему REST. Хотя некоторые могут сказать, что увеличение словарного запаса может усложнить задачу, я отвечаю, что это зависит. Если ваш целевой пользователь - технический директор, который понимает, что такое POST, тогда да, это может быть более сложным; однако, если целевые пользователи вашего API - это реальные люди (то есть люди, которые не пишут код и не знают, что такое POST), то настоящие глаголы намного проще в использовании. Фактически наличие соответствующего набора глаголов для вашего API помогает сохранить короткие URL-адреса (что важно, если вы хотите, чтобы пользователи вводили их в браузер. Если вы используете пользовательский словарь, вы ' Я хочу убедиться, что ваш API и его глаголы хорошо документированы. При использовании пользовательского API REST вы должны убедиться, что ваши «действия только для чтения» в виде HTTP GET и «действия записи» с POST.

Подростковая социальная сеть Piczo.com (пусть будет пухом) представила расширенный API REST (включая глаголы, упомянутые выше), который был реализован на 7 разных языках!

Андрей
источник
0

Простое это хорошо.

Бывают случаи, когда вам нужны дополнительные глаголы и сложность, но большинство проблем можно сократить до простых действий CRUD над ресурсами, и именно это REST пытается продвигать. Когда вы думаете о большинстве веб-приложений, в конце они читают и сохраняют записи в хранилище данных, которые используют одни и те же очень простые действия.

object.foo () все хорошо, но что он делает? Что это возвращает? Это изменение состояния объекта или какой-либо из его зависимостей? Можете ли вы назвать его дважды и получить один и тот же результат, или он даст вам два разных значения? Если у вас также есть object.bar (), нужно ли их вызывать в определенном порядке?

Для использования богатого API требуется много знаний, и они обычно имеют свои собственные соглашения (т.е. setFoo собирается мутировать объект, getBar, вероятно, идемпотентен, dispose () или destroy () означает, что никаких других вызовов для того же объекта нет). будет возможно и т.д ...)

ptyx
источник