休息API开发用于复杂的分层项目

Waq*_*qas 2 api rest uri

我们有一个复杂的结构BPM解决方案.我们现在想要将结构公开为一组休息API.

我们有一个应用程序,在应用程序中我们有工作流程,工作流程可以有动作.动作有字段和字段可以有规则.

所以现在第一组字段或规则的api被制作为

[获取] apps/1/workflows/1/actions/1/fields/4 /规则

[发布]

应用/ 1 /工作流/ 1 /动作/ 1 /场/ 3 /规则

但这看起来不太好,这些可能会变得更复杂,通常我读到的是尽可能保持URI尽可能简单,不应该进入那个深度.

那么对于上面提到的应该是首选的uri.

我们应该将字段和规则作为单独的资源吗?或者如何去做.如果我们将它作为单独的资源,那么如何获得特定的字段.它不会需要很多参数,然后又不是一个好的方法.

再次编辑

我要确认的是,如果制作我上面提到的深度URI是一个很好的标准(一些人认为这不是一个很好的方法),但正如你所提到的更像是一个选择.

那么如果我没有选择制作长URI并且保持它非常适合至少版本1,该怎么办呢?

在上面的URI示例中,我必须提供应用ID,工作流ID,操作ID和字段ID才能到达必填字段.这将保持这种方式,除非我有一些哈希来识别特定的URI.所以

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

/55667788

如果我想保持URI可读性小而该怎么办?例如, Fields/返回app 1的所有字段,工作流1动作1但是如何提供所有这些id而不会使我的URI如此混乱?保持两个级别?是可能还是我朝错误的方向走?

Ale*_*sen 8

嗯,关于这个话题还有很多话要说,但我认为具体来说这是围绕URI模板.我想我们需要使用一些更好的例子.如果您的意思是示例URI(正如您在问题中所说的那样);

apps/1/workflows/1/actions/1/fields/4/rules
Run Code Online (Sandbox Code Playgroud)

然后我会说,不,在这里你将语义引入到不需要的URI中,特别是/ workflows// actions// fields// rules /.你应该为此表示一个URI模板,我会想出这样的东西;

{application}/{workflow}/{action}/{field}/{rule}
Run Code Online (Sandbox Code Playgroud)

基本上我们可以翻译这样的URI;

/yalla/4356/open_portfolio
Run Code Online (Sandbox Code Playgroud)

进入;

application = 'yalla'
workflow = '4356'
action = 'open_portfolio'
field = ''
rule = ''
Run Code Online (Sandbox Code Playgroud)

然后看看使用了什么HTTP方法,并基于此应用动作类.你的里程会有所不同.

但是,在这一点上我有点警惕,{action}因为在REST中我们最努力地使用统一的界面,但后来我不知道你指的是什么样的动作.它让我感到更加传统的RPC思维方式,我试图摆脱它.例如,如果您有更像这样的传统RPC结构;

/yalla/4356/create_new_portfolio
Run Code Online (Sandbox Code Playgroud)

你打破了GET操作的保证安全性(比如使用/ delete_user作为操作URI的经典错误,然后让蜘蛛用GET爬行你的网站......).相反,我会这样做;

/yalla/4356/portfolio
Run Code Online (Sandbox Code Playgroud)

对于这个资源,我将GET查看,PUT更新,POST创建,删除,以及删除.从这个意义上说,{action}URI模板的一部分变得有点混乱.您希望API涵盖哪些内容?

创建良好URI的第一条规则是创建与系统中的资源匹配的URI,而不是操作和操作.我会为你的投资组合创造资源,但不会为行动创造资源; 那些我在我的GET/POST/PUT/DELETE里面烤的东西.

另外,我不知道你需要什么点的细粒度{field}{rule},但是这取决于你.很可能你只想更新一个字段值,而且没有任何问题.我可能会支持自己,但也支持爬上结构树,以便你可以更新一个字段;

PUT /yalla/4356/portfolio/name?value=new_value
Run Code Online (Sandbox Code Playgroud)

还要更新几个字段;

PUT /yalla/4356/portfolio?name=new_name&other=something
Run Code Online (Sandbox Code Playgroud)

等等,在树的结构上下.这是一个很好的做法,因为您可以让开发人员/用户灵活地选择他们希望如何使用您的API,这总是一个奖励.

更新: 更多说明如下.

既然我们讨论的是REST并且很好地使用了URI,那就没有什么能说明这个资源;

/yalla/4356/portfolio
Run Code Online (Sandbox Code Playgroud)

也不可能;

/454A876D786F
Run Code Online (Sandbox Code Playgroud)

这两个标识符都代表完全相同的东西.系统中的每个资源都可以获得规范标识符和URI,并且可以使用各种路径进入结构.甚至这个特定的领域;

/yalla/4356/portfolio/53464/A4576456/title
Run Code Online (Sandbox Code Playgroud)

也可以有URI;

/3498756A8768976FF8976
Run Code Online (Sandbox Code Playgroud)

此外,关于限制你的URI这样的严格性;

{application}/{workflow}/{action}/{field}/{rule}
Run Code Online (Sandbox Code Playgroud)

这只是一个例子.以下是几个让您的想法得以实现的例子;

/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}
Run Code Online (Sandbox Code Playgroud)

严肃的RESTafarian不会过多担心URI中的结构.我经常故意为事物/实体/主题选择非语义标识符,使用了很多

/3498756A8768976FF8976
Run Code Online (Sandbox Code Playgroud)

各种事物,甚至事物之间的关系.上面的URI可能是; 主题,主题,类别,关系,角色,领域,动作,表单,应用程序等等.

我来自Topic Maps的世界(你可以看到我对一些稍微不同的回答以及它如何在这里工作的答案),其中你谈论的每件事,模型的每个方面,都用一个主题来表示,所有主题都有标识符.(我可以使它复杂化,并声明有三种标识符;内部,本地和外部,后两者使用URI,但我不确定在这一点上解释得多:)例如,这里是一个主题代表一个应用程序 ;

PUT /1234 name='My app'&type='application'
Run Code Online (Sandbox Code Playgroud)

这意味着我可以在我的系统中的任何地方使用该标识符来讨论或引用我的应用程序(通常您可以使用类型的缓存).创建每个小东西都独有的标识符,RESTful接口将更容易处理.

至于你最近的编辑,我不太清楚我理解你在那里问什么,所以如果你提供一些例子也许会有所帮助.但是,你的意思是你自己制作了一些子属性的唯一URI吗?喜欢 ;

/3498756A8768976FF8976
Run Code Online (Sandbox Code Playgroud)

获得此资源后,您将收到回复.不确定你要使用什么表示,它可能是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>
Run Code Online (Sandbox Code Playgroud)

在不了解您的系统要求的情况下,这里有一个示例<resource>,其中您可以通过该字段(其中包含其id)(即使我说id是'type',我的意思是一些其他含糊不清的ID 3459867354代表'field',对于其他名称拼写出来的id也是如此;它们实际上只是id而且拼写为易于理解:),它有一些别名.您在关系中进行映射,我们可以看到该字段属于某种形式,并且它还附加了两个规则.您可以接下来查询这些ID中的任何一个,以获取有关它们所属的位置以及它们的来源和行为的元数据.

您当然可以直接在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>
Run Code Online (Sandbox Code Playgroud)

REST客户端可以基于此自动使用和浏览完整的应用程序.当然,有很多有趣的事情可以说,但是我担心我会进入新颖的模式,也许超出了你的问题的范围,但足以说,如果你专注于无数的形式是接口到您的应用程序,您甚至不必担心URI模板; 只需指向一个资源,获取XHTML表单,您的API应该相当容易使用并完全自我记录.

第二次编辑:

我总是避免使用复数来对项目进行结构化访问.例如,我会用;

/product/345634
Run Code Online (Sandbox Code Playgroud)

对于特定产品,只需使用;

/product
Run Code Online (Sandbox Code Playgroud)

获取所有产品的清单.例如,要创建新产品,请POST到/ product,如果成功,您应该获得/ product/{new_id}.如果你愿意,你也可以这样做;

/product/3456345
/products
Run Code Online (Sandbox Code Playgroud)

但我不推荐它.至于两个等级与任何一个等级,我认为你不应该过分担心它会变得多么混乱.系统深处的URI很少被人类解释.如果您的URI很长,这真的很重要吗?

尽管如此,当然你可以做到;

/field
/workflow
/action
/application
Run Code Online (Sandbox Code Playgroud)

获取这些类型的集合.同样,您为此创建此API的要求是什么?如果只是出于审美原因,即.你自己对混乱的URI的看法,然后我会说你担心错误的事情.短URI不一定使您的API更容易理解.我会按照我在这个答案的早期谈到的完整结构.

无论如何,希望有所帮助,并随时澄清,我将进一步阐述.