前言
文档
使用
- 函数调用注意要做异常捕获处理
目录介绍
clam脚手架是阿里商旅内部的,在创建项目的时候可以选择仅client还是client与service都支持的。 如果选择后者的话,创建后的项目,service目录如下
view目录中配置cdn链接,同时在client配置中设置 externals: {react: 'React','react-dom': 'ReactDOM'} 这样在打包的时候就不会把react打包到项目中,通过cdn的方式拉取。
view/index.ejs.ts 中配置
//注意 src为cdn的链接,需要注意版本号,版本号要小于package.json中的版本号
<script src="https://xxx/code/lib/react/18.2.0/umd/react.production.min.js"></script>
config配置文件
function文件夹下面,写一些入口处理,当发送过来一个http请求的时候,首先会在function中处理,
相当于MVC中的controller
service会做一些逻辑处理一般在function中的函数调用这里面的函数进行进一步处理。
model对数据进行增删改查操作, 一般是service中调用model中的操作。
简单的使用
1. 客户端发送一个http请求
使用js自带的fetch发送一个post请求
请求的url: http:/这里是域名/api/moduleName/getList?name=Jonh&age=30
const host = 'xxx'
const params = {
name: 'John',
age: 30
}
fetch(`${host}/api/moduleName/getList`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body:JSON.stringify(params)
}).then(response => response.json()).then(data => {
console.log('data',data)
}).catch(err => {
console.log(err)
})
以上的moduleName我使用具体的名字代替
我以用户模块为例 user
http:/这里是域名/api/user/getList?name=Jonh&age=30
2.控制器解析用户的输入,并返回数据
方法一:通过官网给出的@Controller注解方式处理
方法二: 根据请求方法名称,做统一的调用处理
import { Context as FaasContext } from "@midwayjs/faas";
import {
Inject,
Provide,
ServerlessTrigger,
ServerlessTriggerType,
Config,
} from "@midwayjs/decorator";
import { IUserService } from "@/interface/user";
@Provide()
export class UserHandler {
@Inject()
ctx!: FaasContext; //这里获取上下文 主要有url,params等信息 返回信息处理
@Inject()
userService!: IUserService;//service的实例,通过该对象调用service里面定义的函数处理
@Config("user")
userConfig;
//该 装饰器用于定义不同的触发器,它的参数为每个触发器信息,以及通用触发器参数
@ServerlessTrigger(ServerlessTriggerType.HTTP, {
path: "/api/user/*",
method: "post",
})
async userHandle() {
const data = this.ctx.request.body;
let res = {};
try {
//path='/api/user/getList' funcType的值为getList
const funcType = this.ctx.path?.split("/").reverse()[0] || "";
//如果我的service里面有定义getList这个函数 继续执行
if (typeof this.userService[funcType] === "function") {
//bind用来创建一个新的函数,并绑定指定的对象
//function.bind(thisArg, arg1, arg2, ...);
const _handler = this.userService[funcType].bind(this, data);
//这里其实是调用service层的方法
res = await _handler();
} else {
res = {
data: null,
success: false,
msg: "",
code: "fail",
};
}
} catch (err) {
this.ctx.logger.error(`user api ${this.ctx.path} error`, err);
res = {
data: null,
success: false,
msg: err,
code: "fail",
};
}
this.ctx.body = {
status: 200,
success: true,
data: res,
};
}
}
config/config.daily.ts
通过 @Config("user")注解就可以获取到配置
export default{
user:{
appName:"app's name",
accessKey:'这里随便写各种属性和属性值'
}
}
说明
@Provide 装饰器的作用:
- 1、这个 Class,被依赖注入容器托管,会自动被实例化(new)
- 2、这个 Class,可以被其他在容器中的 Class 注入
而对应的 @Inject 装饰器,作用为:
- 1、在依赖注入容器中,找到对应的属性名,并赋值为对应的实例化对象
@Inject的类中,必须有对应的@Provide才会生效。成对出现的。
3.service服务层 业务逻辑处理层
interface/user.ts
export interface IUserService{
getList():Promise<any>
}
service/user.ts
方式一:这一层调用后端服务获取到返回值后做一些简单处理,返回给客户端的页面使用
import { Context as FaasContext } from "@midwayjs/faas";
import { Inject, Provide, Config } from "@midwayjs/decorator";
import { IUserService } from "@/interface/acl";
@Provide()
export class UserService implements IUserService{
@Inject()
ctx!: FaasContext & { user?: any; hsfClient?: any };
@Config("user")
userConfig;
/**
* 通过name获取该应用下所有用户
* @param {number} userId
* @param {Array<string>} roleNames
* @return {*} {Promise<UserResult[]>}
* @memberof UserService
*/
async getList(data): Promise<any[]> {
const { name } = data;
const res: any = await this.ctx.hsfClient.invoke({
id: "com.xxx.UserService:2.0.0",
method: "findUserByName",
group: "HSF",
args: [
{
searchName: name,
class: "com.xxx.FindListByNameParam",
},
],
parameterTypes: [
"com.xxx.FindListByNameParam",
],
});
if (res.success) {
const { result = [] } = res;
return result;
}
throw new Error(res.msg);
}
//另外的service方法,假设在这里调用这个类的其他函数,可以controller中的实力化的 userService对象调用
async getAllAppUser(data): Promise<any[]>{
try{
//这里就是调用上面的函数
//@ts-ignore
const res = await this.userService.getList()
}catch(err){
this.ctx.body = {
success: false,
data: "xxx",
};
return;
}
}
}
方法二:这一层调用dao层定义的增删改查操作 不调用后端的服务
sequelize 是基于nodejs的ORM
ORM(Object-Relational Mapping,对象关系映射)是一种技术,用于将面向对象的程序中的对象与关系型数据库中的表进行映射。它提供了一种将对象模型与数据库模型进行交互的方式,使开发人员可以使用面向对象的编程语言来操作数据库,而无需直接编写SQL语句。
ORM框架通常提供以下功能:
- 对象映射:ORM框架将数据库表映射为对象,表的列映射为对象的属性。这样,开发人员可以使用面向对象的方式来操作数据库,而无需关注底层的SQL语句。
- 数据库操作:ORM框架提供了一组API和方法,用于执行数据库操作,如插入、更新、删除和查询数据。开发人员可以使用这些方法来操作对象,ORM框架会自动将操作转换为对应的SQL语句。
- 关系管理:ORM框架能够处理对象之间的关系,如一对一、一对多、多对多等关系。它可以自动处理关系的建立、更新和删除,简化了数据库关系的管理。
- 数据库迁移:ORM框架通常提供数据库迁移工具,可以根据定义的对象模型自动生成数据库表结构,以及在模型变更时对数据库进行更新。
常见的ORM框架包括Java的Hibernate、Python的Django ORM、Ruby的Active Record、Node.js的Sequelize等。它们提供了强大的功能和易于使用的API,简化了开发人员与数据库之间的交互。
使用ORM框架可以提高开发效率,减少编写SQL的工作量,并使代码更具可维护性和可扩展性。然而,ORM框架也有一些限制,例如性能问题、复杂查询的处理等。在选择和使用ORM框架时,需要根据具体应用的需求和性能要求进行评估和选择。
在sevice层中调用还是使用this.model对象.findAndCountAll 等等其他的操作