4.1.12 • Published 1 year ago

@zhr6525/hsm-mw v4.1.12

Weekly downloads
-
License
ISC
Repository
-
Last release
1 year ago

moleculer SDK

背景

  1. 使用 SDK 接入中间件,通过 SDK 请求接口
  2. 基于 prisma 和 graphql,创建 moleculer 服务,可被 moleculer 的 apollo-server 网关发现并调用

依赖

  • node:16.x 以上
  • moleculer:^0.14.29
  • graphql: ^16.6.0"
  • @graphql-tools/graphql-file-loader: ^7.5.17"
  • @graphql-tools/load: ^7.8.14"
  • nanoid: 3
  • moment: ^2.29.4
  • nats: "^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 配置可参考官方文档


更新记录

changeLog