我们在上一部分讲述了sword是如何托管我们的unicloud的应用, 想必大家也已经学会了使用sfu去开发unicloud啦, 那么这一章就让我这个unicloud小白, 和大家一起开发一个简单的功能吧~
初始化一个项目
如果你全局安装了我们的脚手架之后, 在你熟悉的文件夹下, 跑一下我们熟悉的init命令, 它会帮助我们生成一个模板
sword init
我们可以看到, 默认的模板中有一个hello world的例子, 它的目录结构是这样的:
配置unicloud的link属性
我们可以运行程序, 但是在运行程序之前, 我们需要在sword.config.ts的配置项中, 配置unicloud的link属性, 指定我们的云函数目录, 帮助程序把产物编译到指定目录
那么如何能获取一个文件夹的完整路径呢? 在windows中, 我们可以这样做:
而在macos中, 最简单的办法就是打开我们电脑的任意一个终端, 把云函数的文件夹拖进去, 就可以获取到完整路径了
在我们的配置文件中, 把link配置一下就可以啦!
import type { Config } from '@swordjs/sword-framework-cli';const config: Config = {unicloud: {link: '/Users/seho/Documents/HBuilderProjects/sword-unicloud-faas/uniCloud-aliyun/cloudfunctions/test'}};export default config;
然后你就可以运行我们的unicloud项目了
npm run dev:unicloud
创建业务文件夹

我们可以使用便捷操作符来快捷创建api, 这个概念在实现API就已经说明了, 如图我们创建了4个api, 分别是增删改查
创建表
我们创建一个表schema.json
// 文档教程: https://uniapp.dcloud.net.cn/uniCloud/schema{"bsonType": "object","required": [],"permission": {"read": false,"create": false,"update": false,"delete": false},"properties": {"_id": {"description": "ID,系统自动生成"},"name": {"description": "名字"}}}
并且上传, 我们接下来的demo, 将会用到这个list这个表
编写add函数
已知我们的表是需要name字段的, 所以我们的params需要指定name为字符串类型
export interface ReqParams {name: string;}export interface ReqQuery {}export interface Res {success: boolean;}
我们简单实现一下add逻辑, 这并没有做容错处理, 我们在实际开发中, 是需要考虑边界条件的, 但是由于sword, 我们不需要考虑参数带来的边界问题, 因为你获取参数始终是安全的
import { useApi, Post } from '@swordjs/sword-framework';import { ReqQuery, ReqParams, Res } from './proto';export const main = useApi<{query: ReqQuery;params: ReqParams;res: Promise<Res>;}>({instruct: [Post()],handler: async (ctx) => {const db = uniCloud.database();const collection = db.collection('list');const result = await collection.add({name: ctx.params.name});return {success: true};}});
接着我们测试一下, 在云函数的测试json中, 编写下面的对象, 然后本地运行云函数
{"route": "/api/add","method": "POST","query": {},"params": {"name": "seho"}}

之后, 我们可以在控制台看到, 这个函数已经被成功执行了, 并且我们的数据库已经插入了一条记录
编写delete函数
我们需要传递一个id, 然后通过id删除一条记录, 所以我们的proto的params是id, 同样也是字符串类型
export interface ReqParams {id: string;}export interface ReqQuery {}export interface Res {success: boolean;}
import { useApi, Delete } from '@swordjs/sword-framework';import { ReqQuery, ReqParams, Res } from './proto';export const main = useApi<{query: ReqQuery;params: ReqParams;res: Promise<Res>;}>({instruct: [Delete()],handler: async (ctx) => {const db = uniCloud.database();const collection = db.collection('list');await collection.doc(ctx.params.id).remove();return {success: true};}});
本地运行函数也成功删除了我们的一条记录
{"route": "/api/delete","method": "DELETE","query": {},"params": {"id": "629f046a257bc80001c6c3e0"}}
编写update函数
我们不仅需要传递id, 还需要传递修改后的name, 所以我们的proto需要这么设计
export interface ReqParams {name: string;id: string;}export interface ReqQuery {}export interface Res {success: boolean;}
import { useApi, Put } from '@swordjs/sword-framework';import { ReqQuery, ReqParams, Res } from './proto';export const main = useApi<{query: ReqQuery;params: ReqParams;res: Promise<Res>;}>({instruct: [Put()],handler: async (ctx) => {const db = uniCloud.database();const collection = db.collection('list');await collection.doc(ctx.params.id).update({name: ctx.params.name});return {success: true};}});
运行本地云函数
{"route": "/api/update","method": "PUT","query": {},"params": {"id": "629f04bfc2cedc0001308c1b","name": "吴彦祖"}}
编写list函数
在list函数中我们要实现返回一个列表, 我们需要前端传递limit, 然后这个函数不再发挥boolean, 而是一个对象数组
export interface ReqParams {}export interface ReqQuery {limit: number;}export type Res = {// unicloud数据库返回的id是有下划线的_id: string;name: string;}[];
import { useApi } from '@swordjs/sword-framework';import { ReqQuery, ReqParams, Res } from './proto';export const main = useApi<{query: ReqQuery;params: ReqParams;res: Promise<Res>;}>({handler: async (ctx) => {const db = uniCloud.database();const collection = db.collection('list');const result = await collection.limit(ctx.query.limit).get();return result.data as Res;}});
由于unicloud的type是官方工具生成的, 所有很多api都没有泛型支持, 我们这里直接as成Res保证程序不报错就可以了
{"route": "/api/list","method": "GET","query": {"limit": 1},"params": {}}
部署上线
npm run build:unicloud

这个时候, 你会发现我们的代码已经被编译好了, 放到了云函数的根目录中
接下来, 我们就尝试一下, 上传并且运行, 它会在云端执行我们的函数
可以看见, 我们的云函数已经成功运行啦😄
