在我的REST API中,我应该使用信封吗?如果我在一个地方使用它,我应该总是使用它吗?

Jes*_*per 28 rest

我正在构建一个RESTful Web服务.我已经阅读了为每个机制使用HTTP的原则,只要它会占用你,而且大多数时候,就像获取资源一样,它工作得很好.

但是当我需要发布某种新条目时,为了清晰和健壮,无论客户端做什么,我都想提供新条目可能失败的特定验证错误.此外,存在特定错误,例如,用于创建新用户的数据完全有效,但可以采用昵称或电子邮件地址.简单地返回409 Conflict没有详细说明昵称或电子邮件地址的详细信息.

所以解决这个问题不是火箭科学:记录一堆特定的错误代码并返回一个有错误的对象:

{ errors: [4, 8, 42] }
Run Code Online (Sandbox Code Playgroud)

这意味着在请求失败的情况下,我不会返回REST哲学所预期的资源或密钥.类似地,当我返回许多资源时,我必须以某种方式在数组中构造它们.

所以我的问题是:如果我为每个请求标准化一个信封,我是否仍然会提供一个表现良好的RESTful Web服务,例如,总有一个像这样的对象{ errors, isSuccessful, content }

我之前已经构建了使用它的RPC风格的Web服务,但我不想做一些"几乎是REST"的东西.如果有任何关于REST的意义,我希望尽可能保持良好的行为.

如果答案是"地狱没有",我认为它可能是,我想知道它是否至少正确地解决了验证问题,并且对于这种问题解决可能是一个很好的参考,因为大多数指南我都是我发现只详细的简单案例.

sof*_*arn 25

我会说"好吧!" (与此处有人说"地狱不"的信息相反)总有一些额外的信息需要从某些端点发送.例如,分页,errorMessages,debugMessages.facebook如何做到这一点的一个例子:

Response from get friends request

{
  "data": [
    {
      "id": "68370", 
      "name": "Magnus"
    }, 
    {
      "id": "726497", 
      "name": "Leon"
    }, 
    {
      "id": "57034", 
      "name": "Gonçalo"
    }
  ], 
  "paging": {
    "next": "https://graph.facebook.com/v2.1/723783051/friends?fields=id,name&limit=5000&offset=5000&__after_id=enc_AeyGEGXHV9pJmWq2OQeWtQ2ImrJmkezZrs6z1WXXdz14Rhr2nstGCSLs0e5ErhDbJyQ"
  }, 
  "summary": {
    "total_count": 200
  }
}
Run Code Online (Sandbox Code Playgroud)

在这里,我们分别用下一个链接来请求获取下一个用户块,以及一个摘要,其中包含可以获取的朋友总数.然而,他们并不总是发送这个信封,有时数据可以直接在身体的根部.始终以相同的方式发送数据使客户端更容易解析数据,因为它们可以对所有端点执行相同的操作.客户端如何处理信封响应的一个小例子:

public class Response<T> {
  public T data;
  public Paging paging;
  public Summary summary;
}

public class Paging {
  public String next;
}

public class Summary {
  public int totalCount;
}

public class WebRequest {
  public Response<List<User>> getFriends() {
    String json = FacebookApi.getFriends();
    Response<List<User>> response = Parser.parse(json);
    return response;
  }
}
Run Code Online (Sandbox Code Playgroud)

然后,只需将List更改为端点返回的数据,即可将此Response对象用于所有端点.

  • 此示例不是RESTful.元数据进入标题.通过将摘要数据与详细数据包括在一起,您可以将双重目 在设计API时,您需要考虑整个系统架构.使用此设计缓存会有问题.http://restcookbook.com/ (9认同)
  • 我一直开始把分页视为YAGNI; 它在设计时似乎是一个好主意,但从不需要,因为大多数用户将搜索而不是分页数据.分页是保持信封的唯一引人注目的用例,因此我一直在完全放弃它. (2认同)
  • 不,HTTP 是信封。不要用元数据污染正文数据。相反,应将此元数据放在它所属的位置,即 HTTP 响应标头中。例如。对于分页,请使用链接标头。 (2认同)

nat*_*ood 16

HTTP 你的信封.通过返回4**错误代码,您正在做正确的事情.

话虽如此,在响应中设置描述性主体并没有错 - 实际上HTTP RFC中,大多数HTTP错误代码都主张您确实返回错误发生原因的描述. 例如,参见403:

如果请求方法不是HEAD并且服务器希望公开为什么请求没有得到满足,那么它应该描述实体中拒绝的原因.

所以你可以继续使用响应的主体来更详细地描述错误.如果您不确定要使用的特定HTTP错误响应(例如多个错误),并且您知道用户不应该重复请求,那么我通常会回到使用400.