javascript - RESTful API 及相关资源

标签 javascript c# rest api wcf

我正在设计我的第一个正式的 RESTful API,它将位于 WCF 服务之上。

有这样的资源;导出,时间表和工作。时间表始终由导出拥有,并且时间表将包含 0 个或多个作业。工作不必按计划进行。

我一直认为资源应该可以像文件系统上的资源寻址方式一样进行寻址。这意味着我将拥有如下 URI:

/outlets
/outlets/4/schedules
/outlets/4/schedules/1000/jobs
/outlets/4/schedules/1000/jobs/5123

虽然在考虑如何在不同情况下拉回资源时,事情开始变得困惑。

例如我想要一份不按计划的工作:

/outlets/4/jobs/85(这意味着我们现在有两种方法可以按计划撤回工作)

例如无论导出如何,我都想要所有时间表:

/schedules/outlets/ALL/schedules

还有许多其他更复杂的要求,但我相信您已经掌握了要点。

文件系统有一个很好的、合乎逻辑的寻址资源的方式。您显然可以创建符号链接(symbolic link)并实现类似于我所描述的内容,但它会很困惑。一旦事情变得稍微复杂一点,它会变得更加困惑,例如添加按日期获取时间表的功能:

/outlets/4/2016-08-29/schedules

在不使用查询字符串参数的情况下,我什至不确定如何请求回所有未按计划进行的作业。以下感觉不对,因为 unscheduled 不是资源:

/outlets/4/unscheduled/jobs

因此,我开始认为文件系统类型寻址仅适用于最简单的服务(我们的底层系统有数百种实体类型,具有一些非常复杂的关系和大量操作)。

用多种方法做同一件事往往会导致困惑和困惑的文档,我想避免这种情况。因此,我几乎被迫选择使用最低公分母并选择非常简单的地址形式 - 如下面的第三个:

/outlets/4/schedules/1000/jobs/5123
/outlets/4/jobs/5123
/jobs/5123

从这些非常简单的地址表单中,我需要使用查询字符串参数进行扩展以执行更复杂的操作,例如:

/jobs?scheduleId=1000
/jobs?outletId=4
/jobs?outletId=4&fromDate=2016-01-01&toDate=2016-01-31

这感觉就像它违背了 REST 模型,而且像这样的查询字符串参数是不可预测的,与“不需要文档”的想法相去甚远。

好吧,现在我几乎站在栅栏的一边说为了获得一个干净、可维护的 API 我将不得不使用非常简单的资源地址,广泛使用查询字符串参数并有很好的文档。

总之,这似乎不是我应该得出的结论。我哪里出错了?

最佳答案

欢迎来到 REST API 编程世界。这些是我们在尝试将一般原则应用于特定情况时都面临的难题。您的问题没有明确简单的答案,但这里有一些可能有用的额外提示。

首先,您是对的,当您拥有复杂的关系时,文件系统寻址方法就会失效。只有在存在真正的层次结构 时,您才会想要建立那种寻址方式。

例如,如果所有作业都是单个计划的一部分,那么查看 schedules/{id}/jobs/{id} 以获取给定作业是有意义的。如果您从数据存储的 Angular 考虑它,您可以想象每个计划都有一个 XML 文件,而作业只是该文件中的元素。

但是,在这种特殊情况下,您的数据听起来更关系。从数据存储的 Angular 来看,您会将每个作业表示为数据库表中的一行,并建立一些外键关系以将一些作业与一些计划联系起来。您的寻址方案应通过使 /jobs 成为顶级端点来反射(reflect)这一点,并在必要时使用可选的查询字符串参数按时间表或导出进行过滤。

所以您走在正确的轨道上。您可能需要考虑的另一件事是 OData,它通过一种面向标准的方式来扩展基本的 REST 原则,以表示诸如使用查询字符串参数进行过滤之类的事情。地址语法感觉有点“在那里”,但它在处理直接 REST 开始崩溃的情况方面做得很好。而且因为它更加标准化,所以有一些工具可用于帮助处理诸如从数据层转换为 OData 端点,或基于该端点公开的元数据生成客户端代理助手等事情。

This feels like it's going against the REST model though and query string parameters like this aren't predictable, so far from the "no docs needed" idea.

如果您使用 OData,那么它的规范会与您的工具生成的元数据相结合,成为您的文档。例如,您的元数据表明 job 具有代表日期的 date 属性。然后 OData 规范提供了一种方法来表示日期值的筛选查询。从这些信息中,消费者可以可靠地生成一个“正常工作”的过滤器查询,因为您正在使用框架服务器端来完成困难的部分。如果他们不想记住 OData URL 的工作原理,他们可以用他们选择的语言生成一个客户端代理,这样他们就可以通过他们最喜欢的语法生成适当的 URL。

关于javascript - RESTful API 及相关资源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39210578/

相关文章:

javascript - LI 中的 Scriptaculous Ajax.Autocompleter 额外功能

javascript - 使用 ionic 范围来设置月份和年份

Javascript - 在框架中加载页面

c# - 无法使用 inkscape 从 ASP.NET 生成文件

c# - WebInvoke 方法 = *

c# - 当未选择行时,复选框列第一次不会更改其状态

java - "/"的 Restful 路径用法

javascript - 从文件内容设置状态

javascript - 如何使用 jQuery/ajax 发出 GET 请求?

ios - 没有核心数据示例的Restkit