前言

最近在校内的三叶草比赛中需要使用 leancloud 作为后台服务的提供者,但从看文档到具体使用还是有差距的,mark 一下中间踩过的坑

节点

LeanCloud 有三个节点:中国华北节点中国华东节点美国节点,用户可以选择三个节点中的一个部署应用,但问题关键是三个节点不互通。。所以这个就有点难受了。。幸好可以选择将同一个应用部署到三个节点上,起码不用重复写代码,但还是好麻烦呀 (:з」∠)

三个节点的网址也是不一样的:

节点选择

我们可以根据直接的需求选择相应节点来部署自己的服务,应该用的项目中需要访问 Google 的网址,所以只能选择美国节点了(逃

应用创建与部署

应用创建

用户可以轻松创建开发版的应用,唯一的限制就是每个月请求上限是 2000 次,一般来说足以满足个人日常的开发使用

应用创建

创建完成后即可进入相应应用界面:

开发版应用

应用部署

我们已经创建了一个应用,那么如何部署一个应用呢?这里推荐使用官方的命令行工具:lean-cli

WindowsLinux 可以选择在 Github releases 页面 下载相应安装包进行安装,而 Mac 则可以选择使用 Homebrew 进行安装:

brew update
brew install lean-cli

在安装完成之后,我们可以选择使用 lean 命令进行操作:

C:\Users\syang>lean
 _                        ______ _                 _
| |                      / _____) |               | |
| |      ____ ____ ____ | /     | | ___  _   _  _ | |
| |     / _  ) _  |  _ \| |     | |/ _ \| | | |/ || |
| |____( (/ ( ( | | | | | \_____| | |_| | |_| ( (_| |
|_______)____)_||_|_| |_|\______)_|\___/ \____|\____|
NAME:
   lean - Command line to manage and deploy LeanCloud apps

USAGE:
   lean [global options] command [command options] [arguments...]

VERSION:
   0.18.1

COMMANDS:
     login    登录 LeanCloud 账户
     metric   获取当前项目云存储的性能总览
     info     查看当前登录用户以及应用信息
     up       本地启动云引擎应用
     init     初始化云引擎项目
     switch   切换当前项目关联的 LeanCloud 应用
     deploy   部署云引擎项目到服务器
     publish  部署当前预备环境的代码至生产环境
     upload   上传文件到当前应用 File 表
     logs     查看 LeanEngine 产生的日志
     debug    不运行项目,直接启动云函数调试服务
     env      输出运行当前云引擎应用所需要的环境变量
     cache    LeanCache 管理相关功能
     cql      进入 CQL 交互查询
     search   根据关键词查询开发文档
     help, h  显示全部命令或者某个子命令的帮助

GLOBAL OPTIONS:
   --version, -v  print the version

可以看的 lean-cli 官方的说明其实是相当详细的

一般我们需要熟悉以下几个操作:logininitupswitchdeploy

login 操作会登录相应用户

[?] 请输入您的邮箱
 => email@example.com
[?] 请输入您的密码
 => ******
[INFO] 登录成功:
[INFO] 用户名: xxxxxx
[INFO] 邮箱: email@example.com

init 会在当前目录初始化应用并下载相应的模板代码

C:\Users\syang\Desktop\>lean init
[?] 请选择应用节点
 1) 美国节点
 2) 中国华北节点
 3) 中国华东节点
 => 2
[?] 请选择 APP
 1) AutoDraw
 => 1
[?] 请选择需要创建应用的编程语言
 1) Node.js
 2) Python
 3) Java
 4) PHP
 5) Others
 => 2
[?] 请选择需要创建的应用模版
 1) Flask
 2) Django
 => 2
[INFO] 下载模版文件 5.92 KiB / 5.92 KiB [===========================] 100.00% 0s
[INFO] 正在创建项目...
[INFO] 创建 Django 项目成功,更多关于 Django 的文档请参考官网: https://www.djangoproject.com/

上面说到了节点的问题,其实同一份代码是可以部署到不同节点上的,关键就是 switch 这个命令:

C:\Users\syang\Desktop\AutoDraw>lean switch
[?] 请选择应用节点
 1) 美国节点
 2) 中国华北节点
 3) 中国华东节点
 => 3
INFO] 获取应用列表 ...
[?] 请选择 APP
 1) AutoDraw
 => 1
切换应用至:AutoDraw ,分组:web

我们在刚刚创建的 AutoDraw 这个项目里使用了 switch 这个命令,并将应该在华北节点的程序切换到了华东节点上

lean up 命令用来调试相应程序,我们可以在本地端口 3000 和 3001 对应用进行测试:

[INFO] 当前命令行工具版本: 0.18.1
[INFO] 检测到 Python 运行时
[WARNING] 没有找到命令 `python2`,使用 `python` 代替
[INFO] 获取应用信息 ...
[INFO] 当前应用:AutoDraw (v0FzUWSFswfnQfGGQ08iILYS-9Nh9j0Va)
[INFO] 使用 [python wsgi.py] 启动项目
[INFO] 项目已启动,请使用浏览器访问:http://localhost:3000
[INFO] 云函数调试服务已启动,请使用浏览器访问:http://localhost:3001

lean deploy 用于将本地项目部署到 LeanCloud 平台上,类似效果如下:

✓ 获取应用信息
 ✓ 准备部署至目标应用:AwesomeApp (xxxxxx)
 ✓ 获取应用分组信息
 ✓ 准备部署应用到生产环境: web
 ✓ 检测到 Python 运行时
 ✓ 压缩项目文件
 ✓ 上传应用文件 6.41 KB / 6.41 KB [=======================================] 100.00% 0s
 ✓ 开始构建 20161021-171836
 ✓ 正在下载应用代码 ...
 ✓ 正在解压缩应用代码 ...
 ✓ 运行环境: python (leanengine/python-base-2.7)
 ✓ 从之前的构建中恢复依赖项 ...
 ✓ 正在下载和安装依赖项 ...
 ✓ 缓存最新的依赖项 ...
 ✓ 存储镜像到仓库 ...
 ✓ 镜像构建完成:20161021-171836
 ✓ 开始部署 20161021-171836 到 web1
 ✓ 正在创建新实例 ...
 ✓ 正在启动新实例 ...
 ✓ 实例启动成功:{"version": "1.6.5", "runtime": "cpython-2.7.6"}
 ✓ 正在统一切换新旧实例 ...
 ✓ 正在更新云函数信息 ...
 ✓ 部署完成:1 个实例部署成功
 ✓ 删除临时文件

对于命令行工具的使用在这里就简单进行介绍,详情可以参考 LeanCloud 的官方文档:命令行工具使用指南

应用开发

这才是重点 😊

云函数

LeanCloud 实现了一种云函数的功能,即你定义了云函数的函数名,然后把它具体实现,那么你就可以通过 SDK 的函数来调用你定义的云函数了

具体还是贴代码:

const AV = require('leanengine');
AV.Cloud.define('fetchUser', async (request) => {
    const { u_id } = request.params;
    let user;
    try {
        user = await findUser(u_id);
    } catch (err) {
        const UserModel = AV.Object.extend('UserModel');
        user = new UserModel();
        user.set('u_id', u_id);
        user.set('amount', 1000);
        user.set('rp_ids', []);
        user.set('sp_ids', []);
        user.set('rAmount', 0);
        user.set('rNum', 0);
        user.set('sAmount', 0);
        user.set('sNum', 0);
        await user.save();
    }
    return user;
});

我们可以通过调用 AV.Cloud.define() 函数的方式来定义我们的云函数,函数的第一个参数是云函数的名称,注意每个云函数的名称必须是唯一的,而函数的第二个参数是云引擎接收到对函数调用时的回调函数,回调函数的参数是一个复杂的对象,其中一个属性 params 即调用云函数的用户调用时发送的参数,以对象的形式给出,这意味着我们很容易就能用 {...}=request.params 解构出相应属性。当我们需要返回值时,LeanCloud 建议我们以 return 方式返回,旧的返回方式已经不做推荐了,那么就不去研究了(逃

LeanCloud 建议是以 Promise() 的链式调用来优化代码的,但当然还是要用 async () => {await...} 实现才是王道呀,其它的实现代码可读性真是极差

这里是调用者的代码,第一个参数是我们调用的函数名,第二个参数是相应参数对象,参数需要以键值对的方式给出。然后该函数会返回一个 Promise() 对象,然后就可以 .then(()=>{}) 编写熟悉的代码了

AV.Cloud.run('fetchUser', {u_id: u_id}).then((response)=>{
    let {rAmount, rNum, sAmount, sNum, rp_ids, sp_ids} = response;
    that.setData({
        rAmount: rAmount,
        rNum: rNum,
        sAmount: sAmount,
        sNum: sNum,
        rp_ids: rp_ids,
        sp_ids: sp_ids,
        userInfo:app.globalData.userInfo
    });
}

这里贴一下相应的网络请求:

network

数据存储

我们可以直接使用 LeanCloud 提供的数据存储服务,大致有一下几个步骤:

1. 声明一个对象类型,如果我们需要声明一个对象为 Todo 类型,那么 const Todo = AV.Object.extend('Todo');
2. 新建一个对象 const todo = new Todo();
3. 为对象新建属性 todo.set('title', 'Hello World');
4. 可以通过 save() 函数保存相应对象

与通常的 DB 相比,LeanCloud 提供的 LeanStorage 主要有以下几个差异:

  1. Schema Free/Not free 的差异;
  2. 数据接口上,LeanStorage 是面向对象的(数据操作接口都是基于 Object 的),开放的(所有移动端都可以直接访问),DB 是面向结构的,封闭的(一般在 Server 内部访问);
  3. 数据之间关联的方式,DB 是主键外键模型,LeanStorage 则有自己的关系模型(Pointer、Relation 等);

大致看来 LeanStorage 有点类似 MongoDB,类似分布式的文件存储式的数据库系统,所以有极高的拓展性

DB

LeanCloud 的增加、删除、更改、查询都有相应的 API 封装调用,需要的可以查询相应文档 数据存储开发指南 · JavaScript

这里贴上我的代码作为 demo:

const uQuery = new AV.Query('UserModel');
uQuery.equalTo('u_id', u_id);
const result = await uQuery.find();
if (result.length === 0) {
  throw new AV.Cloud.Error('No such user!');
}
return result[0];