首页 > 其他分享 >优维低代码:定制 Providers

优维低代码:定制 Providers

时间:2023-04-03 17:37:22浏览次数:41  
标签:core http Providers import next provider 优维低 定制 brick

优维低代码:定制 Providers_低代码

优维低代码:定制 Providers_低代码_02

优维低代码技术专栏,是一个全新的、技术为主的专栏,由优维技术委员会成员执笔,基于优维7年低代码技术研发及运维成果,主要介绍低代码相关的技术原理及架构逻辑,目的是给广大运维人提供一个技术交流与学习的平台。


连载第四十三期

《现场定制:定制Providers

# 何为 provider ?

provider 也是一种构件,设计的原意是为了封装后台接口,提供统一的前端 SDK 。在介绍 provider 之前,要先介绍下优维科技在 2019 年开始推行的“契约为中心”的开发模式。

在 2019 年前,优维科技的后台主流开发语言为 python 和 php ,前端则为 JavaScript。因为这弎都是弱类型,开发者一不注意,接口的输入和输出就会出现了大量的 map。随着系统的不断膨胀,在接口对接过程中,总是会出现各种字段不一致的情况,特别是在重构的时候,就更加是“动态类型一时爽,代码重构火葬场”。因此,2019 年,整个优维技术研发部开始推行以“契约为中心”的开发模式,后台主流开发语言切到了 go,前端开发语言也切到了 TypeScript。

优维低代码:定制 Providers_低代码技术_03

在开发一个接口的时候,都要先定义契约(点击查看 接口契约介绍 ),然后再基于该契约直接生成前端的 SDK(provider)和后端的框架代码及后端的 SDK(go,python)及 API 文档。这样,前后台都强制遵循契约精神,保证各方统一。

定制化 provider

我们推行前端尽量少写处理逻辑,当前我们绝大部分 provider 都是自动生成的(点击查看内置 provider 文档),不需要写任何一行代码就可以将展示构件与后台接口对接起来。但,不可否认的,在某些特殊场景还是需要写些处理逻辑,另外,如果有第三方 API 数据接入的时候,也需要写定制 provider。

yarn yo脚手架封装了 provider 的生成。参考如下,按提示执行:

➜  brick-next git:(master) ✗ yarn yo
yarn run v1.12.3
$ brick-scripts
? What do you want? a new custom provider brick
? which package do you want to put the new brick in? search
? What's the name of your new brick (in lower-kebab-case)? provider-demo-provider
File created: ./bricks/search/src/data-providers/DemoProvider.spec.ts
File created: ./bricks/search/src/data-providers/DemoProvider.ts
File updated: ./bricks/search/src/index.ts


No worries!
✨  Done in 53.99s.

示例

# 封装第三方 API 接口请求

import { createProviderClass } from "@next-core/brick-utils";
import { http } from "@next-core/brick-http";


export interface TestParams {
  a: string;
  b: string;
}


export async function Test(
  params: TestParams
): Promise<any> {
  return http.put(
    "http://localhost:8080/test",
    params
  );
}


customElements.define(
  "demo.provider-test",
  createProviderClass(Test)
);

注意:请检查项目一级 package.json 的 devDependencies 有没声明@next-core/brick-http 的依赖,如果没有,请加入:

  • "@next-core/brick-http": "^1.0.0",
  • "@next-core/brick-dll": "^1.0.61",

第三方接口接入优维的 api_gateway

如上示例直接请求后端接口
http://localhost:8080/test 会有几个问题:

  1. 跨域的问题
  2. 安全的问题

建议统一接入到优维的 api_gateway 来转发,具体配置方式见第三方接口接入。由此,这里需要改为:

import { createProviderClass } from "@next-core/brick-utils";
import { http } from "@next-core/brick-http";


export interface TestParams {
  a: string;
  b: string;
}


export async function Test(
  params: TestParams
): Promise<any> {
  return http.put(
    // 注意不要写成全路径/api,而应该写成 api
    "api/gateway/your-api-prefix/test",
    params
  );
}


customElements.define(
  "demo.provider-test",
  createProviderClass(Test)
);

# 纯逻辑处理的 provider

index.ts

import { createProviderClass } from "@next-core/brick-utils";


import { listBrickStory, categoryList } from "./processor";


customElements.define(
  "developers.providers-of-brick-story",
  createProviderClass(listBrickStory)
);


customElements.define(
  "developers.get-category-list",
  createProviderClass(categoryList)
);

processor.ts

import i18next from "i18next";
import { MenuIcon } from "@next-core/brick-types";
import { atomBook } from "../stories/chapters/atom-bricks";
import { businessBook } from "../stories/chapters/business-bricks";
import { Story, Chapter, I18nString } from "../stories/interfaces";


export const categoryList = (storyType: string): Promise<string[]> => {
  let books: Chapter[] = [];
  if (storyType === "atom") {
    books = atomBook;
  } else if (storyType === "business") {
    books = businessBook;
  }
  const lang = i18next.language
    ? (i18next.language.split("-")[0] as keyof I18nString)
    : "zh";
  const categoryList = books.map((book: Chapter) => {
    return book.title[lang];
  });
  return Promise.resolve(categoryList);
};


// 省略 listBrickStory 函数

# 基于已有 SDK 修改

import { createProviderClass } from "@next-core/brick-utils";
import { HttpOptions } from "@next-core/brick-http";
import { InstanceTreeApi } from "@sdk/cmdb-sdk";
import { AntTreeNodeProps } from "antd/lib/tree";
import { MenuIcon } from "@next-core/brick-types";
import { CustomIconComponentProps } from "antd/lib/icon";


import { Instance } from "../../interfaces";


interface Business extends Instance {
  _businesses_APP?: Instance[];
  _sub_system?: Business[];
}


type TreeIcon = MenuIcon | React.ComponentType<CustomIconComponentProps>;


export interface BrickTreeNodeProps extends AntTreeNodeProps {
  title?: string;
  icon?: TreeIcon;
  children?: BrickTreeNodeProps[];
}


function convertBusinessesToTreeNodes(businesses: Business[]) {
  const treeNodes: BrickTreeNodeProps[] = [];


  businesses.forEach((business) => {
    let children: BrickTreeNodeProps[] = [];


    if (business._sub_system) {
      children = children.concat(
        convertBusinessesToTreeNodes(business._sub_system)
      );
    }


    business._businesses_APP &&
      business._businesses_APP.forEach((app) => {
        children.push({
          title: app.name,
          key: app.instanceId,
          icon: { lib: "fa", icon: "cube" },
        });
      });


    if (children.length > 0) {
      treeNodes.push({
        title: business.name,
        key: `_${business.instanceId}`,
        icon: { lib: "fa", icon: "briefcase" },
        selectable: false,
        children,
      });
    }
  });


  return treeNodes;
}


async function getBusinessAppTree(options?: HttpOptions) {
  const data: {
    BUSINESS?: Business[];
    APP?: Instance[];
  } = await InstanceTreeApi.instanceTree(
    {
      tree: {
        object_id: "BUSINESS",
        fields: { name: true },
        child: [
          { relation_field_id: "_sub_system", fields: { name: true } },
          { relation_field_id: "_businesses_APP", fields: { name: true } },
        ],
      },
    },
    options
  );
  let treeNodes: BrickTreeNodeProps[] = [];


  if (data.BUSINESS) {
    treeNodes = treeNodes.concat(convertBusinessesToTreeNodes(data.BUSINESS));
  }


  data.APP &&
    data.APP.forEach((app) => {
      treeNodes.push({
        title: app.name,
        key: app.instanceId,
        icon: { lib: "fa", icon: "cube" },
      });
    });


  return treeNodes;
}


customElements.define(
  "app-deploy-statistics.provider-business-app-tree",
  createProviderClass(getBusinessAppTree)
);

# 使用方式

点击查看[构件事件传递](
/next-docs/docs/micro-app/brick-event#调用 provider)

标签:core,http,Providers,import,next,provider,优维低,定制,brick
From: https://blog.51cto.com/u_15605878/6166911

相关文章

  • 全栈声明式可观测:KubeVela 开箱即用且灵活定制的云原生应用洞察
    作者介绍:殷达,KubeVelaMaintainer,阿里云高级工程师,深度参与了KubeVela混合云多集群管理、可扩展工作流、可观测等核心能力体系的建设KubeVela[1]是一个开箱即用的现代化应用交付与管理平台,它通过统一的应用模型、可编程可扩展的架构,帮助企业构建统一的平台,向上为不同场景......
  • 两种方式自定制基于JWT的认证类BaseAuthentication和BaseJSONWebTokenAuthentication
    1.基于BaseAuthentication的自定义方法  2.views中调用自定义方法MyJwtAuthentication验证  3.基于BaseAuthentication的自定义方法测试:token过期  4.基于BaseAuthentication的自定义方法测试:token数据有错误,需检查token正确性  5.基于BaseAuthenticati......
  • 中小微企业免费实施,30人以下免费使用一年,数据免费迁移,按需定制
    题目:中小微企业免费实施,30人以下免费使用一年,数据免费迁移,按需定制正文:您是一位中小微企业的管理者吗?您在寻找一款高效的ERP系统来管理您的业务,但是担心高昂的实施和使用费用?现在,我们向您介绍一款适合您的ERP系统——我们的ERP系统。我们为您提供免费的实施服务,无需支付任何费......
  • 免费实施、后付费,享受免费试用和定制服务
    广告方案:免费实施、后付费,享受免费试用和定制服务正文:ERP系统可以提高企业运营效率,帮助企业更好地管理资源和流程,实现高效盈利。但很多企业因为ERP系统的高昂价格而望而却步,错失了这个提升竞争力的机会。现在,我们推出免费实施、后付费的优惠方案,让更多的企业可以轻松拥有优秀的......
  • 使用JWT自定制认证类
    1.创建auth写MyToken类  2.view中接口导入引用MyToken  3.测试自定义认证类_失败测试  4.测试自定义认证类_成功测试  5.打印用户信息  6.自定义Mytoken类_2  7.可以单独打印某项用户信息  8.可以单独打印某项用户信息_获取名称  ......
  • 练习——简单的定制排序
    packagecom.arrays_;importjava.util.Arrays;importjava.util.Comparator;publicclassArraysSortCustom{publicstaticvoidmain(String[]args){int[]arr={1,-2,0,2,32};bubble01(arr);System.out.println("排序结果&quo......
  • 陪诊小程序开发|医疗陪诊小程序|陪诊小程序定制
    信息的快速发展,人们越来越忙碌,信息的发达,所有的都智能化,代替人工,为我们提供更加便捷的生活,而另一方面也给一些老人家带来困扰。陪诊小程序的出现让陪诊工作人员一方面可以帮......
  • APP定制开发标准是什么?如何判断一款APP符合开发需求?
    如何判断一款APP开发的质量呢,判断标准又是怎样的呢?一、功用是否都已实现用户需求是不是都已在软件功能上进行意义匹配,是软件定制开发衡量的第一条标准。公司软件需求管理......
  • ES定制化排序的骚操作
    一.通过邻尽查询提升相关度1.配合使用match_query和match_phrease2.match_phrease匹配条件比match_query复杂二.直接通过排序存在哪些问题1.将权重转化为排序的先后顺......
  • 广州APP定制开发要把握的阶段,帮你成功开发
     一些人虽然有意广州APP定制开发,但是他们在和开发商合作的时候经常会出现一些问题,导致开发失败。为此我们在开发过程中要把握一些阶段,今天名锐讯动为大家介绍广州APP定制......