本节介绍InterSystems IRIS®中的REST和REST服务。您可以将这些REST接口与UI工具(如Angular)一起使用,以提供对数据库和互操作性产品的访问。您还可以使用它们使外部系统能够访问InterSystems IRIS®数据平台应用程序。有关REST服务的交互式介绍,请尝试“开发REST接口”。
2.1 REST简介
REST是根据“代表性状态转移”命名的,具有以下属性:
-
REST是一种体系结构风格,而不是一种格式。尽管REST经常使用HTTP来传输消息,使用JSON来传递数据,但您也可以将数据作为XML或纯文本传递。REST利用现有的web标准,如HTTP、URL、XML和JSON。
-
REST是面向资源的。通常,资源由URL标识,并使用基于HTTP方法的操作,例如GET、POST、PUT和DELETE。
-
REST通常开销很小。虽然它可以使用XML来描述数据,但它更常用的是JSON,这是一种轻量级的数据包装器。JSON使用标记标识数据,但标记没有在正式模式定义中指定,也没有明确的数据类型。
2.2 InterSystems REST服务简介
InterSystems IRIS 2019.2及更高版本中有两种定义REST接口的方法:
- 规范优先定义-首先创建OpenAPI 2.0规范,然后使用API管理工具生成REST接口的代码。
- 手动编码REST接口。
使用规范优先定义,InterSystems REST服务正式由以下组件组成:
-
规范类(
%REST.Spec
的子类)。此类包含REST服务OpenAPI 2.0规范。InterSystems支持可以在规范中使用的几个扩展属性。 -
分派类(
%CSP.REST
的子类)。此类负责接收HTTP请求并调用实现类中的适当方法。 -
实现类(
%REST.Impl
的子类)。此类定义实现REST调用的方法。API管理工具生成实现类的存根版本,然后将其扩展为包含必要的应用程序逻辑。(您的逻辑当然可以调用该类之外的代码。)
%REST.Impl
提供了可以调用的方法,以便设置HTTP标头、报告错误等。 -
InterSystems web应用程序,通过InterSystems web网关提供对REST服务的访问。web应用程序被配置为启用REST访问并使用特定的分派类。web应用程序还控制对REST服务的访问。
InterSystems对这些组件遵循严格的命名约定。给定应用程序名称(appname
),规范、分派和实现类的名称分别为appname.spec
、appname.disp
和appname.impl
。默认情况下,web应用程序名为/csp/appname
,但可以使用其他名称。
InterSystems支持规范优先范式。您可以从规范中生成初始代码,当规范发生更改时(例如,通过获取新的端点),您可以重新生成该代码。后面的部分提供了更多详细信息,但现在请注意,您不应该编辑分派类,而是可以修改其他类。此外,当您重新编译规范类时,调度类会自动重新生成,实现类也会更新(保留您的编辑)。
2.2.1 手动编码REST服务
在2019.2之前的版本中,InterSystems IRIS不支持规范第一范式。REST服务在形式上仅由分派类和web应用程序组成。本书将REST服务定义为手动编码的REST服务。区别在于,由较新的REST服务定义的REST服务包含规范类,而手动编码的REST服务不包含规范类。本书的“手动创建REST服务”附录描述了如何使用手动编码范式创建REST服务。类似地,一些API管理实用程序使您能够使用手动编码的REST服务。
2.3 InterSystems API管理工具简介
为了帮助您更轻松地创建REST服务,InterSystems提供了以下API管理工具:
- 名为
/api/mgmnt
的REST服务,您可以使用它来发现服务器上的REST服务、生成OpenAPI 2.0规范的REST服务,以及在服务器上创建、更新或删除REST服务。 ^%REST
例程,它提供了一个简单的命令行界面,可用于列出、创建和删除REST服务。%REST.API
类,您可以使用它来发现服务器上的REST服务,生成OpenAPI 2.0规范的REST服务,以及在服务器上创建、更新或删除REST服务。
您可以为这些工具设置日志记录,如本章稍后所述。
有用的第三方工具包括REST测试工具,如PostMan(https://www.getpostman.com/)和Swagger编辑器(https://swagger.io/tools/swagger-editor/download/)。
2.4 创建REST服务概述
在InterSystems产品中创建REST服务的推荐方法大致如下:
- 获取(或写入)Rest服务OpenAPI 2.0规范。
- 使用API管理工具生成REST服务类和关联的web应用程序。请参阅“创建和编辑REST服务”
- 修改实现类,使方法包含适当的业务逻辑。请参阅“修改实现类”一章
- (可选)修改规范类。请参阅“修改规范类”一章。例如,如果您需要支持CORS或使用web会话,请执行此操作。
- 如果需要安全性,请参阅“保护REST服务”一章
- 使用Rest服务OpenAPI 2.0规范,生成文档,如“发现和记录REST API”一章所述
对于步骤2,另一个选项是手动创建规范类(将规范粘贴到其中),然后编译该类;这个过程生成分派和存根实现类。也就是说,严格来说,不必使用/api/mgmnt
服务或^%REST
例程。
2.5 深入了解REST服务类
本节详细介绍了规范、分派和实现类。
2.5.1 规范类
规范类旨在定义REST服务遵循的契约。此类扩展了%REST.Spec
,并包含OpenAPI 2.0规范的REST服务XData块。以下是部分示例:
Class petstore.spec Extends %REST.Spec [ ProcedureBlock ]
{
XData OpenAPI [ MimeType = application/json ]
{
{
"swagger":"2.0",
"info":{
"version":"1.0.0",
"title":"Swagger Petstore",
"description":"A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification",
"termsOfService":"http://swagger.io/terms/",
"contact":{
"name":"Swagger API Team"
},
"license":{
"name":"MIT"
}
},
...
您可以通过替换或编辑XData块中的规范来修改此类。您还可以根据需要添加类参数、属性和方法。每当编译规范类时,编译器都会重新生成分派类并更新实现类(请参阅“InterSystems如何更新实现类”)。
2.5.2 分派类
当调用REST服务时,直接调用分派类。以下是部分示例:
/// Dispatch class defined by RESTSpec in petstore.spec
Class petstore.disp Extends %CSP.REST [ GeneratedBy = petstore.spec.cls, ProcedureBlock ]
{
/// The class containing the RESTSpec which generated this class
Parameter SpecificationClass = "petstore.spec";
/// Default the Content-Type for this application.
Parameter CONTENTTYPE = "application/json";
/// By default convert the input stream to Unicode
Parameter CONVERTINPUTSTREAM = 1;
/// The default response charset is utf-8
Parameter CHARSET = "utf-8";
XData UrlMap [ XMLNamespace = "http://www.intersystems.com/urlmap" ]
{
<Routes>
<Route Url="/pets" Method="get" Call="findPets" />
<Route Url="/pets" Method="post" Call="addPet" />
<Route Url="/pets/:id" Method="get" Call="findPetById" />
<Route Url="/pets/:id" Method="delete" Call="deletePet" />
</Routes>
}
/// Override %CSP.REST AccessCheck method
ClassMethod AccessCheck(Output pAuthorized As %Boolean) As %Status
{
...
}
...
请注意,SpecificationClass
参数指示关联的规范类的名称。URLMapXData
块(URL映射)定义此REST服务中的调用。
在这些项之后,类包含URL映射中列出的方法的定义。这里有一个例子:
ClassMethod deletePet(pid As %String) As %Status
{
Try {
If '##class(%REST.Impl).%CheckAccepts("application/json") Do ##class(%REST.Impl).%ReportRESTError(..#HTTP406NOTACCEPTABLE,$$$ERROR($$$RESTBadAccepts)) Quit
If ($number(pid,"I")="") Do ##class(%REST.Impl).%ReportRESTError(..#HTTP400BADREQUEST,$$$ERROR($$$RESTInvalid,"id",id)) Quit
Set response=##class(petstore.impl).deletePet(pid)
Do ##class(petstore.impl).%WriteResponse(response)
} Catch (ex) {
Do ##class(%REST.Impl).%ReportRESTError(..#HTTP500INTERNALSERVERERROR,ex.AsStatus())
}
Quit $$$OK
}
请注意以下几点:
-
此方法调用实现类中同名的方法(本例中为
petstore.impl
)。它从该方法获取响应,并调用%WriteResponse()
将响应写回调用者。%WriteResponse()
方法是一个继承的方法,存在于所有实现类中,这些实现类都是%REST.Impl
的子类。 -
此方法执行其他检查,如果出现错误,则调用
%REST.Impl
的其他方法。
重要:
因为分派类是一个生成的类,所以您永远不应该编辑它。InterSystems提供了一些机制,可以在不编辑分派类的情况下重写分派类的部分。
2.5.3 实现类
实现类用于保存REST服务的实际内部实现。你可以(也应该)编辑这个类。它最初看起来像以下示例:
/// A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification<br/>
/// Business logic class defined by RESTSpec in petstore.spec<br/>
Class petstore.impl Extends %REST.Impl [ ProcedureBlock ]
{
/// If ExposeServerExceptions is true, then details of internal errors will be exposed.
Parameter ExposeServerExceptions = 0;
/// Returns all pets from the system that the user has access to<br/>
/// The method arguments hold values for:<br/>
/// tags, tags to filter by<br/>
/// limit, maximum number of results to return<br/>
ClassMethod findPets(tags As %ListOfDataTypes(ELEMENTTYPE="%String"), limit As %Integer) As %Stream.Object
{
//(Place business logic here)
//Do ..%SetStatusCode(<HTTP_status_code>)
//Do ..%SetHeader(<name>,<value>)
//Quit (Place response here) ; response may be a string, stream or dynamic object
}
...
实现类的其余部分包含与此类似的其他存根方法。在每一种情况下,这些存根方法都具有符合REST服务规范定义的契约的签名。注意,对于options方法,InterSystems不会生成存根方法供您实现。相反,%CSP.REST
会自动执行所有选项处理。
2.6 为API管理功能启用日志记录
要启用API管理功能的日志记录,请在终端中输入以下内容:
set $namespace="%SYS"
kill ^ISCLOG
set ^%ISCLOG=5
set ^%ISCLOG("Category","apimgmnt")=5
然后,系统将条目添加到^ISCLOG
全局中,以便调用API管理端点。
要将日志写入文件(以便于阅读),请输入以下内容(仍在%SYS
命名空间中):
do ##class(%OAuth2.Utils).DisplayLog("filename")
其中filename
是要创建的文件的名称。目录必须已存在。如果文件已存在,则将覆盖该文件。
要停止日志记录,请输入以下内容(仍在%SYS
命名空间中):
set ^%ISCLOG=0
set ^%ISCLOG("Category","apimgmnt")=0
2.6.1 查看日志
启用HTTP请求日志记录后,日志条目将存储在^ISCLOG
全局中,该全局位于%SYS
命名空间中。
要使用管理门户查看日志,请导航到System Explorer>Globals并查看ISCLOG
全局(而不是%ISCOLOG
)。确保您位于%SYS
命名空间中。