十个书写Node.js REST API的最佳实践(下)

《十个书写Node.js REST API的最佳实践(上)》

5. 对你的Node.js REST API进行黑盒测试

测试你的REST API最好的方法之一就是把它们当成黑盒对待。

黑盒测试是一种测试方法,通过这种方法无需知道应用内在的结构或者工作机制,就可以检测到其功能。因此依赖不会被mock或者stub,但是系统会被作为一个整体来测试。

译者注:mock 和 stub 都是测试的方法

有个可以帮你进行Node.js REST API进行黑盒测试的模块叫做supertest

一个简单的测试用例,其使用测试运行器mocha检查一个用户是否被返回,可以这么用:

const request = require('supertest')

describe('GET /user/:id', function() {  
  it('returns a user', function() {
    // 更新的mocha也可以使用promise
    return request(app)
      .get('/user')
      .set('Accept', 'application/json')
      .expect(200, {
        id: '1',
        name: 'John Math'
      }, done)
  })
})

你可能会问:数据是怎么被构建到服务REST API的数据库里的?

通常,覆盖尽量多系统状态的方式来书写你测试代码是个很好的方法。然而,有时候你会发现自己处于一个需要准确知道系统状态的情况,因此,你可以果断点,同时达到更高的测试覆盖率。

因此基于你的需要,你可以使用下面的任何一种方法来把数据库用测试数据填充:

  • 在已知产品数据集上运行你的黑盒测试方案
  • 在测试用例运行之前使用构造的数据填充数据库

当然,黑盒测试并不意味着你不需要做单元测试,你依旧必须给你的API写单元测试

6. 做基于JWT的无状态认证

由于你的REST API必须是无状态的,你的认证层也是。从这点来看,JWT (JSON Web Token)是完美的。

JWT由三个部分组成:

  • Header,包含token的类型和散列算法
  • Payload,包含声明
  • Signature (JWT不对payload加密,直接签名就对了!)

给你的应用添加基于JWT的认证是很简单的:

const koa = require('koa')  
const jwt = require('koa-jwt')

const app = koa()

app.use(jwt({  
  secret: 'very-secret' 
}))

// Protected middleware
app.use(function *(){  
  // content of the token will be available on this.state.user
  this.body = {
    secret: '42'
  }
})

之后,API末端随着JWT被保护。为了使用受保护的末端,你需要在Authorization头区域里提供token。

curl --header "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ" my-website.com

你可能注意到一件事,就是JWT模块不依赖任何数据库层。事实就是这样,因为所有的JWT token可以自我验证,并且它们也包含存留时间值。

同样的,你要一直确保所有的API末端只能被使用了HTTPS的安全连接通过。

7.使用条件请求

条件请求是因特定HTTP头而异的HTTP请求。你可以把这些头想作先决条件:如果他们被碰到,请求会以一种不同的方式执行。

这些头会试着检查存储在服务器上资源的版本是否和同样资源的给定版本一致。由于这个原因,这些头可以是:

  • 上次修改的timestamp
  • 或者一个每个版本都不同的实体标签

这些头是:

  • Last-Modified(表明资源被上次修改的时间)
  • Etag(表明实体标签)
  • If-Modified-Since (和Last-Modified头一起用)
  • If-None-Match (和Etag头一起用)

让我们一起看下一个例子!

下面的客户端没有任何doc资源的先前版本,因此当资源被发送时无论If-Modified-Since还是If-None-Match都没有被应用。然后,服务器带着EtagLast-Modified正确地返回设置。

来自MDN条件请求文档

一旦客户端尝试请求同样的资源,其可以设置If-Modified-SinceIf-None-Match的头,因为它现在已经有了一个版本。如果响应是一样的,服务器会直接以304 - Not Modified状态码响应,同时也不会再次发送资源。

来自MDN条件请求文档

8. 接收率限制

接受率被用来控制特定消费者可以发送给API的请求数。

为了告知你的API用户他们还剩余多少请求,设置如下的头部 :

  • X-Rate-Limit-Limit,在给定的时间间隔内允许的请求数
  • X-Rate-Limit-Remaining, 同一时间间隔内保持的请求数
  • X-Rate-Limit-Reset, 接受率被被重置时的时间

大部分HTTP框架自带(或者通过插件)支持这一功能。例如,如果你在使用Koa,有个叫koa-ratelimit的包。

需要注意的是,基于不同的API提供者,时间窗口也会有所不同——例如,Github用的是一个小时,而Twitter用的是15分钟。

9. 创建合适的API文档

你书写API,这样其他人就可以使用它们,并从中收益。给你的Node.js Rest API提供API文档是很重要的。

下面的开源项目可以帮你给你的API创建文档:

此外,如果你想使用托管产品,可以试试Apiary

10. 不要错过API的未来

过去那几年里,API调用的两个主要查询语言——也就是Facebook的GraphQL和Netflix的Falcor。但是我们为什么还需要它们呢?

看看下面这个RESTful资源请求:

/org/1/space/2/docs/1/collaborators?include=email&page=1&limit=10

这很容易失控——正如你想一直为你的模型获得同样响应格式一样。这就是GraphQL和Falcor发挥所长的地方。

关于GraphQL

GraphQL是一个给API用的查询语言,其同样也是一个使用你的现存数据填充这些查询的运行环境。GraphQL提供一个你的API数据的完整和易懂的描述,给予客户端能力以获取其所需要的并且绝不多做,随着时间推移让扩展API更加容易,并且提供强有力的开发工具。—— 这里可以了解更多

关于Falcor

Falcor是推动Netflix UI的创新性数据平台。Falcor允许你在Node服务器端把你所有的后端数据模拟成单个的虚拟JSON对象。在客户端上,你使用熟悉的JavaScript操作像get,set和call来和远程的JSON对象一起工作。如果你了解你的数据,那么你也会了解你的API。——在这里了解跟多

令人惊讶的REST API,激发你的灵感

如果你正准备开始开发Node.js REST API或者给一个旧的项目开发新版本,我们在这里精心挑选了四个值得check out的真实案例

我希望现在你对怎么使用Node.js书写API有一个更好的认知。如果你错过了什么,请在评论里面让我知道。

原文链接:

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏ChaMd5安全团队

Memcache UDP反射放大攻击实验

无耻的接受了p猫的py交易,自己也想实验下memcached这个放大攻击 0x01 前言 近日,一种利用Memcached缓存服务器来作为放大器的DRDOS攻...

810100
来自专栏小狼的世界

提高Mac下itunes的下载速度

给老婆买了iPhone4s之后,开始在Mac上用iTunes下载软件,发现速度龟速,好歹家里也是10M光纤啊,这个小水管的下载速度绝对不能忍受,于是百度了一下,...

15020
来自专栏醉程序

怎么使用slim-jwt-auth对API进行身份验证

27020
来自专栏Fundebug

Web应用架构入门之11个基本要素

译者: 读完这篇博客,你就可以回答一个经典的面试题:当你访问Google时,到底发生了什么?

15630
来自专栏FreeBuf

更适合作为主系统使用的Parrot Security简介

Parrot 是一个基于Debian的专注于渗透测试和隐私保护的Linux发行版,但是更加方便日常使用,有贴心的使用体验,丰富的工具,更注重隐私保护。 The...

1K50
来自专栏Java进阶干货

Tomcat中用JNDI方式加载JDBC DataSource以连接数据库

下载与所要连接的数据库版本对应的JDBC驱动程序,加入到应用的CLASSPATH。如果用tomcat部署,tomcat中最好也加上(笔者觉得好像没必要加,可是不...

19520
来自专栏信安之路

锁首技术总结

在公司实习也有一个月了,学到不少东西,不知不觉就要大四了,回首漫漫安全路,不禁感慨万千:我入安全的时间比较晚,大一大二跟着老师参加 Android 移动应用开发...

14920
来自专栏linux驱动个人学习

深入 kernel panic 流程【转】

我们在项目开发过程中,很多时候会出现由于某种原因经常会导致手机系统死机重启的情况(重启分Android重启跟kernel重启,而我们这里只讨论kernel重启也...

73510
来自专栏漏斗社区

黑客游戏| Owasp juice shop (三)

0x01 前言 继续上一篇的内容,往下闯关。想了解如何搭建的同学可参考第一篇文章。 看第一篇:黑客游戏| Owasp juice shop (一) 0x0...

41760
来自专栏信安之路

用powershell下载文件的姿势你研究过吗?

PowerShell 的最大优势在于以 .NET 框架为基础。 .NET 框架在脚本领域几乎是无所不能,这是一个优点,也有可能成为一个方便黑客攻击的一个强大的便...

62100

扫码关注云+社区

领取腾讯云代金券