#REST API

0 关注者 · 67 帖子

表述性状态传递 (REST) 是一种软件架构风格,它定义了一组用于创建 Web 服务的约束。符合 REST 架构风格的 Web 服务(称为 RESTful Web 服务 (RWS))提供了互联网上计算机系统之间的互操作性。RESTful Web 服务允许请求系统通过使用统一预定义的无状态操作集来访问和操作 Web 资源的文本表示。其他类型的 Web 服务(如 SOAP Web 服务)需要公开它们自己的专有操作集。

了解更多信息

文章 Nicky Zhu · 十月 10, 2024 7m read

本演示程序用于展示如何采用自定义FHIR profile来验证数据合规性。自定义FHIR实施指南基于FHIR R4版本开发,在本例中实现了对Organization资源的扩展并用于验证数据的合规性。

安装

  1. 通过Git clone下载本项目。
  2. 执行docker-compose up -d构建并启动容器,初次执行时需执行需10~15分钟(视配置变化)。将构建InterSystems IRIS for Health镜像,安装FHIR服务器,导入自定义FHIR规范,使自定义FHIR 规范可用于验证数据。
  3. 在Postman中导入TestCases中的测试用例文件,查看各类FHIR约束的测试效果
  4. 容器启动后可查看自定义IG内容

项目代码结构

FHIRValidation
├─ ExampleIG                        
│  ├─ ig.ini
│  ├─ input
│  │  ├─ fsh
│  │  │  ├─ alias.fsh
│  │  │  ├─ codesystems.fsh
│  │  │  ├─ organization.fsh
│  │  │  └─ valuesets.fsh
│  │  └─ pagecontent
│  │     └─ index.md
│  └─ sushi-config.yaml
├─ README.md
├─ README_zh.md
├─ TestCases
│  └─ FHIR Profile-based Validation  testcases.postman_collection.json
├─ docker-compose.yml
└─ image-iris
   ├─ Dockerfile
   └─ src
      ├─ FullIG
      ├─ IGPackages
      │  ├─ hl7.fhir.uv.extensions.r4#5.1.0.tgz
      │  ├─ hl7.terminology.r4#6.0.2.tgz
      │  └─ package.tgz
      └─ init
         └─ init.sh

ExampleIG

该子目录下的所有文件为本项目所采用的自定义FHIR规范SUSHI源码,供用户定义FHIR规约时参考使用。

TestCases

该子目录下存放基于FHIR REST API的测试用例脚本,需导入到Postman中使用

image-iris

该子目录下存放nterSystems IRIS for Health镜像所需的文件,其中: └─ src ├─ FullIG 该目录中存放SUSHI生成的自定义FHIR IG ├─ IGPackages 该目录中存放自定义FHIR IG的 package 文件 └─ init 该目录中存放IRIS的Docker镜像初始化脚本

FHIR package简介

HL7组织推荐使用实施指南(Implementation Guild)来解释如何使用FHIR规范。除用于开发人员阅读的说明(如html)外,实施指南中通常也包括可直接被机器读取和应用的工件(artifacts),可被用于驱动代码生成和数据验证等任务。
FHIR实施指南采用NPM Package规范管理依赖。指南涉及的所有StructureDefinition,ValueSet等资源将被打包在一块,形成可被FHIR Server用于读取规范,生成客户端代码或执行数据质量校验的资源包。
通过SUSHI工具生成的实施指南中就包含若干package文件。如本例中,image-iris/src/IGPackages/package.tgz即为生成的package包,可被IRIS FHIR Server直接导入使用。应当注意到的是,除核心资源包(如hl7.fhir.r4.core)外,完整的FHIR规范还需要引用术语、扩展等额外的资源包。
目前FHIR规范引用机制的文档尚不完善。如基于R4版的FHIR规范除引用hl7.fhir.r4.core外,还需引用hl7.fhir.uv.extensions.r4#5.1.0hl7.terminology.r4#6.0.2,但这些引用关系在R5版本中方有记录,在R4版文档中并未完整声明,需开发者在开发过程中自行补充。
在本例中这些包已下载在image-iris/src/IGPackages文件夹下,将作为依赖在自定义FHIR实施指南之前加载。

FHIR validation简介

参见FHIR规范Validating Resources一节。FHIR规范已经设计了对数据结构、属性基数、值域、代码绑定和约束等一系列机制在内的数据质量校验机制。HL7组织在FHIR规范中并未强制要求遵循何种强度的质量控制,但建议采用宽进严出的原则处理FHIR数据。
对于保存FHIR资源的FHIR存储库而言,保障FHIR资源的数据质量是使医疗行业具有价值,保障医疗行为安全性的前提条件。因此,在构建基于FHIR存储的数据共享交换方案时,即使不得不保存不满足数据质量要求的数据,也应对其进行校验,标识不符合项,推动数据治理活动的进行,从而保障医疗安全和数据消费者的利益。
在FHIR规范指出的多种数据校验方式中,FHIR Validator和FHIR操作对数据质量校验的覆盖最为全面。
本例将使用InterSystems IRIS for Health所提供的$validate操作,通过profile参数对尚未保存的FHIR数据进行校验。使用者也可修改测试用例,构建HTTP POST参数,对存量FHIR资源进行校验。
还应当注意的是,$validate操作如被正确调用,将通过Http 200返回校验结果,如有不符合项,将在返回的OperationOutcome资源中包裹错误信息,而不通过Http代码标识错误。

对FHIR的扩展

在本例中基于FHIR R4对Organization资源进行了如下扩展:

1. 修改language的绑定强度

将机构主要语言的绑定强度修改为required

2. active字段基数从0..1改为1..1

从而使得数据的状态成为必填字段,有且只有一个元素

3. name字段基数从0..1改为1..1

组织机构名称成为必填字段,有且只有一个元素。参考我国医院除医院名称外,如果具备急救中心、胸痛中心等牌照,还可能具有多个名称。但因注意到,这些牌照通常标识了医疗机构提供的服务能力,而非在组织机构注册系统中具备的法定名称,且此类牌照生命周期与医疗机构自身的生命周期并不一致。因此,从牌照获得的名称宜视为该医疗机构的服务能力而非机构的唯一名称。在FHIR中,通过服务能力获得的名称可通过资源HealthcareService提供,该资源与Organization资源间可建立多对一的引用关系,更适合用来表达上述概念。

4. 增加医疗机构的组织机构类型

根据中国国家标准GB/T 20091-2021 组织机构类型,分别增加了CodeSystem organizationtype-code-system和ValueSet organizationtype-vs,并通过Extension向Organization资源中添加了扩展mdm-organizationTypeExtension,从而使得该资源可用于表示表示标识中国组织机构类型。
该扩展通过对Extension切片实现,且基数为1..1,即医疗机构资源必须具有组织机构类型元素。

5. 约束医疗机构证件号码

FHIR基础标准并未纳入中国组织机构统一社会信用代码的证件类型,为此增加了CodeSystem cs-identifierType-code-system,并对Identifier按其类型进行了切片,使之必须可以表达社会信用代码。且社会信用代码的格式遵循以下约束:

  1. identifier.use必须取值为official,即正式/官方用途
  2. identifier.type必须遵循cs-identifierType-code-system要求,system必须为该codesystem的uri,code必须为“USCC”
  3. identifier.value必须遵循自定义约束uscc-length-18,该字段长度必须为18位,其中前17位必须为数字,最后1位必须为数字或字母

测试用例列表

1. Without profile - All OK

未声明资源对应的profile,因此FHIR Server将不对资源中各属性的值进行校验,仅返回All OK。

2. Unknow field

在资源中加入了未被定义的属性isNational,因此校验引擎返回了Unrecognized element错误。

3. Wrong cardinality - less

在本IG中,修改了Organization资源name属性的基数为1..1,即应有且仅有一个组织机构名称。本测试用例未填写名称,因此数据校验失败。 另外,可以观察到Identifier.type经过扩展,加入了统一社会信用代码作为标识符类型,FHIR R4规范里并不包含这个值,但该字段的代码绑定强度仅为example,不强制约束。因此校验引擎返回了information级的值域代码不符合信息而没有报错。

4. Binding strength

在本IG中,组织机构的language属性的代码绑定强度改为了required,则该字段值域必须符合http://hl7.org/fhir/ValueSet/languages,因此,当该字段取值为wrong language时,因不在required值域中,将导致error级错误

5. Wrong value

在本IG中,组织机构类型的值域来自于organizationtype-code-system,因此,当类型为mdm-organizationTypeExtension的extension元素中code的值为“999”,不在值域中时,将导致error级错误

6. Failing invariant

在本IG中,组织机构的社会信用代码必须遵循自定义约束uscc-length-18(该字段长度必须为18位,其中前17位必须为数字,最后1位必须为数字或字母),因此,当其末位为字符“%”时,违反该约束,将导致error级错误

7. Failing profile

对于一个资源定义的一个profile包含了多个约束,因此,在校验时所有不满足profile的问题都将被检出,例如本例中:

  1. 错误的language代码
  2. 错误的组织机构类型
  3. 缺少name字段 可见上述问题都被检出
0
0 127
问题 liu bo · 八月 19, 2024

1.我在java中发布了一个服务提供给调用,postman中可以请求解析出数据

请求信息如下:

POST /uploadPersonExcel HTTP/1.1
Host: localhost:8017
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
cache-control: no-cache
Postman-Token: 1c23edfe-1e83-44c6-8f91-e06bccfd4af3

Content-Disposition: form-data; name="file"; filename="C:\Users\elite\Desktop\personinfo.xlsx

------WebKitFormBoundary7MA4YWxkTrZu0gW--

2.Ensemble中请求代码如下:

2
0 94
文章 Nicky Zhu · 六月 29, 2024 8m read

通过 REST API 将前端 React 应用程序与 IRIS 数据库等后端服务集成,是构建健壮网络应用程序的强大方法。但是,开发人员经常遇到的一个障碍是跨源资源共享(CORS)问题,由于网络浏览器强制执行的安全限制,该问题可能会阻止前端访问后端的资源。在本文中,我们将探讨在将 React Web 应用程序与 IRIS 后端服务集成时如何解决 CORS 问题。

创建Schema

我们首先定义一个名为 Patients 的简单Schema:

Class Prototype.DB.Patients Extends %Persistent [ DdlAllowed ]
{

Property Name As %String;

Property Title As %String;

Property Gender As %String;

Property DOB As %String;

Property Ethnicity As %String;
}

您可以在表中插入一些虚假数据进行测试。我个人认为 Mockaroo 在创建假数据时非常方便。它可以让你把虚拟数据下载为 .csv 文件,直接导入管理门户。

定义 REST 服务

然后,我们定义几个 REST 服务

Class Prototype.DB.RESTServices Extends %CSP.REST
{

Parameter CONTENTTYPE = "application/json";
    
XData UrlMap [ XMLNamespace = "http://www/intersystems.com/urlmap" ]
{
<Routes>
    <Route Url = "/patients" Method="Get" Call="GetPatients"/>
    <Route Url = "/patient/:id" Method="Post" Call="UpdatePatientName"/>
</Routes>
}

ClassMethod GetPatients() As %Status
{
    #Dim tStatus As %Status = $$$OK

    #Dim tSQL As %String = "SELECT * FROM Prototype_DB.Patients ORDER BY Name"

    #Dim tStatement As %SQL.Statement = ##class(%SQL.Statement).%New()
    
    Set tStatus = tStatement.%Prepare(tSQL)

    If ($$$ISERR(tStatus)) Return ..ReportHttpStatusCode(..#HTTP400BADREQUEST, tStatus)

    #Dim tResultSet As %SQL.StatementResult

    Set tResultSet = tStatement.%Execute()

    #Dim tPatients As %DynamicArray = []

    While (tResultSet.%Next()) {
        #Dim tPatient As %DynamicObject = {}
        Set tPatient.ID = tResultSet.ID
        Set tPatient.Name = tResultSet.Name
        Set tPatient.Title = tResultSet.Title
        Set tPatient.Gender = tResultSet.Gender
        Set tPatient.DOB = tResultSet.DOB
        Set tPatient.OrderedBy = tResultSet.OrderedBy
        Set tPatient.DateOfOrder = tResultSet.DateOfOrder
        Set tPatient.DateOfReport = tResultSet.DateOfReport
        Set tPatient.Ethnicity = tResultSet.Ethnicity
        Set tPatient.HN = tResultSet.HN
        Do tPatients.%Push(tPatient)
    }
    Do ##class(%JSON.Formatter).%New().Format(tPatients)
    Quit $$$OK
}

ClassMethod UpdatePatientName(pID As %Integer)
{
    #Dim tStatus As %Status = $$$OK
    #Dim tPatient As Prototype.DB.Patients = ##class(Prototype.DB.Patients).%OpenId(pID,, .tStatus)
    If ($$$ISERR(tStatus)) Return ..ReportHttpStatusCode(..#HTTP404NOTFOUND, tStatus)
    #Dim tJSONIn As %DynamicObject = ##class(%DynamicObject).%FromJSON(%request.Content)
    Set tPatient.Name = tJSONIn.Name
    Set tStatus = tPatient.%Save()
    If ($$$ISERR(tStatus)) Return ..ReportHttpStatusCode(..#HTTP400BADREQUEST, tStatus)
    #Dim tJSONOut As %DynamicObject = {}
    Set tJSONOut.message = "patient name updated successfully"
    Set tJSONOut.patient = ##class(%DynamicObject).%New()
    Set tJSONOut.patient.ID = $NUMBER(tPatient.%Id())
    Set tJSONOut.patient.Name = tPatient.Name
    Do ##class(%JSON.Formatter).%New().Format(tJSONOut)
    Quit $$$OK
}

}

然后,我们继续在管理门户上注册网络应用程序

  1. 在管理门户上导航至 系统管理 -> 安全 -> 应用程序 -> Web 应用程序 -> 创建 Web 应用程序"。
  2. 填写下表 image
  3. Prototype/DB/RESTServices.cls 中定义的 API 将在 http://localhost:52773/api/prototype/* 中提供。
  4. 现在,我们可以使用 Postman 请求端点,以验证 API 是否可用 image

创建前端

我使用 Next.js 创建了一个简单的前端,Next.js 是一个流行的 React 框架,它能让开发人员轻松创建服务器端渲染(SSR)的 React 应用程序。

我的前端是一个简单的表格,用于显示存储在 IRIS 中的患者数据,并提供更新患者姓名的功能。

 const getPatientData = async () => {
    const username = '_system'
    const password = 'sys'
    try {
        const response: IPatient[] = await (await fetch("http://localhost:52773/api/prototype/patients", {
        method: "GET",
        headers: {
          "Authorization": 'Basic ' + base64.encode(username + ":" + password),
          "Content-Type": "application/json"
        },
      })).json()
      setPatientList(response);
    } catch (error) {
      console.log(error)
    }
  }

看似一切准备就绪,但如果直接运行 "npm run dev",就会出现 CORS :(

解决 CORS 问题

当网络应用程序尝试向不同域上的资源发出请求,而服务器的 CORS 策略限制了客户端的访问,导致请求被浏览器阻止时,就会发生 CORS 错误。我们可以在前台或后台解决 CORS 问题。

设置响应标头(后台方法)

首先,我们在定义 API 端点的同一个 Prototype/DB/RESTServices.cls 调度器类中添加 HandleCorsRequest 参数。

Parameter HandleCorsRequest = 1;

然后,我们在派发器类中定义 OnPreDispatch 方法来设置响应头。

   ClassMethod OnPreDispatch() As %Status
    {
        Do %response.SetHeader("Access-Control-Allow-Credentials","true")
        Do %response.SetHeader("Access-Control-Allow-Methods","GET, PUT, POST, DELETE, OPTIONS")
        Do %response.SetHeader("Access-Control-Max-Age","10000")
        Do %response.SetHeader("Access-Control-Allow-Headers","Content-Type, Authorization, Accept-Language, X-Requested-With")
        quit $$$OK
    } 

使用 Next.js 代理(前端方法)

next.config.mjs文件中添加重写函数:

 /** @type {import('next').NextConfig} */
        const nextConfig = {
            async rewrites() {
                return [
                    {
                        source: '/prototype/:path',
                        destination: 'http://localhost:52773/api/prototype/:path'
                    }
                ]
            }
        };

        export default nextConfig;

并将所有提取 url 从 http://127.0.0.1:52773/api/prototype/:path 更新为 `/prototype/:path

最终产物

在这里,我放置了前台页面的代码:

'use client'
import { NextPage } from "next"
import { useEffect, useState } from "react"
import { Table, Input, Button, Modal } from "antd";
import { EditOutlined } from "@ant-design/icons";
import type { ColumnsType } from "antd/es/table";
import base64 from 'base-64';
import fetch from 'isomorphic-fetch'
const HomePage: NextPage = () => {
  const [patientList, setPatientList] = useState<IPatient[]>([]);
  const [isUpdateName, setIsUpdateName] = useState<boolean>(false);
  const [patientToUpdate, setPatientToUpdate] = useState<IPatient>()
  const [newName, setNewName] = useState<string>('')
  const getPatientData = async () => {
    const username = '_system'
    const password = 'sys'
    try {
        const response: IPatient[] = await (await fetch("http://localhost:52773/api/prototype/patients", {
        method: "GET",
        headers: {
          "Authorization": 'Basic ' + base64.encode(username + ":" + password),
          "Content-Type": "application/json"
        },
      })).json()
      setPatientList(response);
    } catch (error) {
      console.log(error)
    }
  }

  const updatePatientName = async () => {
     let headers = new Headers()
    const username = '_system'
    const password = 'sys'
    const ID = patientToUpdate?.ID
    try {
      headers.set("Authorization", "Basic " + base64.encode(username + ":" + password))
      const response: { message: string, patient: { ID: number, Name: string } } =
        await (await fetch(`http://127.0.0.1:52773/api/prototype/patient/${ID}`, {
        method: "POST",
          headers: headers,
          body: JSON.stringify({Name: newName})
      })).json()
      let patientIndex = patientList.findIndex((patient) => patient.ID == response.patient.ID)
      const newPatientList = patientList.slice()
      newPatientList[patientIndex] = {...patientList[patientIndex], Name: response.patient.Name}
      setPatientList(newPatientList);
      setPatientToUpdate(undefined);
      setNewName('')
      setIsUpdateName(false)
    } catch (error) {
      console.log(error)
    }
  }
  const columns: ColumnsType = [
    {
      title: 'ID',
      dataIndex: 'ID',
    },
    {
      title: "Title",
      dataIndex: "Title"
    },
    {
       title: 'Name',
      dataIndex: 'Name',
      render: (value, record, index) => {
        return (
          <div className="flex gap-3">
            <span>{value}</span>
            <span className="cursor-pointer" onClick={() => {
              setIsUpdateName(true)
              setPatientToUpdate(record)
            }}><EditOutlined /></span>
          </div>
        )
      }
    },
    {
      title: "Gender",
      dataIndex: 'Gender'
    },
    {
      title: "DOB",
      dataIndex: "DOB"
    },
    {
      title: "Ethnicity",
      dataIndex: "Ethnicity"
    },
    {
      title: 'HN',
      dataIndex: "HN"
    }
  ]

  useEffect(() => {
    getPatientData();
  }, [])
  return (
    <>
      <div className="min-h-screen">
        <Modal open={isUpdateName} footer={null} onCancel={() => {
          setIsUpdateName(false);
          setPatientToUpdate(undefined);
          setNewName('')
        }}>
          <div className="flex flex-col gap-5 pb-5">
            <div>
              <div className="text-2xl font-bold">Update name for patient {patientToUpdate?.ID} </div>
            </div>
            <div className="text-xl">Original Name: { patientToUpdate?.Name}</div>
            <div className="flex flex-row gap-2">
              <Input className="w-60" value={newName} onChange={(event) => setNewName(event.target.value)} />
              <Button type="primary" onClick={updatePatientName}>OK</Button>
              <Button onClick={() => {
                setIsUpdateName(false)
                setPatientToUpdate(undefined);
                setNewName('')
              }}>Cancel</Button>
            </div>
          </div>
        </Modal>
      <div className="flex justify-center py-10">
        <div className="h-full w-4/5">
          {patientList.length > 0 && <Table dataSource={patientList} columns={columns}/>}
        </div>
        </div>
      </div>
    </>
  )
}

export default HomePage

现在访问 http://localhost:3000, 可见如下效果: image

项目的Github存储库: https://github.com/xili44/iris-react-integration

感谢 Bryan (@Bryan Hoon), Julian(@Julian Petrescu) 和 Martyn (@Martyn Lee),感谢新加坡办事处提供的支持和专业知识。

0
0 197
文章 Jingwei Wang · 六月 23, 2024 8m read

低代码挑战

想象一下那个场景。您正在 Widgets Direct 愉快地工作,这是互联网上首屈一指的小部件和小部件配件零售商。您的老板有一些毁灭性的消息,一些客户可能对他们的小部件不太满意,我们需要一个帮助台应用程序来跟踪这些投诉。为了让事情变得有趣,他希望代码占用非常小,并挑战您使用 InterSystems IRIS 以少于 150 行代码交付应用程序。这可能吗?

免责声明:本文记录了一个非常基本的应用程序的构建,为了简洁起见,省略了安全性和错误处理等细节。该应用程序仅供参考,不得用于任何生产应用。本文使用IRIS 2023.1作为数据平台,并非所描述的所有功能在早期版本中都可用

第 1 步 - 定义数据模型

我们首先定义一个新的干净的命名空间 - 带有代码和数据数据库。虽然所有内容都可以位于 1 个数据库中,但将它们拆分以便于数据刷新。

我们的帮助台系统需要 3 个基本类:一个 Ticket 对象,它可以包含用于记录员工顾问 UserAccount 和客户联系人 UserAccount 之间交互的操作。让我们用一些基本属性来定义它们:

0
0 127
文章 Kelly Huang · 九月 3, 2023 7m read

对于即将到来的Python 竞赛,我想制作一个小型演示,介绍如何使用 Python 创建一个简单的 REST 应用程序,该应用程序将使用 IRIS 作为数据库。使用这个工具

  • FastAPI框架,高性能,易学,快速编码,可用于生产
  • SQLAlchemy 是 Python SQL 工具包和对象关系映射器,为应用程序开发人员提供 SQL 的全部功能和灵活性
  • Alembic 是一个轻量级数据库迁移工具,可与 SQLAlchemy Database Toolkit for Python 一起使用。
  • Uvicorn 是 Python 的 ASGI Web 服务器实现。
0
0 153
文章 Jingwei Wang · 九月 1, 2023 2m read

JWT Authentication 原理及验证流程

原理

JWT 是一种结构紧凑、URL 安全的身份验证、授权或信息交换方式。在身份验证的情况下,服务器会向已通过身份验证的客户端提供一个 JWT,这样客户端在 JWT 过期之前就无需再提供密码来访问服务器上受保护的资源。

验证流程:

  1. 客户端发送Login到服务端
  2. 服务端返回 JWT给客户端
  3. 客户端校验JWT签名
  4. 客户端发送带有JWT签名的request到服务端
  5. 服务端检查JWT签名的有效期,在有效期内,则返回response给客户端,不在有效期内,返回error

JWT 配置步骤

  1. 创建REST服务
  2. 配置Web Application
  3. 安全配置
  4. 客户端发送Login,从服务器获取JWT
  5. 配置成功,发送带有JWT的request

1. 创建REST服务

在InterSystems IRIS中,可以使用/api/mgmnt自动创建REST的 .disp .impl 和 .spec 类,本篇文章不介绍具体创建REST服务的流程,具体内容请参考社区文章创建REST 服务

2. 配置Web Application

IRIS管理门户:系统管理 -> 安全 -> 应用程序 -> Web 应用程序

0
0 238
文章 Kelly Huang · 七月 12, 2023 4m read

在本文中,我将分享我们在 2023 年全球峰会技术交流室中提出的主题。我和@Rochael Ribeiro  

借此机会,我们就以下话题进行探讨:

  • 用于快速 API 的开放交换工具
  • 开放API规范
  • 传统与快速 Api 开发
  • 复合 API(互操作性)
  • 规范优先或 API 优先方法
  • API 治理和监控
  • 演示(视频)

用于快速 API 的开放交换工具

当我们谈论快速现代 API 开发(Rest / json)时,我们将使用两个 Intersystems Open Exchange 工具:

第一个是用于快速开发 API 的框架,我们将在本文中详细介绍。

https://openexchange.intersystems.com/package/IRIS-apiPub

第二种是使用 Swagger 作为用户界面,用于 IRIS 平台上开发的 Rest API 的规范和文档,以及它们的使用/执行。其运行的基础是开放 API 规范 (OAS) 标准,如下所述:

https://openexchange.intersystems.com/package/iris-web-swagger-ui

 

什么是开放 API 规范 (OAS)?

它是全球范围内用于定义、记录和使用 API 的标准。在大多数情况下,API 甚至在实现之前就已经设计好了。我将在下一个主题中详细讨论它。

0
0 139
文章 Kelly Huang · 七月 12, 2023 4m read

FHIR 通过提供标准化数据模型来构建医疗保健应用程序并促进不同医疗保健系统之间的数据交换,彻底改变了医疗保健行业。由于 FHIR 标准基于现代 API 驱动的方法,因此移动和 Web 开发人员更容易使用它。然而,与 FHIR API 交互仍然具有挑战性,尤其是在使用自然语言查询数据时。

隆重推出FHIR - AI 和 OpenAPI 链应用程序,该解决方案允许用户使用自然语言查询与 FHIR API 进行交互。该应用程序使用OpenAILangChainStreamlit构建,简化了查询 FHIR API 的过程并使其更加用户友好。

 

FHIR OpenAPI 规范是什么?

OpenAPI 规范(以前称为 Swagger,目前是OpenAPI Initiative的一部分)已成为软件开发领域的重要工具,使开发人员能够更有效地设计、记录 API 并与 API 交互。 OpenAPI 规范定义了一种标准的机器可读格式来描述 RESTful API,提供了一种清晰一致的方式来理解其功能并有效地使用它们。

在医疗保健领域,FHIR 成为数据交换和互操作性的领先标准。为了增强FHIR的互操作能力, HL7正式记录了FHIR OpenAPI规范,使开发人员能够将FHIR资源和操作无缝集成到他们的软件解决方案中。

 

FHIR OpenAPI 规范的优点:

0
0 395
文章 Michael Lei · 六月 20, 2023 5m read

这是在 Ensemble 中实现“微服务”设计的初学者指南。 “微服务”是当今流行的一个词,具有广泛的解释。我的解释是:“微服务”是一种“NoSQL 服务”。一个什么?答案在文章中。

我们了解了 SQL 和 NoSQL 数据库之间的区别。对我来说,SOA Web 服务和“微服务”之间的区别几乎相同。我将通过一个例子来解释它。

请注意,虽然这是一本初学者指南,但我假定我对数据建模、RESTful 服务和 Ensemble 有深入的技术知识。

航班预订——示例

我的例子很简单。我想为我的家人订一张机票。我使用www.skyscanner.hu ,但它可以是任何预订网站。那我该怎么办?在着陆页上,我输入了航班信息:我需要从布达佩斯到布拉格并返回的机票,10 月29日起飞,11 月 1返回,直飞航班,经济舱四人。提交搜索表单后,我会返回可用选项。我选择一个并输入乘客详细信息、折扣计划,最后通过 PayPal 付款。直截了当。

在更详细的版本中:后台发生了什么。

n 开始预订

n 输入选择条件

n 生成匹配航班列表

n 选择航班

n 临时封号

n 输入乘客详细信息

n 根据标价应用一些折扣程序计算机票

n 切换到 PayPal 支付

n 完成预订,释放临时块

当任务是使用 SOAP Web 服务开发后端时,最常见的架构如下:

n 将有支持预订的 SOAP 服务。假设它称为 FlightBookingService。

0
0 162
文章 Kate Lau · 三月 17, 2023 1m read


添加凭据以登录 FHIR REST 接口 - 在这例子仅考虑基本身份验证

 

添加服务注册表 - 在这例子仅考虑基本身份验证

- 设置 HTTP 服务

- 输入 FHIR 服务器的路径

- 输入 FHIR 服务的 URL

- 使用配置的凭证

 


添加 "HS.FHIRServer.Interop.HTTPOperation"

选择服务名称

测试 FHIR 客户端

跟踪测试结果

1
0 142
文章 Tete Zhang · 二月 20, 2023 11m read

开发者您好!

这里向介绍@Lorenzo ScaleseOpenAPI-Suite (一个用于从OpenAPI 3.0生成 ObjectScript 代码的工具集)。这个工具集在 2023 年 InterSystems 开发工具大赛的21 个参赛作品中获得专家提名第三名

目前 IRIS 最高支持OpenAPI 2.0 ,但是这个工具支持 OpenAPI 3.0

提供的功能如下。

  1. 在服务器端创建类(与 OpenAPI 2.0相同,首先创建使用 API First理念创建的 REST 调度类所需的类。)
  2. 创建客户端 HTTP 类
  3. 创建客户端Production(业务服务、业务流程、业务操作、Ens.Request、Ens.Response)
  4. 一个 Web 界面,允许您指定要从此工具生成哪些功能
  5. 从 OpenAPI 1.x、2.x 到 3.0 版的转换工具

关于各个功能的详细介绍,请参考@Lorenzo Scales撰写的文章《 OpenAPI Suite - Part 1 》和《 OpenAPI Suite - Part 2 》。

在本文中,我尝试了 1 个功能。其中,以下的应对方案非常好。

0
1 345
文章 Michael Lei · 十二月 7, 2022 11m read

Intersystems IRIS for Health 对 FHIR 行业标准提供了出色的支持。主要特点是:
1.FHIR 服务器
2. FHIR数据库
3. REST 和 ObjectScript API 用于 FHIR 资源(患者、问卷、疫苗等)的 CRUD 操作

本文演示了如何使用这些功能,并展示了用于创建和查看表单类型的 FHIR 资源的Angula前端。

第 1 步 - 使用 InterSystems IRIS for Health 部署您的 FHIR 服务器

要创建 FHIR 服务器,您必须将以下说明添加到 iris.script 文件中(来自:https://openexchange.intersystems.com/package/iris-fhir-template

0
0 156
文章 Tete Zhang · 十月 26, 2022 3m read

“池大小”(PoolSize)设置的值决定了一个组件的作业的量和启动方式。在这篇文章中我们将具体讨论对于不同类型的组件来说“池大小”设置的可能值和这些值所代表的含义。

Pool Size = 1

对于所有的组件来说,运行池大小为1的含义都是一样的: 该组件有且只有一个作业,单独运行该组件的代码,顺序处理发送到该组件的消息(FIFO)。

Pool Size > 1

对于业务进程(BP)和业务操作(BO)来说,当运行池大小大于1时,该组件将运行多个作业(作业数=运行池大小设置数)。每个作业都只运行该组件的代码,但消息处理的顺序将被打乱。将运行池的大小设为大于1的值可以在一定程度上提升组件处理消息的性能,但是每个作业的性能还是受限于系统资源的,所以并不是说组件的性能可以随着运行池的大小增加而无限提升。

对于轮询类业务服务(Polling BS)来说,当运行池大小大于1时,该服务也将运行多个作业(作业数=运行池大小设置数)。但这种配置会导致多个进程对轮询结果产生竞争(race condition),所以一般情况下轮询服务不应将运行池大小设为大于1的数值。

1
0 285
文章 Nicky Zhu · 十月 10, 2022 4m read

在生产环境中IRIS通常以故障转移集群的形态被部署,而集群中各故障转移成员的镜像状态将决定该集群在故障发生时是否能够顺利切换保障业务不中断。因此,成员状态通常也是运维团队需要巡检或监控的目标。

尽管IRIS内部API提供了丰富的集群配置、成员状态监控等一系列接口,但除Portal上的镜像监视器外,并没有特定的接口便于从外部系统访问(如进行企业级监控集成时),也没有整合好的监控接口可用与获取镜像的健康状态。但在IRIS上开发一个REST接口暴露镜像状态数据并不困难,如下所示:

0
0 255
文章 王喆 👀 · 九月 18, 2022 4m read

       这是一篇笔记:

说明

       Restful是一种基于Http的网络应用程序的设计风格和开发方式,可以使用xml格式或者Json格式定义。

RESTFUL特点包括:

1、每一个URI代表1种资源;

2、客户端使用GETPOSTPUTDELETE4个表示操作方式的动词对服务端资源进行操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源;

3、通过操作资源的表现形式来操作资源;

4、资源的表现形式是XML或者HTML

5、客户端与服务端之间的交互在请求之间是无状态的,从客户端到服务端的每个请求都必须包含理解请求所必需的信息。

IRIS中实现

GET

0
0 244
文章 Michael Lei · 九月 15, 2022 4m read

关于微服务架构(MSA)的IRIS定位的初学者指南。MSA在企业级Java世界中的能见度越来越高,因此,了解这股热潮背后的内容是至关重要的。我尝试着写下我的观点并与大家分享。

背景

首先,我必须承认。今年初夏,我的同事要求我收集一些关于匈牙利开发的医疗产品的信息。当我从相关公司得到反馈时,发现该产品是一个模块化系统,基于微服务架构(MSA)。好的。什么是MSA?在网上做了简短的研究,阅读了一些WIKI网页后,我得出结论:啊哈,又是一个 "架构"。我们可以用IRIS在 "架构层面 "遵守 "任何架构"--至少 "在某种程度上"。但也有一些恼人的地方。这让我对MSA有了更多的了解。到目前为止还不错,但是REST不是这篇文章的主要话题吗?MSA和REST之间的关系是什么?我访问的几乎每个网站都在例子中使用了RESTful网络服务。这让我有点怀疑。但总的来说,我赞同对MSA的一般总结:它是SOAP但做得很好。特别是因为有一些关于 "内聚 "和 "耦合 "的句子,我完全不明白。那么,如果MSA只是 "SOAP做得好",为什么我没有看到SOAP的例子?为什么这些例子(几乎)都是RESTful?

0
0 339
文章 Michael Lei · 九月 12, 2022 1m read

Hi 我在线部署了一个demo演示:

https://production-monitor.demo.community.intersystems.com/csp/user/EnsPortal.ProductionConfig.zen?PRODUCTION=dc.Demo.Production#

我更新了几个设置(文件路径和URL),并将调度类切换到dc.rest.GenericService。

我从文件服务重新发送了消息。我看到授权Auth和API服务都收到了消息。

API进程(还)没有返回所需的响应。更多内容请继续关注...

0
0 136
文章 姚 鑫 · 八月 13, 2022 2m read

第二十六章 源代码文件 REST API 参考(八)

GetEnsClassType

此方法返回用于创建产品的类的名称列表。可以指定要获取的类的类型,例如业务服务类。

URL

GET http://server:port/api/atelier/v1/namespace/ens/classes/type

type 是一个整数,并返回对应于该整数的类,如下所示:

  • Adapters 1

  • InboundAdapters 2

  • OutboundAdapters 3

  • Messages 4

  • Requests 5

  • Responses 6

  • BusinessServices 7

  • BusinessProcesses 8

  • BusinessOperations 9

  • DataTransformation 10

  • Production 11

  • BusinessHost 12

  • Dashboard 13

  • Rule 14

JSON Messages

以下返回的内容是一个类名数组:

{
  status: {
    errors: []
    summary: ""
  }
  console: []
  result: {
    content: [
        "Ens.Enterprise.MsgBank.BankTCPAdapter",
        "Ens.Enterprise.MsgBank.ClientTCPAdapter",
        "Ens.InboundAdapter",
        "Ens.OutboundAdapter"
    ]
  }
}

HTTP 返回码

  • HTTP 200 如果正常。
  • HTTP 500 如果发生意外错误(详细信息将在状态错误数组中)。

GetAdpInputOutputClass

此方法返回指定生产适配器的输入和输出类型。

URL

GET http://server:port/api/atelier/v1/namespace/ens/adapter/name

JSON Messages

以下是返回内容的示例:

{
  status: {
    errors: []
    summary: ""
  }
  console: []
  result: {
    content: {
      input: "%Stream.Object"
      output: "%String"
    }
  }
}

HTTP 返回码

  • HTTP 200 如果正常。
  • 如果适配器不存在,则为 HTTP 404
  • HTTP 500 如果发生意外错误(详细信息将在状态错误数组中)。
0
0 233
文章 姚 鑫 · 八月 12, 2022 3m read

第二十五章 源代码文件 REST API 参考(七)

Query

此方法对 IRIS 表执行 SQL 查询并返回结果。请求正文是指定查询的 JSON 对象。它返回一个匹配查询条件的对象数组。每个返回的对象都包含与查询返回的一行相关的信息。

URL

POST http://server:port/api/atelier/v1/namespace/action/query

SQL 查询在 URL 请求的正文中指定。查询必须在指定的命名空间中指定一个数据库。

此调用需要标头 Content-Type application/json。

JSON Messages

返回内容是一个对象数组。错误将出现在每个源代码文件对象的状态属性中:

{
  "status": {
    "errors": [],
    "summary": ""
  },
  "console": [],
  "result": {
    "content": [
      {
        "ID": "%all",
        "Description": "The Super-User Role"
      },
      {
        "ID": "%db_%default",
        "Description": "R/W access for this resource"
      },
      {
        "ID": "%db_irislocaldata",
        "Description": "R/W access for this resource"
      },
      ...
      {
        "ID": "%sqltunetable",
        "Description": "Role for use by tunetable to sample tables irrespective of row level security"
      }
    ]
  }
}

HTTP 返回码

  • HTTP 200 如果正常。
  • 如果传递的内容类型不是 application/json,则 HTTP 415
  • HTTP 500 如果发生意外错误(详细信息将在状态错误数组中)。

Search

此方法在 IRIS 数据库中查找具有指定内容的文件。 Search 方法在 API 的第 2 版中可用。此方法以旨在向用户显示的格式返回搜索结果。

URL

POST http://server:port/api/atelier/v2/namespace/action/search

URL Parameters

  • 必需的 URL 参数 ?query=expression 指定要在指定文件中搜索的正则表达式或文本字符串。
  • 必需的 URL 参数 ?files=file-list 提供以逗号分隔的文件或文件掩码列表,例如 al*.mac,以搜索指定的表达式。
  • 可选的 URL 参数 ?regex=1 指定查询 URL 参数包含正则表达式并且是默认值。 ?regexp=0 指定查询包含文本字符串,不应被解释为正则表达式。
  • 可选的 URL 参数 ?sys=1 指定在搜索中包括系统文件。默认值为 ?sys=0,不包括系统文件。
  • 可选的 URL 参数 ?gen=1 指定在搜索中包含生成的文件。默认值为 ?gen=0,它不包括生成的文件。
  • 可选的 URL 参数 ?max=integer 指定要返回的最大结果数。默认值为 ?max=200

JSON Messages

以下搜索 REST 调用在所有 .cls.mac 文件中搜索单词“Email”,前面和后面都有一个空格。 (在正则表达式中,\s 由空格字符匹配。)

GET localhost:52773/api/atelier/v2/SAMPLES/action/search?query=.*\sEmail\s.*&files=*.cls,*.mac

此调用返回以下消息。返回消息可能因 SAMPLES 命名空间的内容而异。

{
    "status": {
        "errors": [],
        "summary": ""
    },
    "console": [
        "",
        "Searching for '.*\\sEmail\\s.*' in '*.cls,*.mac'",
        "Wasabi.Data.Employee.cls(Email): Property Email ",
        "Wasabi.Person.API.Employee.cls(Email): Property Email ",
        "ZAUTHENTICATE.mac(175): Properties(\"EmailAddress\") - Email address",
        "Found 3 occurrence/s in 3 file/s."
    ],
    "result": [
        {
            "doc": "Wasabi.Data.Employee.cls",
            "matches": [
                {
                    "member": "Email",
                    "text": "Property Email "
                }
            ]
        },
        {
            "doc": "Wasabi.Person.API.Employee.cls",
            "matches": [
                {
                    "member": "Email",
                    "text": "Property Email "
                }
            ]
        },
        {
            "doc": "ZAUTHENTICATE.mac",
            "matches": [
                {
                    "line": "175",
                    "text": "Properties(\"EmailAddress\") - Email address"
                }
            ]
        }
    ]
}

HTTP 返回码

  • 如果请求有效,则为 HTTP 200
  • 如果缺少必需的 URL 参数,则为 HTTP 400
0
0 192
文章 姚 鑫 · 八月 11, 2022 4m read

第二十四章 源代码文件 REST API 参考(六)

Compile

此方法编译源代码文件。它允许一次编译多个源代码文件。它返回一个对应源代码文件对象的数组。

要编译的文件列表作为 JSON 数组在 http 请求的正文中传递。例如,[ "%Api.DocDB.cls", ... ]

有关示例和其他详细信息,请参阅本手册教程章节中的编译文件。

URL

POST http://server:port/api/atelier/v1/namespace/action/compile

此调用需要标头 Content-Type application/json

URL Parameters

  • 可以传递 URL 参数“flags”(默认为“cuk”),该参数将传递给编译器。

  • 如果不希望返回已编译的源代码文件的源,则可以使用值 0 传递 URL 参数 'source'

JSON Messages

以下是编译 Atelier.NewClass1 时返回的内容:

{
  "status": {
    "errors": [],
    "summary": ""
  },
  "console": [
    "Compilation started on 01/12/2016 17:44:00 with qualifiers 'cuk'",
    "Compiling class Atelier.NewClass1",
    "Compiling table Atelier.NewClass1",
    "Compiling routine Atelier.NewClass1.1",
    "Compilation finished successfully in 0.067s.",
    ""
  ],
  "result": {
    "content": [
      {
        "name": "Atelier.NewClass1.cls",
        "status": "",
        "content": [
          "Storage Default",
          "{",
          "<Data name=\"NewClass1DefaultData\">",
          "<Value name=\"1\">",
          "<Value>%%CLASSNAME</Value>",
          "</Value>",
          "</Data>",
          "<DataLocation>^Atelier.NewClass1D</DataLocation>",
          "<DefaultData>NewClass1DefaultData</DefaultData>",
          "<IdLocation>^Atelier.NewClass1D</IdLocation>",
          "<IndexLocation>^Atelier.NewClass1I</IndexLocation>",
          "<StreamLocation>^Atelier.NewClass1S</StreamLocation>",
          "<Type>%Storage.Persistent</Type>",
          "}",
          ""
        ],
        "db": "IRISSYS",
        "ts": "2016-01-12 17:44:00.053",
        "enc": false,
        "flags": 1
      }
    ]
  }
}

与源代码文件有关的错误将出现在每个源代码文件对象的状态属性中。

如果编译持久类导致存储定义更改,则存储定义作为源代码文件对象的内容返回。否则结果内容将为空。

HTTP Return Codes

  • HTTP 200 如果正常。
  • 如果资源名称是无效的源代码文件名,则返回 HTTP 400
  • 如果找不到资源,则返回 HTTP 404
  • 如果源代码文件被锁定,HTTP 423
  • HTTP 500 如果发生意外错误(详细信息将在状态错误数组中)。

Index

此方法返回指定源代码文件的摘要信息。应用程序可以使用此信息来创建源代码文件的索引。它返回一个索引源代码文件对象数组。

要索引的源代码文件列表在 http 请求的正文中传递。请求正文是源代码文件名称的 JSON 数组。例如,[ "%Api.DocDB.cls", ... ]

URL

POST http://server:port/api/atelier/v1/namespace/action/index

此调用需要标头 Content-Type application/json

JSON Messages

与源代码文件有关的错误位于每个源代码文件对象的状态属性中。返回的数组包含与服务器上源代码文件的结构和文档相关的信息。它会因源代码文件所属的类别而异。以下是一个类(类别 CLS)的示例。 (目前我们只支持类的索引。):

{
  "status": {
    "errors": [],
    "summary": ""
  },
  "console": [],
  "result": {
    "content": [
      {
        "name": "%Activate.GenericObject.cls",
        "db": "IRISLIB",
        "ts": "2016-01-04 14:00:04.000",
        "gen": false,
        "others": [
          "%Activate.GenericObject.1.INT"
        ],
        "cat": "CLS",
        "content": {
          "desc": "This class provides functionality to create an ActiveX object, invoke its methods and Get/Set its properties by name.",
          "depl": false,
          "depr": false,
          "final": false,
          "hidden": false,
          "super": [
            "%Activate.IDispatch"
          ],
          "methods": [
            {
              "name": "CreateObject",
              "desc": "This method is used to create a generic object given only its progid. If the object cannot be found an exception is thrown. 
                       The return value should be tested against $$$NULLOREF  in the usual manner to ensure that the object has been successfully created",
              "depr": false,
              "final": true,
              "internal": false,
              "private": false,
              "scope": "class",
              "returntype": "%Library.RegisteredObject",
              "args": [
                {
                  "name": "Progid",
                  "type": "%Library.String"
                }
              ]
            },
            {
              "name": "GetObject",
              "desc": "This method is used to create a generic object from a moniker. If the object cannot be found an exception is thrown. 
                       The return value should be tested against $$$NULLOREF  in the usual manner to ensure that the object has been successfully created.",
              "depr": false,
              "final": true,
              "internal": false,
              "private": false,
              "scope": "class",
              "returntype": "%Library.RegisteredObject",
              "args": [
                {
                  "name": "Moniker",
                  "type": "%Library.String"
                }
              ]
            }
          ],
          "parameters": [],
          "properties": []
        },
        "status": ""
      }
    ]
  }
}

HTTP 返回码

  • HTTP 200 如果正常。
  • 如果传递的内容类型不是 application/json,则 HTTP 415
  • HTTP 500 如果发生意外错误(详细信息将在状态错误数组中)。
0
0 210
文章 Muhammad Waseem · 八月 11, 2022 2m read

嗨社区,

这篇文章公开介绍我的 iris-fhir-client 客户端应用。

 iris-fhir-client 可以可以借助嵌入式 python 连接到任何开放的 FHIR 服务器 fhirpy 图书馆.

通过终端和使用 CSP Web 应用程序获取资源信息。

0
0 200
文章 姚 鑫 · 八月 10, 2022 4m read

第二十三章 源代码文件 REST API 参考(五)

DeleteDoc

此方法删除指定命名空间中的命名源代码文件。它返回相应的源代码文件对象。

与源代码文件有关的错误将在源代码文件对象的状态属性中。

有关示例和其他详细信息,请参阅本手册教程章节中的删除文件。

URL

DELETE http://server:port/api/atelier/v1/namespace/doc/doc-name

注意:如果要删除 CSP 文件 ,则 doc-name 的值包括 /(斜杠)字符。这就是定义 DeleteDocURLMap 包含此参数名称的 (.*) 而不是 :docname 的原因。有关详细信息,请参阅创建 REST 服务中的“为 REST 创建 URL 映射”。

JSON Messages

以下是源代码文件 xyz.macDELETE 的返回内容:

{
  "status": {
    "errors": [],
    "summary": ""
  },
  "console": [],
  "result": {
    "name": "xyz.mac",
    "db": "INVENTORYR",
    "ts": "",
    "cat": "RTN",
    "status": "",
    "enc": false,
    "flags": 0,
    "content": []
  }
}

HTTP 返回码

  • HTTP 200 如果正常。
  • 如果命名资源不是有效的源代码文件名,则返回 HTTP 400
  • 如果源代码文件不存在,则返回 HTTP 404
  • 如果资源被锁定,HTTP 423
  • HTTP 500 如果发生意外错误(详细信息将在状态错误数组中)。

HeadDoc

此方法返回命名源代码文件和命名空间的 HttpHeader。此标头包含一个时间戳,可用于检测服务器和客户端版本之间的差异。

URL

HEAD http://server:port/api/atelier/v1/namespace/doc/doc-name

注意:如果正在获取 CSP 文件的 HTTP 标头,则 doc-name 的值包括 /(斜杠)字符。这就是定义 HeadDocURLMap 包含此参数名称的 (.*) 而不是 :docname 的原因。有关详细信息,请参阅创建 REST 服务中的“为 REST 创建 URL 映射”

HTTP 返回码

  • HTTP 200 如果正常。
  • 如果资源名称是无效的源代码文件名,则返回 HTTP 400
  • 如果找不到资源,则返回 HTTP 404
  • HTTP 500 如果发生意外错误(详细信息将在状态错误数组中)。

GetDocs

此方法返回命名空间中所有指定源代码文件的文本。

URL

POST http://server:port/api/atelier/v1/namespace/docs

要获取的源代码文件列表在 http 请求的正文中传递。请求正文是要获取的源代码文件名称的 JSON 数组。例如,[ "%Api.DocDB.cls", ... ]

此调用需要标头 Content-Type application/json

JSON Messages

返回内容是源代码文件对象的数组。有关源代码文件对象结构的示例,请参见 GetDoc 方法。

与源代码文件有关的错误将出现在每个源代码文件对象的状态属性中。此方法不支持 storageOnly 标志。它也不进行 ETAG 检查(因此在任何情况下都不会返回 HTTP 304)。

HTTP 返回码

  • HTTP 200 如果正常。
  • 如果传递的内容类型不是 application/json,则 HTTP 415
  • HTTP 500 如果发生意外错误(详细信息将在状态错误数组中)。

DeleteDocs

此方法删除命名源代码文件的列表。它返回相应的源代码文件对象数组。

URL

DELETE http://server:port/api/atelier/v1/namespace/docs

要删除的文件列表作为 JSON 数组在 http 请求的正文中传递。例如,[ "%Api.DocDB.cls", ... ]

此调用需要标头 Content-Type application/json

JSON Messages

以下是源代码文件 xyz.mac 和不存在的类 noteexist.clsDELETE 的返回内容:

{
  "status": {
    "errors": [],
    "summary": ""
  },
  "console": [
  ],
  "result": [
    {
      "name": "xyz.mac",
      "db": "INVENTORYR",
      "status": ""
    },
    {
      "name": "notexist.cls",
      "db": "",
      "status": "ERROR #5001: Document Does Not Exist: User.notexist.cls [zExistsDoc+3^%Atelier.v1.Utils.General.1:%SYS]"
    }
  ]
}

与每个源代码文件有关的错误将在每个返回的源代码文件对象的状态属性中。如果状态为空字符串,则源代码文件已成功删除。否则源代码文件不会被删除。

对于已删除的源代码文件,db 属性将指示文档是从哪个数据库中删除的。

HTTP 返回码

  • HTTP 200 如果正常。
  • 如果发布的数据不包含 JSON 数组,则为 HTTP 400
  • 如果传递的内容类型不是 application/json,则 HTTP 415
  • HTTP 500 如果发生意外错误(详细信息将在状态错误数组中)。
0
0 274
文章 Michael Lei · 八月 9, 2022 23m read

在这篇文章中,你可以访问InterSystems开发者社区中与学习InterSystems IRIS最相关主题的文章库。找到按机器学习、嵌入式Python、JSON、API和REST应用、管理和配置InterSystems环境、Docker和云、VSCode、SQL、分析/BI、全局、安全、DevOps、互操作性、Native API排列的顶级发表的文章。快来享受学习的乐趣吧!

机器学习

机器学习是建立先进的数据分析和自动化人工活动的一种必要的技术,具有很好的效率。它可以创建认知模型,从现有的数据中学习,并根据其自我调整的算法进行预测、概率计算、分类、识别和 "非创造性 "的人类活动的自动化。

在所有情况下,InterSystems IRIS作为一个数据平台和环境来创建、执行、提供和使用这些机器学习模型。IRIS能够从SQL命令(IntegratedML)中使用ML,使用嵌入式Python和PMML(预测模型标记语言)来执行ML。你可以在以下文章中查看它的功能:

1
0 290
文章 姚 鑫 · 八月 8, 2022 3m read

第二十一章 源代码文件 REST API 参考(三)

GetDocNames

此方法返回源代码文件名列表。可选的 cattype 约束源代码文件的类型。

URL

GET http://server:port/api/atelier/v1/namespace/docnames

GET http://server:port/api/atelier/v1/namespace/docnames/cat

GET http://server:port/api/atelier/v1/namespace/docnames/cat/type

其中

  • cat 指定类别代码:CLS = class; RTN = routineCSP = CSP 文件OTH = other。默认为 *
  • type 指定源代码文件类型。可以是 * 通配符或文件类型。对于 CLS,类型必须是 *。对于 RTN,类型可以是 mac、int、inc、bas 、mvi 或 mvb。对于 CSPtype 可以是 jscss 等文件类型的列表,以逗号分隔。默认为 *

URL Parameters

  • URL 参数 'generated=1' 指定应包含生成的源代码文件。
  • URL 参数 'filter' 提供了一个可用于匹配名称的 SQL 过滤器。

JSON Messages

以下是返回的内容,源代码文件描述符数组:

{
  "status": {
    "errors": [],
    "summary": ""
  },
  "console": [],
  "result": {
    "content": [
      {
        "name": "%Api.DocDB.cls",
        "cat": "CLS",
        "ts": "2016-08-03 20:01:42.000",
        "upd": true,
        "db": "IRISLIB",
        "gen": false
      },
      ...
      {
        "name": "EnsProfile.mac",
        "cat": "RTN",
        "ts": "2003-09-19 13:53:31.000",
        "upd": true,
        "db": "INVENTORYR",
        "gen": false
      },
      ...
      {
        "name": "xyz.mac",
        "cat": "RTN",
        "ts": "2016-08-11 15:05:02.167",
        "upd": false,
        "db": "INVENTORYR",
        "gen": false
      }
    ]
  }
}

HTTP 返回码

  • HTTP 200 如果正常。
  • HTTP 500 如果发生意外错误(详细信息将在状态错误数组中)。

GetModifiedDocNames

此方法返回自数据库具有指定哈希值以来已修改的源代码文件列表。它以 JSON 数组的形式传递数据库键和哈希列表。哈希值用于确定该键定义的数据库中是否有任何更改。通常,首先使用一个空数组调用此 API 作为传入的 JSON 消息。这将返回命名空间中所有源代码文件的名称以及每个文件的数据库键和哈希。然后可以发布 dbnamedbhash 以发现自上次调用以来在服务器上修改了哪些源代码文件。

发布要检查的源代码文件列表,如以下示例所示:

[ { "dbname" : "USER",
    "dbhash" : "KWAGbOdnRblPzANaiv1Oiu0BZLI" 
}, ... ]

URL

POST http://server:port/api/atelier/v1/namespace/modified/type

其中:

  • type - 将源代码文件类型指定为 * 或三字母代码、ls、mac、int、inc、bas 或 mvi。默认为 *。 此调用需要标头 Content-Type application/json

JSON Messages

以下是返回的内容,源代码文件描述符数组:

[ { "dbname" : "USER", 
    "dbhash" : "Qx1zuNaulq3b_1yR9ahZAfjkc-",
    "crhash" : "47763751EC",
    "docs": [{
            "name": "User.NewClass1.cls",
            "ts": "2016-01-04 14:00:04.000",
            "gen": false,
            "depl": false
            }, ... ]
   }, ... ]

如果在指定的 dbhash 之后删除了源代码文件,则在列表中返回该文件,并将时间戳设置为空字符串:

"ts": ""

如果由于映射而包含数据库并且删除了映射,则 dbhashcrhash 都将返回“000”值,并且 docs 作为空数组返回。

HTTP 返回码

  • HTTP 200 如果正常。
  • 如果发布的内容为空或类型不是 CLS,则 HTTP 400
  • 如果内容类型不是应用程序/json,则为 HTTP 415
  • HTTP 500 如果发生意外错误(详细信息将在状态错误数组中)。
0
0 275
文章 Michael Lei · 八月 8, 2022 2m read

医疗行业的互操作性在改善病人护理、降低医疗服务提供者的成本以及为提供者提供更准确的情况方面发挥着重要作用。然而,由于有这么多不同的系统,数据的格式也有很多不同的方式。有许多标准被创造出来以试图解决这个问题,包括HL7v2、HL7v3和CDA,但每一种都有其缺点。

FHIR,即快速医疗互操作性资源,是一种新的医疗数据格式,旨在解决这些问题。它是由国际卫生级七组织(HL7)开发的,该组织还开发了HL7v2、HL7v3和CDA。

今天我们将探讨如何在VS代码中借助IntelliSense和自动完成功能,通过使用FHIR Schema 创建和验证FHIR资源。

第 1 步 :从FHIR 官方网站 https://www.hl7.org/fhir/下载 JSON schema file 文件用来做资源校验

第 2 步: 创建文件夹(在这个例子中,我使用病人文件夹和病人资源),并将提取的fhir.schema.json文件复制到同一文件夹,然后从VS Code中打开文件夹

第 3 步: 通过修改setting.json文件,设置VS代码以识别FHIR模式。
按CTRL+SHIFT+P并输入工作区设置JSON文件

第 4 步: 在同一文件夹中创建一个新文件patient.fhir.json。
按Ctrl+Space,你将通过IntelliSense获得FHIR资源的所有属性

0
0 475
文章 姚 鑫 · 八月 7, 2022 4m read

第二十章 源代码文件 REST API 参考(二)

GetMetaData

此方法返回命名数据库的 METADATA.zip 文件的二进制内容。 Atelier 使用此文件来存储索引信息,以便为将来的会话保留此信息。

URL

GET http://server:port/api/atelier/v1/%25SYS/metadata/database

注意:因为 %URL 特殊字符,所以要指定文字 %,必须在其后跟 25(百分号字符的十六进制代码)。因此,必须使用 %25SYS 来指定文字 %SYS

HTTP 返回码

  • HTTP 200 如果正常。
  • 如果源代码文件不存在,则返回 HTTP 404
  • HTTP 500 如果发生意外错误(详细信息将在状态错误数组中)。

GetCSPApps

此方法返回在服务器上定义或为服务器上指定命名空间定义的 Web 应用程序列表。

URL

GET http://server:port/api/atelier/v1/%25SYS/cspapps

GET http://server:port/api/atelier/v1/%25SYS/cspapps/namespace

其中:

namespace

指定命名空间的名称。如果未指定命名空间,则此方法返回所有命名空间的 Web 应用程序。

注意:因为 %URL 特殊字符,所以要指定文字 %,必须在其后跟 25(百分号字符的十六进制代码)。因此,必须使用 %25SYS 来指定文字 %SYS

URL Parameters

可以传递 URL 参数 ?detail=1 以返回包含更详细描述应用程序的对象的数组。

JSON Messages

以下返回的内容是一个列出已定义 Web 应用程序的数组:

{
  "status": {
    "errors": [],
    "summary": ""
  },
  "console": [],
  "result": {
    "content": [
      "/csp/broker",
      "/csp/documatic",
      "/csp/sys",
      "/csp/sys/exp",
      "/csp/sys/mgr",
      "/csp/sys/op",
      "/csp/sys/sec",
      "/isc/studio/rules",
      "/isc/studio/templates",
      "/isc/studio/usertemplates",
      "/csp/user"
    ]
  }
}

以下是 detail=1 的相同返回内容:

{
  "status": {
    "errors": [],
    "summary": ""
  },
  "console": [],
  "result": {
    "content": [
      {
        "name": "/csp/broker",
        "default": false
      },
      {
        "name": "/csp/documatic",
        "default": false
      },
      {
        "name": "/csp/sys",
        "default": true
      },
      {
        "name": "/csp/sys/exp",
        "default": false
      },
      {
        "name": "/csp/sys/mgr",
        "default": false
      },
      {
        "name": "/csp/sys/op",
        "default": false
      },
      {
        "name": "/csp/sys/sec",
        "default": false
      },
      {
        "name": "/isc/studio/rules",
        "default": false
      },
      {
        "name": "/isc/studio/templates",
        "default": false
      },
      {
        "name": "/isc/studio/usertemplates",
        "default": false
      },
      {
        "name": "/csp/user",
        "default": true
      }
    ]
  }
}

HTTP 返回码

  • HTTP 200 如果正常。
  • HTTP 500 如果发生意外错误(详细信息将在状态错误数组中)。

GetNamespace

此方法返回有关特定命名空间的信息。

URL

GET http://server:port/api/atelier/v1/namespace

JSON Messages

以下是命名空间USER的返回内容信息:

{
    "status": {
        "errors": [],
        "summary": ""
    },
    "console": [],
    "result": {
        "content": {
            "name": "USER",
            "db": [
                {
                    "name": "USER",
                    "crhash": "3A1A0E8B6C8",
                    "default": true,
                    "dbsys": false
                },
                {
                    "name": "IRISLIB",
                    "crhash": "A56AAA8D5418",
                    "default": false,
                    "dbsys": true
                },
                {
                    "name": "IRISLOCALDATA",
                    "crhash": "3A1A0551876",
                    "default": false,
                    "dbsys": false
                },
                {
                    "name": "IRISSYS",
                    "crhash": "3A19FFD2EF0",
                    "default": false,
                    "dbsys": true
                }
            ],
            "features": [
                {
                    "name": "ENSEMBLE",
                    "enabled": false
                }
            ]
        }
    }
}

HTTP 返回码

  • HTTP 200 如果正常。
  • HTTP 500 如果发生意外错误(详细信息将在状态错误数组中)。
0
0 350
文章 姚 鑫 · 八月 6, 2022 3m read

第十九章 源代码文件 REST API 参考(一)

源代码文件 REST 接口支持以下方法:

  • GetServer:返回有关服务器的信息。
  • HeadServer:返回服务器的 HttpHeader
  • GetJobs:返回正在运行的jobs列表。
  • GetMetaData:返回命名数据库的 METADATA.zip 文件的内容。
  • GetCSPApps:返回 Web 应用程序列表。
  • GetNamespace:返回有关特定命名空间的信息。
  • GetDocNames:返回源代码文件名列表。
  • GetModifiedDocNames:返回自数据库具有指定哈希值以来已修改的源代码文件列表。
  • PutDoc:保存提供的源代码文件。
  • GetDoc:返回指定源代码文件的文本。
  • DeleteDoc:删除命名的源代码文件。
  • HeadDoc:返回命名源代码文件的 HttpHeader
  • GetDocs:返回所有指定源代码文件的文本。
  • DeleteDocs:删除命名源代码文件列表。
  • Compile编译:编译您指定的源代码文件。
  • Index索引:返回有关指定源代码文件的摘要信息。
  • Query查询:对任何表执行 SQL 查询并返回结果。
  • Search搜索:在数据库中搜索源代码文件。
  • GetEnsClassType:返回用于创建作品的类的名称列表。可以指定要获取的类的类型,例如业务服务类。
  • GetAdpInputOutputClass:返回适配器的输入和输出类型。

GetServer

此方法返回有关服务器的信息,包括服务器上可用的 源代码文件 REST API 版本和名称空间。

URL

GET http://server:port/api/atelier/

JSON Messages

{
  "status": {
    "errors": [],
    "summary": ""
  },
  "console": [],
  "result": {
    "content": {
      "version": "IRIS for Windows (x86-64) 2018.1.1 (Build 515U) Mon Feb 5 2018 08:24:13 EST",
      "id": "98E1697E-13F9-4D6A-8B73-827873D1D61C",
      "api": 2,
      "features": [
...
      ],
      "namespaces": [
        "%SYS",
        "USER"
      ]
    }
    }
}

HTTP 返回码

  • HTTP 200 如果正常。
  • HTTP 500 如果发生意外错误(详细信息将在状态错误数组中)。

HeadServer Method

此方法返回服务器的 HttpHeader

URL

HEAD http://server:port/api/atelier/

JSON Messages

没有返回内容。

HTTP 返回码

  • HTTP 200 如果正常。
  • HTTP 500 如果发生意外错误(详细信息将在状态错误数组中)。

GetJobs

此方法返回实例上正在运行的作业列表。

URL

GET http://server:port/api/atelier/v1/%25SYS/jobs

注意:因为 %URL 特殊字符,所以要指定文字 %,必须在其后跟 25(百分号字符的十六进制代码)。因此,必须使用 %25SYS 来指定文字 %SYS

JSON Messages

以下返回的内容是作业描述符数组:

{
  "status": {
  "errors": [],
  "summary": ""
  },
  "console": [],
  "result": {
  "content": [
    {
    "pid": 1394,
    "namespace": "%SYS",
    "routine": "%Studio.Debugger.1",
    "state": "RUN",
    "device": "|TCP|1972|1394"
    },
    {
    "pid": 1345,
    "namespace": "%SYS",
    "routine": "RECEIVE",
    "state": "HANG",
    "device": "/dev/null"
    },
    {
    "pid": 1364,
    "namespace": "%SYS",
    "routine": "%SYS.TaskSuper.1",
    "state": "SELECTW",
    "device": "/dev/null"
    },
    {
    "pid": 1396,
    "namespace": "%SYS",
    "routine": "%SYS.cspServer3",
    "state": "READ",
    "device": "|TCP|1972|1396"
    },
    {
    "pid": 1346,
    "namespace": "%SYS",
    "routine": "ECPWork",
    "state": "RUNW",
    "device": "/dev/null"
    },
      {
        "pid": 1417,
        "namespace": "%SYS",
        "routine": "%SYS.BINDSRV",
        "state": "READ",
        "device": "|TCP|1972|1417"
      }
    ]
  }
}

HTTP 返回码

  • HTTP 200 如果正常。
  • HTTP 500 如果发生意外错误(详细信息将在状态错误数组中)。
0
0 324
文章 姚 鑫 · 八月 4, 2022 3m read

第十七章 源代码文件 REST API 教程(二)

获取在命名空间中定义的源代码文件

要获取有关命名空间中源代码文件的信息:

  • 首先,使用 GetDocNames 方法获取文件的名称。
  • 然后用GetDoc 方法获取一个文件的内容,也可以用GetDocs 方法获取多个文件的内容。
  • 如果要提高应用程序的网络效率,可以保留源代码文件的名称和内容的本地缓存,并使用 GetModifiedDocNames 方法仅获取内容发生变化的源代码文件的名称或使用带有 If-None-Match HTTP 标头的 GetDoc 方法。

GetDocNames 方法返回映射到命名空间的所有数据库中的所有源代码文件的名称。

{
  "status": {
    "errors": [],
    "summary": ""
  },
  "console": [],
  "result": {
    "content": [
      {
        "name": "%Api.DocDB.cls",
        "cat": "CLS",
        "ts": "2016-08-03 20:01:42.000",
        "upd": true,
        "db": "IRISLIB",
        "gen": false
      },
      ...
      {
        "name": "EnsProfile.mac",
        "cat": "RTN",
        "ts": "2003-09-19 13:53:31.000",
        "upd": true,
        "db": "INVENTORYR",
        "gen": false
      },
      ...
      {
        "name": "xyz.mac",
        "cat": "RTN",
        "ts": "2016-08-11 15:05:02.167",
        "upd": false,
        "db": "INVENTORYR",
        "gen": false
      }
    ]
  }
}

以下 GetDoc 调用返回 xyz.mac 文件的内容:

http://localhost:52773/api/atelier/v1/INVENTORY/doc/xyz.mac

此调用返回:

{
  "status": {
    "errors": [],
    "summary": ""
  },
  "console": [],
  "result": {
    "name": "xyz.mac",
    "db": "INVENTORYR",
    "ts": "2016-09-14 14:10:16.540",
    "upd": false,
    "cat": "RTN",
    "status": "",
    "enc": false,
    "flags": 0,
    "content": [
      "ROUTINE xyz",
      "xyz ;",
      "   w \"hello\""
    ]
  }
}

在命名空间中创建新文件或更新现有文件

要在命名空间中创建新文件或更新现有文件,请使用 PutDoc 方法。例如,以下 REST 调用在 INVENTORY 命名空间中创建一个新的 xyz.mac 源代码文件,或者,如果 xyz.mac 文件存在,则此调用将文件的原始定义替换为新定义。如果要更新新文件,则必须指定 HTTP 标头 If-None-Match 以标识文件的当前版本,或指定 ?ignoreConflict=1 URL 参数以绕过版本检查。有关详细信息,请参阅参考部分中的 PutDoc

PUT http://localhost:52773/api/atelier/v1/INVENTORY/doc/xyz.mac

应该指定 Content-Type application/json 和以下 JSON 消息:

{
 "enc": false,
 "content": [
   "ROUTINE xyz",
   "xyz ;",
   "   w \"hello\""
   ]
}

该调用返回以下 JSON 消息。它显示源代码文件已在 INVENTORYR 数据库中创建,该数据库是 INVENTORY 命名空间中例程的默认数据库。

{
  "status": {
    "errors": [],
    "summary": ""
  },
  "console": [],
  "result": {
    "name": "xyz.mac",
    "db": "INVENTORYR",
    "ts": "2016-09-14 14:10:16.540",
    "upd": false,
    "cat": "RTN",
    "status": "",
    "enc": false,
    "flags": 0,
    "content": []
  }
}

如果要更新或创建二进制文件,请为 enc 指定一个真值,并将二进制内容作为二进制值的 base64 编码的块数组包含在内。

0
0 108
文章 姚 鑫 · 八月 3, 2022 3m read

第十六章 源代码文件 REST API 教程(一)

本章提供了一个简短的教程,通过一系列示例演示如何使用源代码文件 REST API。它包含以下部分:

API 基础

Atelier 用于访问 IRIS 源代码文件的 API 使用 REST 架构风格。 REST 的名字来源于“Representational State Transfer”。与许多 REST API 一样 IRIS 源代码文件 REST API 使用 HTTP GETPOSTPUTDELETEHEAD 方法,并将 JSON 用于传入和传出消息体。

要调用 API 方法,需要了解以下内容:

  • HTTP 方法——它是以下之一:GETPOSTPUTDELETEHEAD
  • HTTP 标头——为调用提供上下文信息。此 API 中使用的 HEADERS 包括:
    • 授权,它提供对服务器的访问。除非安装了具有最低安全性的服务器,否则需要提供用户名和密码才能访问 API。
    • Content-Type application/json,指定入站负载以 JSON 格式提供。必须为所有 POSTPUT 方法指定此标头。
    • If-None-Match,它允许 GetDocPutDoc 调用检查源代码文件自上次访问以来是否被修改。
  • URL - URL 由以下部分组成:
    • http://
    • server-name:port-number/——在本章中,我们假设 IRIS 在本地服务器上运行并使用端口 52773
    • api/atelier/——这是由具有 %Api.Atelier 调度类的 Web 应用程序定义的。
    • 标识方法和目标的 URL 部分。此部分可以包含固定文本和您指定用于标识命名空间、文档名称或类型的文本。

例如,标识 GetDocNames 方法的 URL 部分是 v1/namespace/docnames/。此方法从 MYNS 命名空间获取文档的完整 URL 为:

ttp://localhost:52773/api/atelier/v1/MYNS/docnames

标识 GetServer 方法的 URL 部分是一个空字符串,因此 GetServer 的完整 URL 是:

http://localhost:52773/api/atelier/

  • URL 参数——修改调用。如果 API 方法有 URL 参数,它们会在参考部分中描述。
  • 入站 JSON 有效负载 — POSTPUT 方法的入站消息格式。
  • 出站 JSON 负载 — HTTP 方法返回的出站消息的格式。

获取有服务器的信息

通常,将进行的第一个 REST 调用是 GetServer 方法,该方法返回有关 IRIS 源代码文件 REST API 版本号和服务器上可用的命名空间的信息。

GET http://localhost:52773/api/atelier/

此调用返回以下 JSON 消息:

{
  "status": {
    "errors": [],
    "summary": ""
  },
  "console": [],
  "result": {
    "content": {
      "version": "IRIS for Windows (x86-64) 2018.1.1 (Build 515U) Mon Feb 5 2018 08:24:13 EST",
      "id": "98E1697E-13F9-4D6A-8B73-827873D1D61C",
      "api": 2,
      "features": [
...
      ],
      "namespaces": [
        "%SYS",
        "USER"
      ]
    }
    }
}

所有返回 JSON 消息的源代码文件 REST API 方法都使用相同的通用格式:

  • status errors状态错误——通常是 源代码文件 REST APIHTTP 状态代码的形式返回错误。此字段在一些不寻常的情况下使用,并且此元素包含 %Status 值,该值可能包含多个错误的文本。
  • status summary状态摘要—包含状态错误的摘要。
  • console控制台—包含 将在控制台上为该操作显示的文本。
  • result结果—包含方法的结果。

GetServer 方法在“结果result”元素中返回有关服务器的信息。结果元素包含一个值“内容”,其中包含:

  • version版本—包含在服务器上运行的实例的版本字符串。
  • id — 包含的实例 GUID
  • api—指定在这个版本的中实现的 源代码文件 REST API 的版本号。
  • features—表示在此实例上启用的功能。
  • namespaces命名空间—列出在服务器上定义的命名空间。

GetNamespace 方法返回有关指定命名空间的信息,包括映射到命名空间的数据库和每个数据库的哈希值。哈希对于提高与服务器通信的效率很有用。但是你可以通过GetServer返回的命名空间信息来获取命名空间中源代码文件的信息。

0
0 249
文章 姚 鑫 · 八月 1, 2022 4m read

第十四章 手动创建 REST 服务(二)

指定数据格式

可以定义 REST 服务以处理不同格式的数据,例如 JSONXML、文本或 CSVREST 调用可以通过在 HTTP 请求中指定 ContentType 元素来指定它期望发送的数据的形式,并且可以通过在 HTTP 请求中指定 Accept 元素来请求返回数据格式。

DocServer 示例中,GetNamespaces() 方法检查 REST 调用是否使用以下内容请求 JSON 数据:

If $Get(%request.CgiEnvs("HTTP_ACCEPT"))="application/json"

本地化 REST 服务

REST 服务返回的任何字符串值都可以本地化,以便服务器以不同语言存储多个版本的字符串。然后,当服务接收到包含 HTTPAccept-Language 标头的 HTTP 请求时,服务会使用相应版本的字符串进行响应。

本地化 REST 服务:

  1. 在实现代码中,不要包含硬编码的文字字符串,而是使用 $$$Text 宏的实例,为宏参数提供如下值:
  • 默认字符串
  • (可选)该字符串所属的域(将字符串分组到域中时,本地化更易于管理)
  • (可选)默认字符串的语言代码

例如,而不是这个:

 set returnvalue="Hello world"
 set returnvalue=$$$TEXT("Hello world","sampledomain","en-us")
  1. 如果省略 $$$Text 宏的域参数,则还要在 REST 服务类中包含 DOMAIN 类参数。例如:
Parameter DOMAIN = "sampledomain"
  1. 编译代码。当这样做时,编译器会在消息字典中为 $$$Text 宏的每个唯一实例生成条目。

消息字典是全局的,因此可以在管理门户中轻松查看(例如)。有一些类方法可以帮助完成常见任务。

  1. 开发完成后,导出该域或所有域的消息字典。

结果是一个或多个 XML 消息文件,其中包含原始语言的文本字符串。

  1. 将这些文件发送给翻译人员,请求翻译版本。

  2. 当收到已翻译的 XML 消息文件时,将它们导入到导出原始文件的同一名称空间中。

译文和原文在消息词典中并存。

  1. 在运行时,REST 服务根据 HTTP Accept-Language 标头选择要返回的文本。

通过REST 使用 Web 会话

有关介绍,请参阅本书前面的“将 Web 会话与 REST 结合使用”。

要使 REST 服务能够通过多个 REST 调用使用单个 Web 会话,请在 REST 服务类中将 UseSession 参数设置为 1

Parameter UseSession As Integer = 1;

支持 CORS

有关介绍,请参阅本书前面的“CORS 简介”。请注意,当按照本附录中的描述手动创建 Web 服务时,支持 CORS 的详细信息会略有不同。

修改 REST 服务以使用 CORS

要指定 REST 服务支持 CORS,请按如下方式修改 REST 服务类,然后重新编译它。

  1. HandleCorsRequest 参数指定一个值。

要为所有调用启用 CORS 标头处理,请将 HandleCorsRequest 参数指定为 1

Parameter HandleCorsRequest = 1;

或者,要为某些调用启用 CORS 标头处理,但不是调用,请将 HandleCorsRequest 参数指定为“”(空字符串):

Parameter HandleCorsRequest = "";

(如果 HandleCorsRequest0,则对所有调用禁用 CORS 标头处理。在这种情况下,如果 REST 服务接收到带有 CORS 标头的请求,服务将拒绝该请求。这是默认设置。)

  1. 如果将 HandleCorsRequest 参数指定为“”,请编辑 URLMap XData 块以指示哪些调用支持 CORS。具体来说,对于任何应该支持 CORS<Route>,添加以下属性名称和值:
Cors="true"

或者在 <Route> 元素中指定 Cors="false" 以禁用 CORS 处理。

如果 REST 服务类将 REST 请求转发到另一个 REST 服务类,则 CORS 处理的行为由包含与给定请求匹配的 <Route> 元素的类确定。

覆盖 CORS 标头处理

重要提示:默认 CORS 标头处理不适用于处理机密数据的 REST 服务。

默认的 CORS 头处理不做任何过滤,只是将 CORS 头传递给外部服务器并返回响应。可能希望限制对域允许列表中的源的访问或限制允许的请求方法。可以通过覆盖 REST 服务类中的 OnHandleCorsRequest() 方法来做到这一点。

请注意,与 UrlMap 中的 <Route> 元素匹配的所有 URL 请求都使用类中定义的单个 OnHandleCorsRequest() 方法进行处理。如果需要针对不同的 REST URL 请求使用不同的 OnHandleCorsRequest() 方法实现,则应使用 Forward 将请求发送到其他 REST 服务类。

变量:访问查询参数

将参数传递给 REST 服务的推荐方法是将它们作为用于调用服务的 URL 路径的一部分传递(例如,/myapi/someresource/parametervalue)。但是,在某些情况下,将参数作为查询参数传递可能更方便(例如,/myapi/someresource?parameter=value)。在这种情况下,可以使用 %request 变量来检索参数值。在 REST 服务中,%request 变量是 %CSP.Request 的一个实例,它包含整个 URL 查询。要检索给定查询参数的值,请使用以下语法:

$GET(%request.Data(name,1),default)

其中 name 是查询参数的名称,default 是要返回的默认值。或者,如果同一个 URL 包含同一个查询参数的多个副本,请使用以下语法:

$GET(%request.Data(name,index),default)

其中 index 是要检索的副本的数字索引。

0
0 73