@zhr6525/hsm-mw
v4.1.12
Published
提供SDK接入中间件
Downloads
12
Readme
moleculer SDK
背景
- 使用 SDK 接入中间件,通过 SDK 请求接口
- 基于 prisma 和 graphql,创建 moleculer 服务,可被 moleculer 的 apollo-server 网关发现并调用
依赖
node
:16.x 以上moleculer
:^0.14.29graphql
: ^16.6.0"@graphql-tools/graphql-file-loader
: ^7.5.17"@graphql-tools/load
: ^7.8.14"nanoid
: 3moment
: ^2.29.4nats
: "^2.13.1"
安装
设置镜像源
npm set registry=http://172.21.44.57:4873/
安装
npm i @hsmos/mw-microservice
接口
interface ServiceSearchObj {
name: string;
version?: string | number;
}
interface Action {
[actionName: string]: {
rest?: { method: string; path: string };
graphql?: {
[action: string]: string;
};
handler(ctx: any): any;
};
}
interface prismaService {
// .graphql文件路径
gqlPath: string;
// 服务名
name: string;
// 描述
description?: string;
// 同创建ApolloServer的schema
schema: any;
// prismaClient
prisma: object;
// 隔离域
domain?: string;
// 动作
actions?: Action;
// 白名单
whiteList?: string[];
// 受控接口名单
controlList?: string[];
// 允许缓存接口名单
cacheList?:string[];
// 事件
events?: {
[key: string]: any;
};
}
interface whiteList {
apiUrl: string; // 接口名,即action名
method: string; // POST、GET、query、mutation等,rest类型的必须大写,gql类型的必须小写
}
enum ApiTypeEnum {
GRAPHQL = "graphql",
RESTFUL = "restful",
WEBSOCKET = "websocket",
}
interface controlInfo {
apiType: ApiTypeEnum; // 接口类型
method: string; // POST、GET、query、mutation等,rest类型的必须大写,gql类型的必须小写
code: string; // 服务名.接口名.method
apiUrl: string; // 接口名,即action名
}
/**
* @description 启动中间件
* @returns
*/
async start()
/**
* @description 停止中间件
* @returns
*/
async stop()
/**
* @description 内部调用
* @param serviceName 服务名,必填
* @param actionName 接口名,必填
* @param params 参数,非必填
* @param meta 元数据,非必填
* @returns
*/
async call(serviceName: string, actionName: string, params: object, meta: object)
/**
* @description 基于prisma创建gql服务
* @param service prisma服务
* @callback cb schema合并失败时触发
* @returns
**/
async createGqlService(service: prismaService,, cb: (error: any) => void)
/**
* @description 创建服务
* @param service 服务对象
* @param whiteList 白名单
* @param controlList 受控接口名单
* @returns
*/
async createService(service: any, whiteList: whiteList[] = [], controlList: controlInfo[] = [], cacheList: string[] = [])
/**
* @description 等待服务连接
* @param serviceNames 服务名
* @param timeout 超时时间
* @param interval 查询间隔
* @returns
*/
async waitForServices(
serviceNames: string | string[] | ServiceSearchObj[],
timeout: number,
interval?: number
)
/**
* 发布消息
* @param topic 主题名
* @param message 消息体
* @param isbroad 是否广播
* @param persistent 是否持久化
*/
async publish(
topic: string,
message: object,
isbroad: boolean = true,
ack: boolean = false
)
/**
* 可用主题列表
* @returns
*/
async topicLists()
/**
* 动态创建消费着及处理逻辑
* @param event 消费逻辑配置
* @param persistent 是否持久化
* @returns
*/
async createEvent(event: event)
配置说明
可配置项如下,未列出配置项配置不生效: | 名称 | 类型 | 说明 | |-----------|------- |------------| |Logger|Bool|是否打印日志| |logLevel|String|日志等级| |doamin|String|模块,非必填| |name|String|节点名称,需唯一,非必填| |middlewares|Array|moleculer 中间件| |logConfig|Object|winston-daily-rotate-file 日志配置|
示例
仅接入中间件
import MW from "@hsmos/mw-microservice";
// config:自定义moleculer配置,非必须
let config = {
logger: true, // 打印日志
logLevel: "info", // 建议与服务保持一致
domain: "model", // 模块名,非必填,不填时以创建时间填充
name: "infoModel-1", // 节点名,需唯一,非必填,不填时以三个随机数填充
logConfig: {
// winston-daily-rotate-file日志配置,打印日志时才生效
dirname: __dirname,
filename: `%DATE%.log`,
datePattern: "YYYY-MM-DD",
maxSize: "10m",
maxFiles: "10",
},
};
const mwServer = new MW(config);
mwServer.start().catch((err) => {
console.error(err);
});
需要创建 gql 服务
import MW from "@hsmos/mw-microservice";
// config:自定义moleculer配置
let config = {
namespace: "hsm-os-dev", // 开发环境namespace
};
const mwServer = new MW(config);
mwServer
.createGqlService(
{
gqlPath: path.join(__dirname, "../schema.graphql"),
name: "test",
schema,
prisma,
},
(error: string) => {
// error为错误原因
console.log(error);
// 合并schema失败,根据需求自行处理
throw CustomError.of(CommonError.InternalServerError, {
message: "注册中间件失败:schema冲突",
});
},
)
.then(() => mwServer.start())
.catch((err) => {
console.error(err);
});
// 内部调用
mwServer.call("mw", "nodes", {}).then((res) => {
// interface error {
// message: string; // 异常信息的描述信息,必填
// code: number; // 异常信息的状态码,必填
// name?: string; // 异常信息的名称,非必填,默认为code的值
// extensions?: any; // 异常信息扩展数据,非必填,可以是任意类型。例如:上下文信息、分页信息等
// timestamp?: Date; // 异常信息的时间,非必填. 如:2021-08-05T07:25:25.000Z
// }
// interface result {
// code: number; // 异常信息的状态码,必填
// data?: any // call返回的结果
// message?: string; // 异常信息的描述信息,非必填
// errors?: error[]; // 兼容多异常信息同时返回,非必填
// }
if (res.code) {
console.error(res.message);
}
});
内部调用
// 内部调用
// 请求参数需要根据请求类型,将其放入body或query,非必填,无参数可传空对象
mwServer.call("mw", "nodes", { body: {}, query: {} }, { req: { headers: {} } }).then((res) => {
// interface error {
// message: string; // 异常信息的描述信息,必填
// code: number; // 异常信息的状态码,必填
// name?: string; // 异常信息的名称,非必填,默认为code的值
// extensions?: any; // 异常信息扩展数据,非必填,可以是任意类型。例如:上下文信息、分页信息等
// timestamp?: Date; // 异常信息的时间,非必填. 如:2021-08-05T07:25:25.000Z
// }
// interface result {
// code: number; // 异常信息的状态码,必填
// data?: any // call返回的结果
// message?: string; // 异常信息的描述信息,非必填
// errors?: error[]; // 兼容多异常信息同时返回,非必填
// }
if (res.code) {
console.error(res.message);
}
});
// 订阅事件格式 channels: { "topicName"(payload: any) { // do you handle console.log(payload); } }
具体 moleculer 配置可参考官方文档