AngularJS后台API服务之计划性考虑

自己于《写在极端前方》里说了,后台API的文档至关重要。不过,文档只是外在表现形式,设计才是真的的魂。我在即时篇博文主要介绍的哪怕是自当后台开发过程被,设计API时之考虑。我单独说他是考虑,因为众多东西不见得是是的,更不见面是绝了。

 

首先,我要是声明的是,我重点是参照下面就篇稿子(以下简称最佳实践)里的见解:

 

  http://www.cnblogs.com/yuzhongwusan/p/3152526.html  [题: RESTful
API 设计最佳实践]

 

这是同等篇翻译过来的博文,原文地址是:

 

  http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api

 

脚是本人根据那篇文章的片加;也就是说,读者得先念一诵读那同样篇:

 

1.
我之接口设计受到连没有形如/tickets/12/messages/5的接口,因为于自我的资源管理着,id是大局唯一的,不待使用12-5这么的一路id。我之代方案是:/ticket_messages/112255

 

2.
就像最佳实践博文里之所提取的那样,我的List接口中也采取了像sort、分页等体制,搜索这块也使用了显著的q参数。我还参加了include和with_total,
just_total等控制。

 

include:
这是釜底抽薪突出的N+1问题之方案。例如我们定义Ticket资源,同时每个Ticket资源绑定到(belongs_to)一个User资源。通过调用接口/tickets可以拜Ticket列表。此时只有见面回Ticket的音,而休会见放到Ticket的主人User的音信,只是嵌入一个user的id字段,如下:

[
    {
         ...ticket1...,
        user_id: 1
    },

    {
         ...ticket2...,
        user_id: 2
    },
    ...
]

此间见面回N个Ticket,调用了一样不良接口。另外,如果想要更为理解每个Ticket的User的音信,需要调用N次/users/:user_id接口,如下:

  /users/1

  /users/2

    …

  /users/N

顿时便是闻名的N+1问题。这样不光浪费带富,而且为或会见影响数据库查询效率。更要的凡,这无疑增加了前者的工作量。使用include参数的模式是在接口调用中宣示如含有的分段资源,通过一致破接口调用实现N+1此接口调用的功用。调用/tickets?include=user,返回的形式是:

[
    {
        ...ticket1...,
        user: {
            id: 1,
            ...user1...
        }
    },
    {
        ...ticket2...,
        user: {
            id: 2,
            ...user2...
        }
    },
    ...
]

是就是是咱们后台API目前底计划款式。其中include字段可以配备包含多单有关资源,用逗号分隔即可。

更作证以下是计划的一个有些缺陷。就是出新无雷同的景况。如果回去的结果存储在tickets中,那么首先个Ticket是tickets[0],那么没安装include参数时,取user的id是tickets[0].user_id;当设置include=user时,取user的id是tickets[0].user.id。在取Ticket的User的id时,出现了调用的免相同,不好。

好对不起,我甚至没意识及《最佳实践》里已发生只近乎字段embed了。有些概念讲重复了。

 

with_total,
just_total
:一般的话,我于设计”列出…”的API接口时,仅仅返回的是公用的数组。这其中包含能够兼容的资源的总数信息。最常用之情状是做分页的时光,这个总数信息方可导出总页数,进而判断时的请求页是否是最终一页,从而在这儿亦可生好地灰选下同样页按钮。我同开始免思补充加这么的力量,因为我看用瀑布流刷数据是更不行的主意,这时候通过返回一个空数组指示没有再多数据即可。仅仅返回一个屡次组,便于前端开箱即用返回数据,也毕竟一个微小便利吧。最后还是上加了之功能,毕竟全部瀑布流的计并无克全适应前端的计划性,而且有时确实需要了解一个消息的关心总量这样的音讯。这时候添加少独控制参数with_toal,
just_total,它们的施用是排斥的。它们是控制字段,不用显示赋值为true,只要这个字段存在即可。

 

例如/tickets?with_total, /tickets?with_total=true,
/tickets?with_total=false都是回来如下结果(总数存储于total字段中,数据数组存储于list字段中):

{
    total: 1234,
    list: [
        ...
    ]    
}

just_total仅仅返回总数信息,抹去了list字段,这个时候即便甭做片分页控制了,因为没有效果。即:

{
    total: 1234
}

 

3. 筛选控制

 

所谓筛选,是依赖经规范查询返回匹配的资源。例如只回address在’上海‘的User资源。《最佳实践》中是故一个近乎’address=上海’这样的参数来支配标准查询。我从不使用这种分散的方式,而是把富有的询问有关规则还定义在cond这一个参数中。在点的例证中,大致应该是cond={address:
‘上海’}。注意这里我因此了javascript语法已减少输入,您可以拿它们看做等效的JSON语法。也就是说,cond参数的档次应该是一个对象,在内部定义有的询问逻辑。更具体地说,cond参数应该是同样多级的键值对,键是要配置的许段名,如address,值是配合的平整,如设置成’上海’,就是说是字段要完全等于’上海’这个字符串。例如当’address=上海&age=18’这样的多配段匹配的情状下,用cond语法就活该是cond={address:
‘上海’, age:
18}。现在于本人之路里我委为无非开了这些,诸如其他的age>18,age<18都没落实。好以今日种规模非常有点,还从来不因此到这些。

 

将兼具查询控制封闭装在一个cond参数中好接口的统一性,也惠及我联合实现。

 

唯独,接下自己最主要而说的凡,这其间来坑。此坑在于,GET方法(上面所说的那些是用来HTTP
GET
METHOD)中,没有请求求体,也即未能够指定Content-Type=application/json。在cond中定义一个键值对聚集,用json是老大自然之方式,不过未能够传递json。GET方法吃一旦要是传送参数,只能叠加以url中的query
string当中。我无确定会不能够传递json格式的多少,但我实际没有中标了。一般的话,query
string的格式是field1=value1&field2=value2&…这样的形式。有一个非成文的预约,当传递数组时,使用array[]=v1&array[]=v2&…这么的形式,当传递对象,例如地方的cond中的对象,形式是cond[address]=上海&cond[age]=18.
斯约定不是放开的所在皆准。项目之前端采用的凡AngularJS,如果调用Resource的点子时,将下面的目标作为请求参数(我倍感这样针对性前者来说是不过当的),会叫后端收到的query
string那段非常地无健康:

{
   ..., //首先可以有分页,排序等参数
     cond: {
         address: '上海',
         age: 18
     }   
}

最终前端采用了一如既往种植不自的调用方式,是底下:

{
   ..., //首先可以有分页,排序等参数
     'cond[address]': '上海',
     'cond[age]': 18
}

自以考虑下两种植缓解方案:

用cond参数的靶子转化成JSON字符串,这样

{   ..., //首先可以有分页,排序等参数
     cond: JSON.parse({
         address: '上海',
         age: 18
     })
}

还是采用POST方法来查询数据,接口是POST /users/query
查询条件可以据此json格式写以呼吁求体中。

前方一样栽方法并无可知吃自己乐意,后同样种植实现起来较为麻烦。要拍卖GET /users和POST
/users/query两栽情形。

 

4. 错误返回

 

我的统筹里是富含出错情况的。当需要回到用户一个串消息的时,首先会回去一个状态码。就像《最佳实践》里面说的,有些是自家肯定使的,它们是:

  • 400 Bad Request (错误的求) – 请求是怪的, 比如无法解析呼吁求体
  • 401 Unauthorized (未授权) –
    当没有供或供了不算认证细节时。如果打浏览器采用API,也得就此来触发弹出同样破证实要
  • 403 Forbidden (禁止访问) – 当证成功可认证用户无权访问该资源时
  • 404 Not Found (未找到) – 当一个非存的资源让求时
  • 422 Unprocessable Entity (无法处理的实业) – 出现验证错误时用
  • 500 Internal Server Error (服务器间错误) –
    服务器总会出现未知错误的

深信就项目的上进,更多之状态码会用起来。

继之返回体中会回到一个json格式的不当信息。它的指南是:

{
    message: 'something is wrong'
}

而,我再眷恋使的样板是:

{
    code: code, //更细致的错误编号,必要时提供
    error: error, //错误消息,面向API的调用者,必要时提供
    message: message //错误消息,此消息可以让前端使用alert之类的方法显示给终端用户,必要时提供
}

开此改变,是因自发觉前端有时需要看清错的品种因做出相应的动作。另外,有时出错消息可以非常随便地归结出面向终点用户之唤醒音,但有时候又不得不提供给API的调用者一个普遍的荒谬提示。并且,API调用者和用户的关注点是休一致的。

相关文章