OpenAPI-Suite(从 OpenAPI 3.0 生成 ObjectScript 代码的工具集):介绍 InterSystems 开发人员工具大赛 2023 获奖者
开发者您好!
这里向介绍@Lorenzo Scalese的OpenAPI-Suite (一个用于从OpenAPI 3.0生成 ObjectScript 代码的工具集)。这个工具集在 2023 年 InterSystems 开发工具大赛的21 个参赛作品中获得专家提名第三名。
目前 IRIS 最高支持OpenAPI 2.0 ,但是这个工具支持 OpenAPI 3.0 !
提供的功能如下。
- 在服务器端创建类(与 OpenAPI 2.0相同,首先创建使用 API First理念创建的 REST 调度类所需的类。)
- 创建客户端 HTTP 类
- 创建客户端Production(业务服务、业务流程、业务操作、Ens.Request、Ens.Response)
- 一个 Web 界面,允许您指定要从此工具生成哪些功能
- 从 OpenAPI 1.x、2.x 到 3.0 版的转换工具
关于各个功能的详细介绍,请参考@Lorenzo Scales撰写的文章《 OpenAPI Suite - Part 1 》和《 OpenAPI Suite - Part 2 》。
在本文中,我尝试了 1 个功能。其中,以下的应对方案非常好。
- 根据OpenAPI 3.0新增的Components对象的内容自动生成类的定义(在指定包下创建一个模型包,在那里创建可以实例化的类)
- 在POST或PUT的情况下,为了较为轻松地使用实施类(impl.cls)处理HTTP请求中传递的信息,我将Body中接收到的JSON数据设为了1中生成的类的实例,
- 目前,虽然需要进行一些手动更改,但是仅使用按原样创建的实例在 impl.cls 中叫 %Save() 方法也可以保存成功。 )
IRIS 提供了一种根据 OpenAPI 2.0 规范创建 REST 调度类的方法,但实际使用中它只创建要使用的类和根URL。
仅作为参考,这里是使用 IRIS 支持的 OpenAPI 2.0 创建的内容。
(以下示例使用了根据 OpenAPI2.0 规范创建的 JSON 示例。)
在下面的示例中,/crud 是根 URL,类是在 crud 包下创建的。
生成的类如下(左:impl.cls,右:spec.cls)
由于调度类(disp.cls)是一个不需要改动的类,所以这里展示了studio的这部分代码。
接下来介绍一下@Lorenzo Scalese的OpenAPI-Suite的成果。
使用它的过程非常简单。
从管理门户或Studio导入IPM (InterSystems Package Manager,以前称为 ZPM)客户端工具后,您只需运行以下命令,工具就可以使用了。
客户端工具导入可以导入到任意命名空间中。
从管理门户导入时,使用以下菜单:
管理门户 -> 系统资源管理器 -> 类 -> 选择要导入的命名空间 -> 单击导入按钮
转到您希望 REST 调度类存在的命名空间,并使用 ZPM 命令安装工具。
zpm "install openapi-suite"
安装后,您可以通过以下 URL 访问该工具的相关信息。
http://localhost:端口号/openapisuite/ui/index.csp
示例)http://localhost:52773/openapisuite/ui/index.csp
在初始阶段,屏幕右下方的“Install On Server”按钮无法按下。似乎可以通过将值设置为以下全局变量来按下按钮。
(请在你安装工具的命名空间中用ZPM命令设置)
Set ^openapisuite .config( "web" , "enable-install-onserver" ) = 1
准备工作完成后,进行以下设置。
对于“Application package name”,选择类定义的包名称(示例中的 PetStore);对于“What do you want to generate?”问题,选择“REST Server”;对于“NameSpace”,选择要注册 REST 调度类的命名空间;对于“Web 应用程序名称”,指定已定义的根 URL(Web 应用程序路径)(示例中的 /pet1)。
之后,只需指定根据OpenAPI规范创建的JSON文件即可。示例中默认指定https://petstore3.swagger.io/api/v3/openapi.json ,我们可以直接使用这个文件路径。
最后,单击 Install On Server 按钮。
日志如下图所示,确认正常结束后点击关闭按钮。
通过该工具,将创建一个 Web 应用程序路径:/pet1。
从管理门户 -> 系统管理 -> 安全 -> 应用程序 -> Web 应用程序检查 /pet1 是否存在。
定义完成!
现在,让我们检查是否已经创建了记载输入路径对应的方法的disp(调度类)和实施代码的impl类。
类定义已经在 PetStore 包下创建完成!
与IRIS提供的OpenAPI 2.0的类不同的是,这里包含了model包和requests包。
在这个工具中,OpenAPI 3.0的Components对象中指定的信息被创建为可以生成实例的类定义。 (它继承了 %RegisteredObject 类)
Components对象Pet的信息可以在下方展开查看。
根据此信息创建的类如下:
它在可以实例化的类中。
如果将super class从 %RegisteredObject 更改为 %Persistent 并编译,则可以将其用作可以在数据库中持久化储存的类。
此外,POST 请求将发送以下格式的 JSON 对象。
{ "id": 0,
"category": {
"id": 0,
"name": "Dog"
},
"name": "Hachi",
"photoUrls": [
"https://x.gd/1pbYK"
],
"tags": [
{
"id": 0,
"name": "Middle"
}
],
"status": "available"
}
能够将此 JSON 直接作为 Pet、Tag 和 Category 类下的实例会很好,因此又追加继承了 %JSON.Adaptor 。
另外,如果我要修改 Pet、Tag 和 Category,最好将super class的配置从 %RegisteredObject 更改为 %Persistent 和 %JSON.Adaptor 的多重继承。
在此之后,需要将接收到的Body信息更新到数据库中。
Request包下的类描述了这个过程的概要。以下示例显示了在向 /pet 发出 POST 请求时运行的类 (PetStore.requests.addPet.cls) 的内容。
如果你注意LoadFromRequest()方法,你会发现它在把可以处理HTTP请求的%request传递给参数request(在IRIS的REST调度类内部处理时,HTTP请求存储在%CSP.Request的一个实例中)。
request.Content
上面的执行可以得到Body中指定的JSON对象。
Do ..PetNewObject (). %JSONImport (request.Content)
这个类中虽然调用了以上方法,但由于该类中实际上并没有PetNewObject()方法,所以做了如下修改(生成一个Pet实例,将其设置为属性Pet,然后将接收到的JSON分配给实例处理)。
set ..Pet = ##class (PetStore.model.Pet). %New ()
do ..Pet . %JSONImport (request.Content)
这样就完成了接收到 HTTP 请求时的处理。剩下的就是impl.cls的实现了。
在初始状态下,以下方法没有任何描述。
ClassMethod addPet(messageRequest As PetStore.requests.addPet) As %Status
{ ; Implement your service here.
; Return {} $$$ThrowStatus ( $$$ERROR ( $$$NotImplemented ))
}
参数 messageRequest 指定了 PetStore.requests.addPet 类的一个实例,该实例在之前的流程中得到确认(根据 HTTP 请求中收到的 JSON 对象创建的实例在该实例的 Pet 属性中设置。)
改写如下,编译,大功告成!
ClassMethod addPet(messageRequest As PetStore.requests.addPet) As %Status
{
;Implement your service here.
; Return {} //$$$ThrowStatus($$$ERROR($$$NotImplemented))
set status= $$$OK
set status=messageRequest.Pet. %Save ()
return status
}
让我们来测试 POST 请求。
Pet、Category、和Tag都注册并添加数据成功了!
这个用例还是需要一些手动修改,但当我发现类定义是通过 OpenAPI 3.0 Components 对象自动生成的,让我觉得很便利!
大家也请试用一下。