Apinto 网关进阶教程,插件开发入门指南

Apinto 是基于Go语言,由 Eolink 自主研发的一款高性能、可扩展、易维护的云原生 API 网关。Apinto 能够帮助用户简单、快速、低成本、低风险地实现:系统微服务化、系统集成、向合作伙伴、开发者开放功能和数据。

通过 Apinto,企业能够专注于自身业务的发展,并且让企业间能互相借力,实现共赢。

借助 Apinto 强大的插件拓展能力,用户可像乐高积木一样根据需要自行拓展Apinto 的插件,丰富 Apinto 的能力。

本篇文章将给大家介绍如何开发 Apinto插件,自行拓展 Apinto 网关能力

前置知识

插件执行流程

插件系统定义了 Access 、Proxy 两个插件执行周期,其执行阶段定义如下:

  • Access:客户端请求 Apinto,将请求转发给上游服务前执行;
  • Proxy:将响应返回给客户端前执行;

请求从客户端发出,到达路由进行转发前,按顺序从上到下进行每个插件的 Access 执行阶段,转发获取响应后,从下到上执行每个插件的 Proxy 执行阶段。

插件执行流程如下图,请求处理即为转发前执行的操作,响应处理即为转发获得响应后的操作。

 

插件实现 UML 图

插件实现采用工厂设计模式,系统初始化时,自动将插件工厂注册到插件管理器中,当有新增插件/修改插件需求时,插件工厂实例会创建插件执行器实例。

开发插件

为了更加直观介绍自定义开发插件,本文将以开发 响应重写 插件为例,完整代码可参考 [Apinto 项目响应插件]

定义插件配置

开发插件前,先确定插件的功能和界限,根据需求定义插件配置格式,此处以 响应重写 插件为例。


{"status_code":0,"body":"","body_base64":true,"headers":{},"match":{"code":[]}
}

根据上述配置,定义插件配置结构体。


type Config struct {StatusCode int               `json:"status_code" label:"响应状态码" minimum:"100" description:"最小值:100"`Body       string            `json:"body" label:"响应内容"`BodyBase64 bool              `json:"body_base64" label:"是否base64加密"`Headers    map[string]string `json:"headers" label:"响应头部"`Match      *MatchConf        `json:"match" label:"匹配状态码列表"`
}type MatchConf struct {Code []int `json:"code" label:"状态码" minimum:"100" description:"最小值:100"`
}

实现插件执行器

1. 定义执行器结构


type ResponseRewrite struct {drivers.WorkerBasestatusCode intbody       stringheaders    map[string]stringmatch      *MatchConf
}

2. 实现 eosc.IWorker 接口


type IWorker interface {Id() stringStart() errorReset(conf interface{}, workers map[RequireId]IWorker) errorStop() errorCheckSkill(skill string) bool
}

当插件配置被修改时,将会调用 Reset 方法,重置执行器内置数据,当插件被删除时,将会调用 Stop 方法。

3. 实现 eosc.IFilter 接口


type IFilter interface {DoFilter(ctx EoContext, next IChain) (err error)Destroy()
}

该接口在转发流程中被调用,其中 DoFilter 方法执行插件主流程,Destory 方法则在插件被删除时,销毁实例。

由于插件有顺序,在实际调用时,会将插件编排成调用链,并通过 next.DoChain(ctx) 操作调用下一个插件,您可以自定义调用插件前的操作,即 Access阶段 ,也可以自定义调用插件后的操作,即 Proxy 阶段 。代码示例如下:


func (r *ResponseRewrite) DoFilter(ctx eocontext.EoContext, next eocontext.IChain) (err error) {return http_service.DoHttpFilter(r, ctx, next)
}func (r *ResponseRewrite) DoHttpFilter(ctx http_service.IHttpContext, next eocontext.IChain) error {if next != nil {err := next.DoChain(ctx)if err != nil {log.Error(err)}}return r.rewrite(ctx)
}func (r *ResponseRewrite) Destroy() {r.statusCode = 0r.body = ""r.headers = nilr.match = nil
}

定义工厂创建方法


func NewFactory() eosc.IExtenderDriverFactory {return drivers.NewFactory[Config](Create, Check)
}func Create(id, name string, conf *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) {err := conf.doCheck()if err != nil {return nil, err}//若body非空且需要base64转码if conf.Body != "" && conf.BodyBase64 {conf.Body, err = utils.B64DecodeString(conf.Body)if err != nil {return nil, err}}r := &ResponseRewrite{WorkerBase: drivers.Worker(id, name),statusCode: conf.StatusCode,body:       conf.Body,headers:    conf.Headers,match:      conf.Match,}return r, nil
}

结合上文代码,当插件新建时,插件工厂会调用 Create 方法和 Check 方法,Create 方法负责初始化插件执行器实例,Check 方法一般用来校验插件配置的合法性,Check 方法用户可以按需实现,但 Create 方法必须实现。

定义工厂注册方法


const (Name = "response_rewrite"
)func Register(register eosc.IExtenderDriverRegister) {register.RegisterExtenderDriver(Name, NewFactory())
}

将插件注册到拓展驱动管理器中

文件名:app/apinto/worker.go

 

使用插件

开发完成后,新插件就会被同步到节点插件中。我们可以在控制台界面 基础设施 > 节点插件新建插件

 

 新建插件时选择 eolinker.com:apinto:{插件名},本次演示的插件名为 response_rewrite,因此选择插件 eolinker.com:apinto:response_rewrite

若想了解插件的详细使用教程,可点击链接。

写在最后

本文简单介绍了插件入门相关细节,使用者可以根据业务需要,自行开发、安装/卸载、开启/关闭、编排插件,丰富网关能力,强化网关功能。

未来我们计划支持多语言插件,引入插件市场,个人开发者/企业可以将开发的插件贡献到插件市场中,与 Apinto 社区的使用者共享,合作共赢。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/46696.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

clickhouse修改默认密码

1.明文密码 vim /etc/clickhouse-server/users.xml找到下面的语句,增加明文密码 <password>123456789</password> 2. sha256密码 # echo -n 123456789 | openssl dgst -sha256 (stdin) 15e2b0d3c33891ebb0f1ef609ec419420c20e320ce94c65fbc8c3312448eb225 修改…

js new关键字的作用

创建一个新对象&#xff0c;如&#xff1a;var person {};新对象的_proto_属性指向构造函数的原型对象。将构造函数的作用域赋值给新对象。&#xff08;也所以this对象指向新对象&#xff09;执行构造函数内部的代码&#xff0c;将属性添加给person中的this对象。返回新对象pe…

MobileNet、MobileNetV2和MobileNetV3创新点总结

当谈论MobileNet、MobileNetV2和MobileNetV3时&#xff0c;我们指的是一系列基于深度学习的轻量级神经网络架构&#xff0c;这些架构旨在在保持高度准确性的同时减少模型的计算和参数量。以下是它们各自的创新点的详细总结&#xff1a; MobileNet&#xff1a; 深度可分离卷积&…

【LeetCode-中等题】15. 三数之和

题目 题解一&#xff1a;双指针法 图解参考链接&#xff1a;画解算法&#xff1a;15. 三数之和 详解参考代码随想录讲的非常好 梦破碎的地方&#xff01;| LeetCode&#xff1a;15.三数之和 代码&#xff1a; class Solution {public List<List<Integer>> thre…

Codeforces Round 893 (Div. 2) A ~ C

比赛链接 A. Buttons 博弈、最优策略一定是先去按都能按的按钮&#xff0c;按完之后再按自己的。 #include<bits/stdc.h> #define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); #define endl \nusing namespace std;typedef pair<int, int> PII; typede…

Python使用OpenCV库对彩色图像进行通道分离

目录 1、解释说明&#xff1a; 2、使用示例&#xff1a; 3、注意事项&#xff1a; 1、解释说明&#xff1a; 在Python中&#xff0c;我们可以使用OpenCV库对彩色图像进行通道分离。通道分离是将彩色图像的每个像素分解为三个通道&#xff08;红、绿、蓝&#xff09;的过程。…

.eslintrc配置

ESLint 标准规则 /*** AlloyTeam ESLint 规则** 包含所有 ESLint 规则* 使用 babel-eslint 作为解析器** fixable 表示此配置支持 --fix* off 表示此配置被关闭了&#xff0c;并且后面说明了关闭的原因*/module.exports {parser: babel-eslint,parserOptions: {ecmaVersion: 2…

jstack(Stack Trace for Java)Java堆栈跟踪工具

jstack&#xff08;Stack Trace for Java&#xff09;Java堆栈跟踪工具 jstack&#xff08;Stack Trace for Java&#xff09;命令用于生成虚拟机当前时刻的线程快照&#xff08;一般称为threaddump或者javacore文件&#xff09;。 线程快照就是当前虚拟机内每一条线程正在执…

Android 应用冷启动优化

冷启动相关概念 应用启动概念 冷启动&#xff1a;首次打开app或者app彻底销毁后再次打开app&#xff08;开关机后&#xff09;&#xff0c;这也是我们进行启动速度优化的主要方向。热启动&#xff1a;应用运行中按home键再打开应用。温启动&#xff1a;介于两者之间&#xff…

动手学深度学习-pytorch版本(二):线性神经网络

参考引用 动手学深度学习 1. 线性神经网络 神经网络的整个训练过程&#xff0c;包括: 定义简单的神经网络架构、数据处理、指定损失函数和如何训练模型。经典统计学习技术中的线性回归和 softmax 回归可以视为线性神经网络 1.1 线性回归 回归 (regression) 是能为一个或多个…

Linux系统的目录结构

file system hierarchy standard文件系统层级标准&#xff0c;定义了在类Unix系统中的目录结构和目录内容。 即让用户了解到已安装软件通常放置于哪个目录下。 Linux目录结构的特点 使用树形目录结构来组织和管理文件。 整个系统只有一个根目录&#xff08;树根&#xff09;&a…

【SA8295P 源码分析】51 - QNX NFS Server + Android NFS Client 完整配置

【SA8295P 源码分析】51 - QNX NFS Server + Android NFS Client 完整配置 一、QNX 侧 NFS Server 修改:ip 为 192.168.118.21.1 配置拷贝 nfsd、rpcbind 到 /mnt 目录下1.2 配置 exports1.3 为NFS 共享目录挂载镜像1.4 修 startup.sh 开机自启动 nfsd Server1.5 关闭 QNX 防火…

记录几个Hudi Flink使用问题及解决方法

前言 如题&#xff0c;记录几个Hudi Flink使用问题&#xff0c;学习和使用Hudi Flink有一段时间&#xff0c;虽然目前用的还不够深入&#xff0c;但是目前也遇到了几个问题&#xff0c;现在将遇到的这几个问题以及解决方式记录一下 版本 Flink 1.15.4Hudi 0.13.0 流写 流写…

docker redis 配置文件样例

文章目录 1. redis的配置文件1.1 chatGPT 写的配置样例及坑点。 2. docker-compose.yml 文件 1. redis的配置文件 redis官方的配置文件样例 非常有用&#xff0c; 都是从官方文档过摘过来的 1.1 chatGPT 写的配置样例及坑点。 #以下配置来自 chatGPT # 设置 Redis 绑定的 IP…

Flink之时间语义

Flink之时间语义 简介 Flink中时间语义可以说是最重要的一个概念了,这里就说一下关于时间语义的机制,我们下看一下下面的表格,简单了解一下 时间定义processing time处理时间,也就是现实世界的时间,或者说代码执行时,服务器的时间event time事件时间,就是事件数据中所带的时…

DataWhale夏令营第三期-CV赛道-第二次打卡

脑部PET比赛 第二次打卡 运行cnn Baseline时第一段代码报错 FutureWarning: RandomContrast has been deprecated. Please use RandomBrightnessContrast warnings.warn( 根据报错信息新版本的RandomContrast已经弃用&#xff0c;改为RandomBrightnessContrast方法即可。 从这…

nginx代理webSocket链接响应403

一、场景 使用nginx代理webSocket链接&#xff0c;nginx响应403 1、nginx访问日志响应403 [18/Aug/2023:09:56:36 0800] "GET /FS_WEB_ASS/webim_api/socket/message HTTP/1.1" 403 5 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit…

【数据结构】循环队列

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …

浏览器 - 事件循环机制详解

目录 1&#xff0c;浏览器进程模型进程线程浏览器的进程和线程1&#xff0c;浏览器进程2&#xff0c;网络进程3&#xff0c;渲染进程 2&#xff0c;渲染主线程事件循环异步同步 JS 为什么会阻塞渲染任务优先级 3&#xff0c;常见面试题1&#xff0c;如何理解 js 的异步2&#x…

C语言刷题 1

文章目录 题目答案与解析123 题目 1.strcpy实现 自己设计函数模拟实现库函数strcpy 2.strlen实现 自己设计函数模拟实现库函数strlen 3.调整奇数偶数顺序 输入一个整数数组&#xff0c;实现一个函数&#xff0c;来调整该数组中数字的顺序使得数组中所有的奇数位于数组的前半部…