Разработка API отдыха для сложного иерархического проекта - PullRequest
2 голосов
/ 07 июля 2011

У нас есть комплексное решение BPM ткани.Теперь мы хотим представить ткань как набор API остальных.

У нас есть приложение, в приложении у нас есть рабочие процессы, рабочий процесс может иметь действия.у action есть поля, а у полей могут быть правила.

, поэтому сейчас первый набор API для полей или правил был сделан как

[Get] apps / 1 / workflows / 1 / actions / 1/ fields / 4 / rules

[Post]

apps / 1 / workflows / 1 / actions / 1 / fields / 3 / rules

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

, так что должно быть предпочтительным URI для вышеупомянутого.

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

снова отредактировано

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

Так что, если я не выбрал создание длинных URI и оставил их действительно стройными для версии не ниже 1.

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

apps/1/workflows/1/actions/1/fields/3/rules

становится

/55667788

что делать, если я хочу сохранить URI читаемыми, но маленькими.Например, Fields/ возвращает все поля приложения 1, рабочий процесс 1, действие 1, но как предоставить все эти идентификаторы, не делая мой URI таким хаотичным?держать его на двух уровнях?это возможно или я иду в неправильном направлении?

1 Ответ

8 голосов
/ 07 июля 2011

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

apps/1/workflows/1/actions/1/fields/4/rules

Тогда я бы сказал, нет, здесь вы вводите семантику в URI, которая не нужна, в частности / workflows / / actions / / fields / / rules /. Вы должны обозначить шаблон URI для этого, и я бы придумал что-то вроде этого;

{application}/{workflow}/{action}/{field}/{rule}

По сути, мы можем перевести URI, например:

/yalla/4356/open_portfolio

В;

application = 'yalla'
workflow = '4356'
action = 'open_portfolio'
field = ''
rule = ''

И просто посмотрите, какой метод HTTP был использован, и примените классы действий на его основе. Ваш пробег будет варьироваться.

Однако на данный момент я немного настороженно отношусь к {action}, потому что в REST мы изо всех сил стараемся работать с унифицированным интерфейсом, но тогда я не знаю, на какое действие вы ссылаетесь. Мне кажется, что это более традиционный образ мышления RPC, от которого я бы попытался освободиться. Например, если у вас более традиционная структура RPC, подобная этой;

/yalla/4356/create_new_portfolio

вы нарушаете гарантированную безопасность операции GET (например, классическая ошибка использования / delete_user в качестве URI действия, а затем паук, сканирующий ваш сайт с помощью GET ...). Вместо этого я бы сделал это;

/yalla/4356/portfolio

К этому ресурсу я ПОЛУЧУ просмотр, PUT для обновления, POST для создания и DELETE для удаления. В этом смысле часть {action} шаблона URI становится немного запутанной. Что вы хотите, чтобы API покрывал?

Первое правило создания хороших URI - это создание URI, которые соответствуют ресурсам в вашей системе, а не операциям и действиям. Я бы создал ресурсы для ваших портфелей, но не для действий; те, которые я испекла бы внутри своего GET / POST / PUT / DELETE.

Кроме того, я не уверен, в какой момент вам нужна точная гранулярность {field} и {rule}, но это зависит от вас. Вполне возможно, что вы захотите обновить только значение поля, и в этом нет ничего плохого. Я бы, наверное, сам это поддержал, но также поддержал подъем по дереву структуры, чтобы вы могли обновить поле;

PUT /yalla/4356/portfolio/name?value=new_value

Но также обновите несколько полей;

PUT /yalla/4356/portfolio?name=new_name&other=something

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

Обновление: Далее разъяснения.

Поскольку речь идет о REST и правильном использовании URI, ничто не говорит о том, что этот ресурс;

/yalla/4356/portfolio

Не может быть;

/454A876D786F

Оба эти идентификатора представляют одну и ту же вещь. Каждый ресурс в вашей системе может получить канонический идентификатор и подобный URI, и вы можете использовать различные пути в структуре. Даже это конкретное поле;

/yalla/4356/portfolio/53464/A4576456/title

Может также иметь URI;

/3498756A8768976FF8976

Далее, о строгости того, чтобы что-то подобное ограничивало ваши URI;

{application}/{workflow}/{action}/{field}/{rule}

Это всего лишь пример. Вот несколько примеров, чтобы ваши мысли пошли;

/apps/{application}/{workflow}/{action}/{field}/{rule}
/workflows/{workflow}/{action}/{field}/{rule}
/action/{action}
/id/{id}
/api/{application}/{api}/{version}/{resource}
/property/{property}
/forms/{form}/{field}

Серьезный RESTafarian не будет слишком беспокоиться о структуре в URI. Я часто намеренно выбираю несемантические идентификаторы для вещей / сущностей / тем, используя много

/3498756A8768976FF8976

за всевозможные вещи, даже отношения между вещами. Вышеупомянутый URI может быть; тема, тема, категория, отношение, роль, поле, действие, форма, приложение и так далее.

Я пришел из мира Тематических Карт (и вы можете увидеть один из моих ответов на что-то немного другое, о этом и как это работает здесь ), в котором каждая вещь, о которой вы говорите, каждый аспектвашей модели, представлен с темой, и все темы имеют идентификаторы.(Я мог бы усложнить это и заявить, что есть три вида идентификаторов: внутренние, локальные и внешние, где последние два используют URI, но я не уверен, что это многое объясняет на этом этапе :) Например, вот тема, представляющаяприложение;

PUT /1234 name='My app'&type='application'

Это означает, что я могу говорить о своем приложении или ссылаться на него, используя этот идентификатор в любом месте моей системы (обычно у вас есть удобный кеш типов).Создайте идентификаторы, которые уникальны для каждой мелочи, и с интерфейсом RESTful было бы гораздо проще справиться.

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

/3498756A8768976FF8976

Когда вы получите этот ресурс, вы получите ответ обратно.Не уверен, с каким представлением вы собираетесь, это может быть XML или JSON или HTML со встроенными метаданными, но давайте выберем XML только потому, что пример будет простым;

<response>
   <resource id="3498756A8768976FF8976">
      <type id="field" />
      <alias uri="some/other/path" />
      <alias uri="and/another/example" />
      <relationships>
         <parent id="4563456456" type="form" />
         <child id="5784567345" type="rule" />
         <child id="3457698786" type="rule" />
      </relationships>
   </resource>
</response>

Не слишком много зная о вашемСистемные требования, вот пример, где поле (которое является <resource> с его идентификатором в нем), через которое вы можете пройти (и даже если я скажу, что id это 'type', я действительно имею в виду какой-то другой неоднозначный идентификаторкак 3459867354, которые представляют «поле», и то же самое для других идентификаторов, которые прописаны в имени, они на самом деле просто идентификаторы и прописаны для простоты понимания :), и у него есть несколько псевдонимов.Вы отображаете в отношениях, и мы видим, что это поле принадлежит определенной форме, и к нему также прикреплены два правила.Затем вы можете запросить любой из этих идентификаторов, чтобы получить метаданные о том, где они находятся, что они и как делают.

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

Но я должен сказать несколько вещей о создании системы RESTful.Клиенты REST должны уметь понимать формы, поэтому, если я запрашиваю представление XHTML (в отличие от приведенного выше XML), оно может содержать доступные мне действия;

<html>
    <body>
       <form action="/apps/1234" method="get">
          <input type="submit" title="View 1234 application" />
       </form>
       <form action="/apps/1234/567" method="get">
          <input type="submit" title="View 1234 applications' portfolio" />
       </form>
       <form action="/apps/1234" method="post">
          <input type="text" name="query" title="What to search for?" />
          <input type="submit" title="Search application 1234" />
       </form>
    </body>
</html>

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

Второе редактирование:

Я всегда избегаю множественного числа для структурированного доступа к элементам,Например, я бы использовал;

/product/345634

для определенного продукта и просто использовал;

/product

для списка всех продуктов.Например, чтобы создать новый продукт, вы отправляете POST в / product, и вы должны вернуть / product / {new_id} в случае успеха.Если вы хотите, вы также можете сделать;

/product/3456345
/products

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

Сказав это, хотя, конечно, вы могли бы сделать;

/field
/workflow
/action
/application

, чтобы добраться до коллекций этих типов. Опять же, для чего нужны те, для кого вы создаете этот API? Если это только по эстетическим причинам, т.е. ваше собственное мнение о загроможденных URI, тогда я бы сказал, что вы беспокоитесь о неправильной вещи. Короткие URI не обязательно облегчают понимание вашего API. Я бы пошел с полной структурой, о которой я говорил в начале этого ответа.

В любом случае, надеюсь, что это немного поможет, и не стесняйтесь уточнять, и я изложу дальше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...