avatar

ShīnChvën ✨

Effective Accelerationism

Powered by Druid

在微信小程序中使用FeathersJS的RESTful API

前言

最近在做微信小程序开发,为已有的一个Web应用程序提供微信小程序客户端。这个Web应用程序基于FeathersJS 开发,提供RESTful API,因此也想在小程序共用大部分API。

微信小程序中的HTTP请求

微信小程序开发中使用wx.request(Object object) 这个API进行http数据请求,且仅支持https证书加密访问。

JWT认证

微信小程序的容器并不是一个标准的浏览器,在使用wx.request 这个api进行数据请求时,并不会自动带上cookie、session等信息,因此需要自行管理认证信息。我们的应用程序使用的认证方式是jwt ,要实现jwt认证只需要在发送http请求时将token放于header中即可,这和Android、iOS端的http请求框架封装没有什么两样。

CRUD

请求方法对照

参考维基百科中对CRUD 的描述,我制作了这样一张表来对照微信小程序中http请求方法与RESTful API中的接收请求方法。

Operation SQL HTTP RESTful WS DDS FeathersJS REST Client
Create INSERT PUT / POST POST WRITE create
Read(Retrieve) SELECT GET GET read / take get / find
Update(Modify) UPDATE PUT / POST / PATCH PUT write update / patch
Delete(Destroy) DELETE DELETE DELETE dispose remove

根据我的实际情况,其中HTTP列是微信小程序端的请求方法(method),FeathersJS RESTclient列为FeathersJS server api 中的接收请求方法。

微信小程序没有PATCH

微信小程序的wx.request不支持PATCHFeathersJS中的update两种请求方式,因此我们只能使用功能类似的PUT来完成数据修改。

而这是为什么呢?我在寻找解决方案的过程中,我查到了以下这些文献,也许能解释为什么微信团队会选择禁用或者不实现PATCH方法:

根据维基百科中对PATCH的描述:

  • The PATCH method is a request method supported by the HTTP protocol for making partial changes to an existing resource.
  • PATCH方法是HTTP协议支持的请求方法,用于对现有资源进行部分更改。

spring.io 关于的REST 的文档中提到:

  • Update only the specified fields of an entity at a URI. A PATCH request is neither safe nor idempotent (RFC 5789). That's because a PATCH operation cannot ensure the entire resource has been updated.
  • 仅更新URI上实体的指定字段。 PATCH请求既不安全也不是幂等(RFC 5789)。 这是因为PATCH操作无法确保整个资源已更新。

转发PUT到PATCH

FeathersJS中使用基于Sequelize 所创建的Service,无论是update 还是patch 都支持仅更新部分提交的字段,未提交的字段会被忽略。而我们项目中使用的是基于knex的Service,如果在小程序上调用PUT且不传全属性,则会将没有传的属性会当作null更新进数据库,如果在其他客户端调用UPDATE且不传全属性,则会返回400请求体错误。

为了能够支持部分属性更改,我在FeathersJS app启动时添加了一个简单的middleware,将api路由上所有的UPDATE和PUT求请改成了PATCH:

app.use('/api/*', function (req, resp, next) {
  if (req.method.toUpperCase() === "PUT" || req.method.toUpperCase() === "UPDATE") {
    req.method = 'PATCH';
  }
  next();
});