REST中HTTP GET响应的正确设计原则是什么,需要返回2组不同的响应

时间:2015-10-14 02:36:49

标签: java rest server

我想了解在根据REST设计HTTP GET响应时应遵循哪种方法。我有以下要求

class Employee {
   private long employeedID;
   private String name;
   private Date dob;
   private String address;
   private String department;
}

根据REST建模,HTTP GET / employees将返回所有员工的数组。类似地,HTTP GET / employees / 1将返回Id为1的员工

现在有一个UI驱动的工作流程,我需要只显示每个员工的名称 employeeID 。因此,HTTP GET /员工的现有响应是重量级的(其他字段是不必要的转移)。因此,我希望将响应限制为仅包含每位员工的名称 employeeID

我正在评估以下选项

方法1:

使用Content-Type HTTP标头指示发出HTTP GET / employees请求的客户端需要在响应中修剪属性列表。我在Content-Type(即application.summary + json)中有一些自定义字符串,这将导致只有2个属性被包含在响应中

方法2:

使用其他查询参数作为HTTP GET / employess?isSummary = true。在这种情况下,在服务器端,根据 isSummary 参数的值,我只能为每个员工返回2个属性

方法3:

创建一个新的REST端点本身,支持修剪后的响应,即HTTP GET / employees / summaryDetails

在这种情况下,在上述端点中仅返回2个属性。

这三种方法中哪一种最接近REST?

由于

3 个答案:

答案 0 :(得分:2)

我认为方法#2 领域的某些方面是这里的方法。从根本上说,您仍然在资源(Employee)方面访问相同的搜索和结果集,并且它是相同的资源。所以方法#3不太适合。

也就是说,有很多方法可以解决#2。一种方法是使用表示投影的查询字符串参数 - 类似于SQL投影。如下所示:

GET /employees?fields=ID,name

我使用了一些以这种方式工作的API,并且它们运行良好。

答案 1 :(得分:1)

此答案作为以下评论this回答中的讨论的后续行动添加。

基本上,是的,我反对HATEOAS。为什么?一般来说这个想法很好,但是:

  1. IMO在涉及端点数量时往往会删除合理的限制。似乎某些开发人员的回答它是RESTful ......?还是如何在REST中执行...?经常是:添加新端点/data/{id}/add/,将通过_links元字段进行记录。这不是应该怎么做的。这样,您始终可以添加新的端点和适当的链接,并完成大量无法理解或验证的端点。例如。此链接返回基本数据集:

    "http://foo.bar/employees/1"
    

    这将返回更多细节:

    "http://foo.bar/employees/1/details"
    

    如果我需要其他细节子集怎么办?我会添加一个新的端点吗?并且..如果有多个不同的客户需要互斥,该怎么办? 数据子集?每个客户端都有一个专用端点?这是一场噩梦!

  2. 链接不仅仅是关于URL,也是查询参数。它们是否包含在链接中?以什么形式?模板?所以我不能按原样关注链接。每个参数都有一个默认值?我想这不是简单的可能为每个查询参数提供默认值。

  3. 上述可发现性和文档。相信我,对于您设计,开发和部署的大多数API,您需要编写文档。为什么?因为订购此API的公司需要它。 stripe.com遵循HATEOS规则吗?没有!那为什么它如此成功?因为它非常好documented并且有多个库以及多种最流行的语言和工具中的示例。

  4. 找时间查看this对话,这是值得的。

  5. 现在关于HATEOAS的简短注释之后。

    方法#1

    当资源版本更改(添加或删除新字段)本身而不是您需要特定字段或资源子集时,应使用标头。所以IMO不是这样的。

    方法#3

    对于这个答案的介绍中提到的原因,这是一个非常糟糕的主意。

    方法#2

    恕我直言,这是要走的路。正如@leeor所说,这是一种受欢迎的,被接受的和灵活的模式。

    您可以通过添加一个名为eg的查询参数来扩展它。 view这是一个枚举(SIMPLEEXTENDEDFULL),代表预定义视图的列表。这是避免添加新端点的方法。而是添加并记录(!)新视图。如果viewfields相互排斥或处理它们的顺序,则取决于您。

答案 2 :(得分:0)

每种列出的方法的问题在于它使API复杂化,并且可能违反了REST的最基本原则,即可发现性。响应没有提供任何上述API存在的线索。你必须阅读文档(恐怖!)。 REST的基本规则是HATEOAS:超文本作为应用程序状态的引擎。

因此,如果您想要一个最大 RESTful的API,请考虑以下内容,该标准遵循HAL标准:

此:

HTTP GET /employees

的产率:

[ {
    "employeeID": 1,
    "name": "Joe",
    "_links": [ {
        "rel": "self",
        "href": "http://foo.bar/employees/1"
    }, {
        "rel": "details",
        "href": "http://foo.bar/employees/1/details"
    } ]
}, {
    "employeeID": 2,
    "name": "Sam",
    "_links": [ {
        "rel": "self",
        "href": "http://foo.bar/employees/2"
    }, {
        "rel": "details",
        "href": "http://foo.bar/employees/2/details"
    } ]
} ]

点击链接:

HTTP GET /employees/1

的产率:

{
    "employeeID": 1,
    "name": "Joe",
    "_links": [ {
        "rel": "self",
        "href": "http://foo.bar/employees/1"
    }, {
        "rel": "details",
        "href": "http://foo.bar/employees/1/details"
    } ]
}

关注另一个链接:

HTTP GET /employees/1/details

的产率:

{
    "employeeID": 1,
    "name": "Joe",
    "dob": "1985-04-23",
    "address": "123 Main St",
    "department": "Department of Redundant Links",
    "_links": [ {
        "rel": "self",
        "href": "http://foo.bar/employees/1"
    }, {
        "rel": "details",
        "href": "http://foo.bar/employees/1/details"
    } ]
}

要获得灵感,请查看JIRA REST API,可能是我见过的最好的。{/ p>