微信小程序云开发中我们可以在云函数中调用外部系统的API, 比如企业已有的Rest服务API, 通过这样的方式,可以复用企业原有的逻辑,也可以与企业系统集成或是访问或是调用外部的公共服务。

在本文中,我们通过调用一个公共的天气服务来演示如何在云函数中调用外部API。

新建云函数

首先在构建一个名为 my-note-app 的小程序,开通云开发,然后在 cloudfunctions 中新建一个云函数,并命名为 CallExternalAPI。建好以后,可以看到在 cloudfunctions 中添加了一个名为 CallExternalAPI 的目录,目录中包含两个文件: index.js 和 package.json。都是默认内容:

index.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 云函数入口文件
const cloud = require('wx-server-sdk')

cloud.init()

// 云函数入口函数
exports.main = async (event, context) => {
const wxContext = cloud.getWXContext()

return {
event,
openid: wxContext.OPENID,
appid: wxContext.APPID,
unionid: wxContext.UNIONID,
}
}

package.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"name": "CallExternalAPI",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"wx-server-sdk": "latest"
}
}

安装第三方库

在小程序的api中,可以使用 wx.request 在小程序端来访问外部的api, 但这些api所在的主机必须被配置在小程序后台,作为信任的主机。现在如果我们希望从云函数中访问外部的API,则不能采用这个方法。因为我们选择使用Nodejs的第三方库开访问。这里我们选择流行的 axios 库。

打开命令行窗口,进入项目中云函数所在的目录。比如项目在 d:\my-note-app 目录,则进入 d:\my-note-app\cloudfunctions\CallExternalAPI 目录,执行 npm 来安装 axios 库。

1
npm install --save axios

安装完成后,你可以看到在 package.json 中加入了 axios 的依赖。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"name": "CallExternalAPI",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"axios": "^0.19.0",
"wx-server-sdk": "latest"
}
}

同时在命令行中中查看,可以看到在目录中多了 node_modules 目录,里面放的就是相关的依赖库。

1
2
3
4
5
6
7
my-note-app
+ cloudfunctions
+ CallExternalAPI
+ node_modules
index.js
package.json
package-lock.json

调用天气服务

在 index.js 中增加对天气api的调用,修改后的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// 云函数入口文件
const cloud = require('wx-server-sdk')
const axios = require('axios')

cloud.init()

async function getWeather() {

console.log('start getWeather')

var data = {}

try {

var res = await axios.get('http://wthrcdn.etouch.cn/weather_mini', {
params: {
city: '北京市'
}
})

data = res.data.data

} catch (err) {
console.log(err)
}
return data
}

// 云函数入口函数
exports.main = async (event, context) => {

const data = getWeather()

return data
}

可以看到,我们新建了一个名为 getWeather 的函数,在该函数中,使用 axios 的 get 访问用了天气服务。并将结果返回。

部署函数到云端

选择函数,点右键,选择 “上传并部署: 云端安装依赖(不上传node_modules)”, 因为package.json 会上传到云端,云端会更加 package.json 对的内容自动安装相关的依赖在云端,这样就可以显著的减少上传的大小和时间,加快部署速度。

从小程序端调用

因为对第三方API的调用被封装在云函数中,故调用和普通的小程序调用云函数一样, 使用 wx.cloud.callFunction 即可。

1
2
3
4
5
6
7
8
9
10
11
12
wx.cloud.callFunction({
name: 'CallExternalAPI',
data: {
}
}).then(res => {
console.log(res)
that.setData({
weather: JSON.stringify(res.result)
})
}).catch(err => {
console.log(err)
})