3.4.2 函数的开放级别与类型

一、函数开放级别

我们在日常开发中通常会因为安全性,为方法定义不同的开放层级,或者通过应用分层把需要对web开放的接口统一定义在一个独立的应用中。oinone也提供类似的策略,所有逻辑都通过Function来归口统一管理,所以在Function是可以定义其开放级别有API、REMOTE、LOCAL三种类型,配置可多选。

四种自定义新增方式与开放级别的对应关系

函数 本地调用(LOCAL) 远程调用(REMOTE) 开放(API)
伴随模型新增函数 支持 支持【默认】 支持
独立新增函数绑定到模型 支持 支持【默认】 支持
独立新增函数只作公共逻辑单元 支持 支持【默认】
伴随ServerAction新增函数 必选

表3-4-2-1 四种自定义新增方式与开放级别的对应关系

远程调用(REMOTE)

如果函数的开放级别为本地调用,则不会发布远程服务和注册远程服务消费者

非数据管理器函数

提供者:如果函数定义在当前部署包的启动应用中,则主动发布远程服务提供者。

消费者:如果函数定义在部署依赖包中但未在当前部署包的启动应用中,则系统会默认注册远程消费者。发布注册的远程服务使用命名空间和函数编码进行路由。

所以非数据管理器函数的消费者并不需要感知该服务是否是本地提供还是远程提供。而服务提供者也不需要手动注册远程服务。

数据管理器类函数

提供者:如果数据管理器函数所在模型定义在当前部署包的启动应用中,则系统会主动发布数据管理器的远程服务作为数据管理器的远程服务提供者;

消费者:如果模型定义在部署依赖包中但未在当前部署包的启动应用中,则系统会主动注册数据管理器的远程服务消费者。

所以数据管理器类函数的消费者与服务提供者并不需要感知函数的远程调用。

二、函数类型

函数的类型语义分为:增、删、改、查,在编程模式下目前用于Function为API级别,生成GraphQL的Schema时放在query还是mutation。查放在query,其余放mutation。

三、函数分类

TBD

在无代码编辑器中,函数分类主要用函数选择的分类管理。

Oinone社区 作者:史, 昂原创文章,如若转载,请注明出处:https://doc.oinone.top/oio4/9244.html

访问Oinone官网:https://www.oinone.top获取数式Oinone低代码应用平台体验

Like (0)
史, 昂's avatar史, 昂数式管理员
Previous 2024年5月23日
Next 2024年5月23日

相关推荐

  • 4.2.7 框架之翻译工具

    一、说明 Oinone目前的默认文案是中文,如果需要使用其他语言,Oinone也提供一系列的翻译能力。 二、定义语言文件 在src/local下新增一个名为zh_cn.ts文件: 图4-2-7-1 语言文件 编辑zh_cn.ts文件,增加以下内容: const zhCN = { demo: { test: '这是测试' } } export default zhCN 图4-2-7-2 语言内容格式示意 在mian.ts注册语言资源: import { LanguageType, registryLanguage} from '@kunlun/dependencies'; import Zh_cn from './local/zh_cn' registryLanguage(LanguageType['zh-CN'], Zh_cn); 图4-2-7-3 注册语言 三、Vue模板使用 <template> <div class="petFormWrapper"> <form :model="formState" @finish="onFinish"> <a-form-item :label="translate('demo.test')" id="name" name="kind" :rules="[{ required: true, message: '请输入品种种类!', trigger: 'focus' }]"> <a-input v-model:value="formState.kind" @input="(e) => onNameChange(e, 'kind')" /> <span style="color: red">{{ getServiceError('kind') }}</span> </a-form-item> <a-form-item label="品种名" id="name" name="name" :rules="[{ required: true, message: '请输入品种名!', trigger: 'focus' }]"> <a-input v-model:value="formState.name" @input="(e) => onNameChange(e, 'name')" /> <span style="color: red">{{ getServiceError('name') }}</span> </a-form-item> </form> </div> </template> <script lang="ts"> import { defineComponent, reactive } from 'vue'; import { Form } from 'ant-design-vue'; export default defineComponent({ // 引入translate props: ['onChange', 'reloadData', 'serviceErrors', 'translate'], components: { Form }, setup(props) { const formState = reactive({ kind: '', name: '', }); const onFinish = () => { console.log(formState); }; const onNameChange = (event, name) => { props.onChange(name, event.target.value); }; const reloadData = async () => { await props.reloadData(); }; const getServiceError = (name: string) => { const error = props.serviceErrors.find(error => error.name === name);…

    2024年5月23日
    1.4K00
  • 2.4 Oinone的三大独特性

    Oinone在技术方面通过整合互联网架构和低代码技术,实现了三个独特的关键创新点(如图2-5所示): 独立模块化的个性化定制:每个需求都可以被视为一个独立的模块,从而实现个性化定制,提高软件生产效率。此外,这些独立模块也不会影响产品的迭代和升级,为客户带来无忧的体验。 灵活的部署方式:单体部署和分布式部署的灵活切换,为企业业务的发展提供了便利,同时适用于不同规模的公司,有助于有效地节约企业成本,提升创新效率,并让互联网技术更加亲民。 低代码和无代码的结合:低无一体为不同的IT组织和业务用户提供了有效的协同工作方式,能够快速部署安全、可扩展的应用程序和解决方案,帮助企业/组织更好地管理业务流程并不断优化。 图2-5 Oinone的三大独特性

    2024年5月23日
    1.8K00
  • 6.4 国际化之多语言

    多语言是国际化中大家最常面对的问题,我们需要对应用的页面结构元素进行翻译,也需要对系统内容进行翻译比如:菜单、数据字典等,甚至还会业务数据进行翻译。但不管什么翻译需求,我们在实现上基本可以归类为前端翻译和后端翻译。前端翻译顾名思义是在前端根据用户选择语言对内容进行翻译,反之就是后端翻译。本文会带着大家了解oinone的前端翻译与后端翻译 准备工作 pamirs-demo-boot的pom文件中引入pamirs-translate包依赖 <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-translate</artifactId> </dependency> pamirs-demo-boot的application-dev.yml文件中增加配置pamirs.boot.modules增加translate,即在启动模块中增加translate模块 pamirs: boot: modules: – translate 后端翻译(使用) 这里通过对菜单的翻译来带大家了解翻译模块 Step1 新增翻译记录 切换应用到translate模块,点击新增翻译。 选择新增翻译生效模块 选择翻译的模型为:菜单模型 源语言选择中文,目标选择English 添加翻译项目: 源术语为:商店 翻译值为:shop 状态为:激活 Step2 查看效果 应用切换到Demo模块,在右上角切换语言至英语 后端翻译(自定义模型的翻译) 在前面菜单的翻译中,似乎我们什么都没做就可以正常通过翻译模块完成多语言的切换了。是不是真如我们想象的一样,当然不是。是因为Menu模型的displayName字段加上@Field(translate = true)注解。 Step1 为PetType模型的name字段增加翻译注解 package pro.shushi.pamirs.demo.api.model; import pro.shushi.pamirs.meta.annotation.Field; import pro.shushi.pamirs.meta.annotation.Model; import pro.shushi.pamirs.meta.base.IdModel; @Model.MultiTable(typeField = "kind") @Model.model(PetType.MODEL_MODEL) @Model(displayName="品种",labelFields = {"name"}) public class PetType extends IdModel { public static final String MODEL_MODEL="demo.PetType"; @Field(displayName = "品种名" , translate = true) private String name; @Field(displayName = "宠物分类") private String kind; } Step2 重启应用查看效果 切换应用到translate模块,点击新增翻译 切换应用到Demo模块,切换中英文,查看效果 前端翻译 还记得我们前端第一个自定义动作吗?会弹出“oinone第一个自定义Action,啥也没干”,我们要对它进行翻译。 Step1 修改前端DoNothingActionWidget.ts import translateValueByKey 提示语用translateValueByKey加上翻译 const confirmRs = executeConfirm(translateValueByKey(\’oinone第一个自定义Action,啥也没干\’)||\’oinone第一个自定义Action,啥也没干\’); 前端更多翻译工具请见前端高级特性-框架之翻译工具 import { Action, ActionContextType, ActionWidget, executeConfirm, IClientAction, SPI, ViewType, Widget, translateValueByKey } from '@kunlun/dependencies'; @SPI.ClassFactory(ActionWidget.Token({ name: 'demo.doNothing' })) export class DoNothingActionWidget extends ActionWidget { @Widget.Method() public async clickAction() { const confirmRs = executeConfirm(translateValueByKey('oinone第一个自定义Action,啥也没干')||'oinone第一个自定义Action,啥也没干'); } } //定义动作元数据 Action.registerAction('*', { displayName: '啥也没干', name: 'demo.doNothing', id: 'demo.doNothing', contextType: ActionContextType.ContextFree, bindingType: [ViewType.Table] } as IClientAction); Step2 新增翻译记录 前端翻译的翻译记录对应的模型可以随意找一个放。但要注意几点: 不要找有字读配置translate = true的模型,因为会影响后端翻译性能。 最好统一到一个模型中,便于后续管理。这里大家可以自定义一个无有业务访问且本身无需要翻译的模型来挂载,避免性能损失 Step3 刷新远程资源生成前端语言文件 Step4 新增或修改.env 前端在项目根目录下新增或修改.env,可以参考.env.example文件。通过.env文件为前端配置oss文件路径,针对I18N_OSS_URL配置项。真实前端访问翻译语言文件的路径规则为:http://bucket.downloadUrl/mainDir/租户/translate/模块/语言文件。 yaml文件中oss配置的文件路径:http://pamirs.oss-cn-hangzhou.aliyuncs.com/upload/demo/ 租户/translate/模块/语言文件 前端会自动根据上下文组织 # 后端api配置 # API_BASE_URL=http://127.0.0.1:8090 # 下面是国际化语言的cdn配置,默认用当前请求链接下的路径: /pamirs/translate/${module}/i18n_${lang}.js I18N_OSS_URL=http://pamirs.oss-cn-hangzhou.aliyuncs.com/upload/demo Step5 重启前端应用看效果 对语言进行中英文切换,进入宠狗达人页面,点击【第一个自定义Action】,查看前端翻译效果

    2024年5月23日
    2.0K20
  • 4.1.21 框架之分布式消息

    消息中间件是在分布式开发中常见的一种技术手段,用于模块间的解耦、异步处理、数据最终一致等场景。 一、介绍 oinone对开源的RocketMQ进行了封装,是平台提供的一种较为简单的使用方式,并非是对RocketMQ进行的功能扩展。同时也伴随着两个非常至关重要的目的: 适配不同企业对RocketMQ的不同版本选择,不至于改上层业务代码。目前已经适配RocketMQ的开源版本和阿里云版本。 下个版本会对API进行升级支持不同类型MQ,以适配不同企业对MQ的不同要求,应对一些企业客户已经对MQ进行技术选择 对协议头进行扩展:如多租户的封装,saas模式中为了共用MQ基础资源,需要在消息头中加入必要租户信息。 二、使用准备 demo工程默认已经依赖消息,这里只是做介绍无需大家额外操作,大家可以用maven依赖树命令查看引用关系。 依赖包 增加对pamirs-connectors-event的依赖 <dependency> <groupId>pro.shushi.pamirs.framework</groupId> <artifactId>pamirs-connectors-event</artifactId> </dependency> 图4-1-21-1 分布式消息的依赖包 相关功能引入 增加模型、触发器都依赖MQ <!– 增强模型 –> <!– 增强模型 –> <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-channel</artifactId> </dependency> <!– 触发器 api –> <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-trigger-api</artifactId> </dependency> <!– 触发器 core –> <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-trigger-core</artifactId> </dependency> 图4-1-21-2 增加模型、触发器都依赖MQ yml配置文件参考 详见4.1.1【模块之yml文件结构详解】的“pamirs.event”部分。 三、使用说明 发送消息(NotifyProducer) 概述 NotifyProducer是Pamirs Event中所有生产者的基本API,它仅仅定义了消息发送的基本行为,例如生产者自身的属性,启动和停止,当前状态,以及消息发送方法。它本身并不决定消息如何发送,而是根据具体的实现确定其功能。 目前仅实现了RocketMQProducer,你可以使用下面介绍的方法轻松使用这些功能。 使用方法 Notify注解方式 使用示例 @Component public class DemoProducer { @Notify(topic = "test", tags = "model") public DemoModel sendModel() { return new DemoModel(); } @Notify(topic = "test", tags = "dto") public DemoDTO sendDTO() { return new DemoDTO(); } } 图4-1-21-3 Notify注解方式使用示例 解释说明 使用Component注解方式注册Spring Bean。 Notify注解指定topic和tags。 topic和tags对应NotifyEvent中的topic和tags。 RocketMQProducer方法调用 使用示例 @Component public class SendRocketMQMessage { @Autowired private RocketMQProducer rocketMQProducer; /** * 发送普通消息 */ public void sendNormalMessage() { rocketMQProducer.send(new NotifyEvent("test", "model", new DemoModel())); rocketMQProducer.send(new NotifyEvent("test", "dto", new DemoDTO())); } /** * 发送有序消息 */ public void sendOrderlyMessage() { DemoModel data = new DemoModel(); data.setAge(10); rocketMQProducer.send(new NotifyEvent("test", "model", data) .setQueueSelector((queueSize, event) -> { DemoModel body = (DemoModel) event.getBody(); return body.getAge() % queueSize; })); } /** * 发送事务消息 */ public void sendTransactionMessage() { rocketMQProducer.send(new NotifyEvent("test", "model", new DemoModel()) .setIsTransaction(true) .setGroup("demoTransactionListener")); } } 图4-1-21-4 RocketMQProducer方法调用…

    2024年5月23日
    1.2K00

Leave a Reply

Please Login to Comment