ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

OpenEMR Standard REST API 完整实战指南:原生资源接口的认证、路由、响应与调用

OpenEMR Standard REST API 完整实战指南:原生资源接口的认证、路由、响应与调用 医疗健康后端【免费下载链接】openemrThe most popular open source electronic health records and medical practice management solution.项目地址https://gitcode.com/GitHub_Trending/op/openemr点击查看免费下载导读本文以 OpenEMR 官方 Standard API 文档 为骨架系统讲解 OpenEMR 面向原生数据结构的 REST API/apis/{site}/api包括其与 FHIR API 的定位差异、启用前置条件、OAuth2 Bearer 认证、全部资源端点与权限模型、统一响应/错误格式以及 7 个可直接运行的 curl 实战示例。读完本文你将能够在自己的 OpenEMR 实例上完成客户端注册、令牌获取、患者/就诊/预约/文档/过敏/生命体征等核心资源的增删改查与排查验证并通过源码级证据理解这些接口背后的路由分发与授权检查机制。一、什么是 OpenEMR Standard REST APIOpenEMR 提供了三套 RESTful 接口在 _rest_routes.inc.php 中一次性加载到路由映射表Standard API/apis/{site}/api面向 OpenEMR 原生数据结构的 REST 接口FHIR API/apis/{site}/fhir符合 HL7 FHIR R4 / US Core 标准的互操作接口Patient Portal API/apis/{site}/portal面向患者角色、处于实验阶段的轻量接口。Standard API 的设计目标非常明确官方文档将其概括为四类场景OpenEMR 特定操作直接暴露patient_data、form_encounter、lists、pc_event等原生表结构自定义集成需要直接访问 OpenEMR 表的第三方系统管理功能用户、机构Facility等后台管理类操作遗留系统集成不兼容 FHIR 的既有系统。从源码注释还可以确认一个关键设计约束_rest_routes.inc.php与apis/routes/_rest_routes_portal.inc.php中均注明“api 路由只面向 user 角色portal 路由只面向 patient 角色”并通过鉴权机制强制保证_rest_routes.inc.php、apis/routes/_rest_routes_portal.inc.php。1.1 何时用 Standard API何时用 FHIR API使用 Standard API 的场景使用 FHIR API 的场景需要 OpenEMR 特有的数据结构需要医疗健康互操作性集成现有 OpenEMR 工作流构建符合标准的应用需要直接访问底层表需要厂商中立的数据模型管理/运营类任务临床数据交换遗留系统集成强制要求 SMART on FHIR 的应用官方建议对于全新的医疗应用优先使用 FHIR API 以获得更好的互操作性Standard API 更适合在 OpenEMR 生态内部做深度集成与管理。二、使用前置条件2.1 启用 Standard API打开Administration管理→ Config配置→ Connectors连接器勾选☑ Enable OpenEMR Standard REST API启用 OpenEMR 标准 REST API对应的开关在 OpenEMR 全局配置中生效只有启用后才能访问/api/前缀端点。2.2 配置 SSL/TLS所有 API 端点强制要求 HTTPS/TLS。需要在Administration → Config → Connectors → Site Address站点地址中配置对外访问的完整基地址该项同时是 OAuth2 与 FHIR 所必需的。例如https://your-openemr.example.com。2.3 注册 API 客户端Standard API 使用 OAuth2 保护使用前必须先注册一个应用客户端Client。完整的注册流程见 Authentication Guide。所需 scope 的最低组合为openid api:oemr user/patient.rs user/encounter.rsopenidOpenID Connect 认证标识强制api:oemrStandard API 访问开关。在 ScopeRepository.php 中可以看到三个 API 类型 scope 的官方定义api:oemr标准 API、api:fhirFHIR API、api:port患者门户 APIuser/patient.rs、user/encounter.rs资源级 scoper代表 Read、s代表 Search/List。完整的 scope 清单与权限语义见 Authorization Guide。三、Base URL 与端点结构Standard API 的 Base URL 模式为https://{your-openemr-host}/apis/{site}/api其中{site}是 OpenEMR 的站点标识典型示例场景URL默认站点https://localhost:9300/apis/default/api多站点alternatehttps://localhost:9300/apis/alternate/api端点结构遵循三层嵌套模式{base}/[resource] # 资源集合 {base}/[resource]/[id] # 单个资源 {base}/[resource]/[id]/[sub-resource] # 子资源嵌套资源官方示例GET https://localhost:9300/apis/default/api/patient GET https://localhost:9300/apis/default/api/patient/123 GET https://localhost:9300/apis/default/api/patient/123/encounter值得注意的是在最新路由实现中[id]一段统一使用UUID作为资源标识见下文“验证规则”例如GET /api/patient/:puuid/encounter:puuid即患者 UUIDapis/routes/_rest_routes_standard.inc.php。四、认证Bearer Token所有 Standard API 请求都必须携带Bearer tokencurl -X GET https://localhost:9300/apis/default/api/patient \ -H Authorization: Bearer YOUR_ACCESS_TOKEN \ -H Accept: application/jsonHTTP 报文视角GET /apis/default/api/patient HTTP/1.1 Host: localhost:9300 Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9... Accept: application/json4.1 获取 Access Token令牌通过 OAuth2 授权流程获取官方文档推荐Authorization Code Grant授权码模式推荐Password Grant密码模式不推荐仅限特殊场景且 OpenEMR 8.5.0 起对机密客户端强制校验client_secretRefresh Token Grant刷新令牌模式。以授权码模式为例先引导用户访问https://localhost:9300/oauth2/default/authorize?...回调收到code后在https://localhost:9300/oauth2/default/token换取令牌得到的响应中access_token即为后续所有/api/请求所需的 Bearer 令牌。4.2 授权模型OAuth2 Scope 与 OpenEMR ACL 双重校验从源码可以看清 Standard API 的授权是双层结构RestConfig.phpACL 检查每个路由入口调用RestConfig::request_authorization_check($request, $section, $value, $aclPermission)内部通过AclMain::aclCheckCore()校验当前登录用户是否具备对应 OpenEMR ACL 权限不通过则抛出AccessDeniedHttpExceptionScope 检查scope_check($scopeType, $resource, $permission)校验令牌中是否包含形如user/patient.rs的 scope通过OEGlobalsBag中的oauth_scopes数组比对不通过抛出AccessDeniedException。这意味着一个请求必须同时满足“OAuth2 scope 授权”和“OpenEMR 内部 ACL 权限”才能成功二者叠加提供了纵深防御。五、API 端点全览官方文档给出的完整资源清单如下权限列见下文解释描述中的表名为 OpenEMR 底层数据表资源权限说明Facilitycrus管理机构/服务地点信息facility表Patientcrus管理患者人口学与注册信息patient_data表Encountercrus管理患者就诊与到访form_encounter表Soap Notecrus管理就诊表单 SOAP 记录form_soap表Vitalscrus管理患者生命体征form_vitals、form_vital_details表Practitionerrus管理从业者信息users表Medical Problemcruds管理患者医疗问题与疾病状况lists表Allergiescruds管理患者过敏lists表Medicationscruds管理患者用药lists表Surgery Issuescruds管理患者手术问题lists表Dental Issuescruds管理患者牙科问题lists表Appointmentscrus管理患者预约pc_event表Listsrs只读访问列表lists表Usersrs只读访问用户users表Insurance Companycrus管理保险公司insurance_data表Patient Documentscrs管理患者文档documents表Patient Employersrs只读访问患者雇主employers表Patient Insurancecrus管理患者保险信息patient_insurance表Patient Messagescud创建患者消息patient_messages表Patient Referrals (transactions)cruds管理患者转诊lbt_data表Patient Immunizationsrs只读访问患者免疫记录immunizations表Patient Proceduresrs只读访问患者手术/检验流程procedure_order、procedure_report、procedure_result表Drugsrs只读访问药品drugs表Prescriptionsrs只读访问处方prescriptions表5.1 权限字母表权限含义cCreate创建资源rRead读取资源uUpdate更新资源dDelete删除资源sSearch/List搜索/列出资源5.2 从路由源码看真实端点分布打开仓库中的 apis/routes/_rest_routes_standard.inc.php可以看到文档表格对应的完整路由实现。除了文档列出的资源最新版本还包含若干附加端点可作为扩展阅读GET /api/version、GET /api/product版本与产品注册信息无需额外 ACLGET /api/insurance_type保险类型查询GET /api/list/:list_name通用列表选项读取GET /api/background_service、POST /api/background_service/:name/run后台服务查询与手动触发需admin/superACLPUT /api/transaction/:tid按事务 ID 更新转诊事务。此外每条路由都通过request_authorization_check指定了 ACL 权限位例如GET /api/patient要求patients/demo_rest_routes_standard.inc.phpPOST /api/prescription额外要求write/addonly写权限L677-L681。处方端点还特意注释说明了“用patients/rx而不是patients/med门控防止仅有病史读取权限的调用者触达处方接口”。六、Patient Portal API实验性Portal API 是面向患者的接口子集官方明确标注EXPERIMENTAL实验性端点覆盖有限、后续可能变化。6.1 启用与 Base URL在Administration → Config → Connectors中勾选☑ Enable OpenEMR Patient Portal REST API (EXPERIMENTAL)Base URL 为https://localhost:9300/apis/default/portal6.2 可用资源资源权限说明Patientr获取当前登录患者的个人信息Encounterrs获取当前登录患者的就诊记录Appointmentrs获取当前登录患者的预约从 apis/routes/_rest_routes_portal.inc.php 可以看到实现细节Portal 路由不接收 URL 中的患者 ID而是通过$request-getPatientUUIDString()强制绑定到当前认证的患者如GET /portal/patient、GET /portal/patient/encounter/:euuid从机制上杜绝了越权访问其他患者数据。6.3 患者凭证与认证患者需要先由临床医生生成 API 凭证打开患者人口学信息页Patient Demographics点击API Credentials按钮为患者生成 API 凭证。患者端认证使用Password Grant且在请求中携带user_rolepatient详见 Authentication Guide。这意味着患者的门户登录凭据portal_login_username/ 密码可以直接换取 OAuth2 令牌而无需走交互式授权码流程。6.4 限制与替代方案⚠️ 端点覆盖有限、随时可能变更⚠️ 官方建议若需要患者自助数据访问优先使用带patient/*scope 的 FHIR API。七、请求/响应格式7.1 统一响应包装所有 Standard API 响应都使用一致的 JSON 包装结构{ validationErrors: [], internalErrors: [], data: result }字段含义字段含义validationErrors客户端侧的校验错误数组如必填字段缺失、日期格式错误internalErrors服务端内部错误数组如数据库连接失败data实际数据载荷单个资源为对象多个资源为数组7.2 成功响应示例单个资源{ validationErrors: [], internalErrors: [], data: { id: 1, uuid: 90cde167-7b9b-4ed1-bd55-533925cb2605, fname: John, lname: Smith } }多个资源{ validationErrors: [], internalErrors: [], data: [ {id: 1, fname: John, lname: Smith}, {id: 2, fname: Jane, lname: Doe} ] }7.3 错误响应示例校验错误422{ validationErrors: [ The fname field is required., The DOB field must be a valid date. ], internalErrors: [], data: [] }服务端错误500{ validationErrors: [], internalErrors: [ Database connection failed ], data: [] }该包装结构由 RestControllerHelper.php 及ProcessingResult校验器在控制器层统一生成保证所有端点行为一致。八、错误处理与 HTTP 状态码状态码含义常见原因200OK成功的 GET/PUT/PATCH 请求201Created成功的 POST 请求400Bad Request请求格式非法401Unauthorized令牌缺失或无效403Forbiddenscope/权限不足404Not Found资源不存在422Unprocessable Entity数据校验失败500Internal Server Error服务端错误8.1 常见错误与处置401 Unauthorized{ error: invalid_token, error_description: The access token is missing }解决在请求头携带Authorization: Bearer TOKEN。403 Forbidden{ validationErrors: [], internalErrors: [Insufficient scope for requested resource], data: [] }解决在授权时申请对应 scope如user/patient.rs或让管理员为该用户分配相应 ACL 权限。404 Not Found{ validationErrors: [], internalErrors: [Resource not found], data: [] }解决核实资源 UUID 是否存在。特别地对于 Portal 路由还会主动校验 UUID 格式非法 UUID 直接返回 400_rest_routes_standard.inc.php。422 Validation Error{ validationErrors: [ The fname field is required., The DOB must be a date in the format Y-m-d. ], internalErrors: [], data: [] }解决修正请求体中校验失败的数据。九、数据验证规则9.1 UUID 格式所有资源 ID 必须是合法的UUID v4格式90cde167-7b9b-4ed1-bd55-533925cb2605源码中通过UuidRegistry::isValidStringUUID()等工具进行校验_rest_routes_standard.inc.php非法 UUID 会触发 400 响应。9.2 日期格式所有日期使用ISO 8601格式YYYY-MM-DD示例2024-01-15。校验错误消息中会明确提示如The DOB must be a date in the format Y-m-d.。十、实战示例7 个可直接运行的 curl以下示例均以默认站点https://localhost:9300/apis/default/api为基准Bearer eyJ0eXAiOiJKV1Qi...为占位令牌请替换为真实获取的 access token。示例 1创建患者POST /api/patientcurl -X POST https://localhost:9300/apis/default/api/patient \ -H Authorization: Bearer eyJ0eXAiOiJKV1Qi... \ -H Content-Type: application/json \ --data { title: Mr, fname: John, lname: Smith, DOB: 1980-01-15, sex: Male, street: 123 Main St, city: Boston, state: MA, postal_code: 12345, phone_home: 555-1234, email: john.smithexample.com }成功后返回 201data中会包含新患者的uuid供后续示例使用。示例 2搜索患者GET /api/patient?lnamecitycurl -X GET https://localhost:9300/apis/default/api/patient?lnameSmithcityBoston \ -H Authorization: Bearer eyJ0eXAiOiJKV1Qi...支持以查询参数形式组合搜索条件底层通过SearchQueryConfig::createConfigFromQueryParams()解析分页与过滤参数_rest_routes_standard.inc.php。示例 3获取患者就诊记录GET /api/patient/{uuid}/encountercurl -X GET https://localhost:9300/apis/default/api/patient/90cde167-7b9b-4ed1-bd55-533925cb2605/encounter \ -H Authorization: Bearer eyJ0eXAiOiJKV1Qi...对应路由GET /api/patient/:puuid/encounter要求encounters/auth_aACL。示例 4创建预约POST /api/appointmentcurl -X POST https://localhost:9300/apis/default/api/appointment \ -H Authorization: Bearer eyJ0eXAiOiJKV1Qi... \ -H Content-Type: application/json \ --data { pc_catid: 5, pc_title: Annual Physical, pc_duration: 1800, pc_eventDate: 2024-02-15, pc_startTime: 09:00:00, pc_facility: 1, pid: 1 }字段直接对应pc_event表结构pc_catid为预约类别、pc_duration为时长秒、pc_eventDate/pc_startTime为日期与时间、pc_facility为机构、pid为患者内部 ID。示例 5上传患者文档POST /api/patient/{uuid}/documentcurl -X POST https://localhost:9300/apis/default/api/patient/90cde167-7b9b-4ed1-bd55-533925cb2605/document \ -H Authorization: Bearer eyJ0eXAiOiJKV1Qi... \ -F file/path/to/lab-results.pdf \ -F pathLab Reports \ -F date2024-01-15这是唯一使用 multipart/form-data 的端点。源码中通过$_FILES[document]接收文件、path与eid查询参数指定存储目录与关联就诊_rest_routes_standard.inc.php并要求patients/docswrite/addonly权限。注意这里的占位 UUID 路径也可替换为患者内部pid。示例 6添加过敏POST /api/patient/{uuid}/allergycurl -X POST https://localhost:9300/apis/default/api/patient/90cde167-7b9b-4ed1-bd55-533925cb2605/allergy \ -H Authorization: Bearer eyJ0eXAiOiJKV1Qi... \ -H Content-Type: application/json \ --data { title: Penicillin, begdate: 2020-01-15, diagnosis: Allergy to penicillin, severity_al: severe, reaction: Hives }示例 7记录生命体征POST /api/patient/{uuid}/vitalcurl -X POST https://localhost:9300/apis/default/api/patient/90cde167-7b9b-4ed1-bd55-533925cb2605/vital \ -H Authorization: Bearer eyJ0eXAiOiJKV1Qi... \ -H Content-Type: application/json \ --data { date: 2024-01-15, bps: 120, bpd: 80, weight: 180, height: 70, temperature: 98.6, pulse: 72, respiration: 16 }注意文档中的 vitals 端点路径存在新旧两套路由。最新路由实现将 Vitals 嵌套在就诊下/api/patient/:pid/encounter/:eid/vital见 _rest_routes_standard.inc.php示例 7 沿用了文档给出的便捷路径请以你所用 OpenEMR 版本的实际 Swagger 为准。十一、Swagger 交互式文档11.1 本实例 Swagger UI在浏览器打开本实例的 Swagger UIhttps://your-openemr-install/swagger/在 Swagger 界面中选择standard分组可查看并交互测试全部 Standard API 端点。仓库的 swagger 目录即为 Swagger UI 静态资源含openemr-api.yaml定义文件。11.2 配置 Swagger OAuth将你的客户端回调地址设置为OpenEMR base URI/swagger/oauth2-redirect.html示例https://localhost:9300/swagger/oauth2-redirect.html配置完成后即可在 Swagger UI 中直接点击 Authorize输入client_id完成授权并在线发起真实请求。十二、源码级原理一次 Standard API 请求的完整链路为了让读者真正理解 Standard API 的底层运作这里补充请求处理流水线对应 apis/dispatch.php 与 ApiApplication.php入口分发apis/dispatch.php将全局请求包装为HttpRestRequestHttpRestRequest::createFromGlobals()并创建ApiApplication实例执行run()事件监听链ApiApplication::run()依次注册 9 个监听器——异常处理、遥测、响应日志、会话清理、站点初始化数据库连接与 globals、CORS、OAuth2 授权、ACL 授权、路由解析、视图渲染JSON 输出路由匹配RoutesExtensionListener根据请求 URI 前缀区分三类 APIRestConfig::is_api_request()/is_portal_request()/is_fhir_request()见 RestConfig.php并到对应的路由映射表中查找匹配项双重鉴权路由闭包内先做request_authorization_checkOpenEMR ACL令牌本身的有效性、scope 合法性则交给 OAuth2 授权监听器与scope_check完成控制器执行实例化对应的 RestController如PatientRestController、EncounterRestController调用 Service 层完成数据读写统一响应控制器返回结果经RestControllerHelper/ProcessingResult包装成{validationErrors, internalErrors, data}结构由ViewRendererListener渲染为 JSON 响应。12.1 授权检查实现RestConfig::request_authorization_check()最终调用AclMain::aclCheckCore($section, $value, $user, $aclPermission)不满足权限即抛出AccessDeniedHttpExceptionRestConfig.php而scope_check()则比对令牌携带的oauth_scopesRestConfig.php。两套机制共同决定一个请求是否被放行。十三、后续学习路径完整掌握 OAuth2 客户端注册与四种授权流程Authentication Guide深入理解 scope 语法、上下文patient/user/system与权限位Authorization Guide标准互操作集成方案FHIR APISMART on FHIR 应用开发SMART_ON_FHIR.md高级主题与实现细节Developer Guide最终建议Standard API 是 OpenEMR 生态内的“原生直通车”适合管理集成、数据迁移与遗留系统对接而面向医疗健康行业标准互操作的新应用官方仍然推荐优先考虑 FHIR API。无论选择哪条路线本文的认证、响应包装与错误排查知识都是共通的可放心复用。赞分享医疗健康后端【免费下载链接】openemrThe most popular open source electronic health records and medical practice management solution.项目地址https://gitcode.com/GitHub_Trending/op/openemr点击查看免费下载相关推荐OpenEMR FHIR R4 API 完整实战指南资源、认证、Bulk 导出与 CCD 生成OpenEMR FHIR R4 API 完整实战指南资源、认证、Bulk 导出与 CCD 生成 导读 OpenEMR 提供了完整的 HL7 FHIR R44医疗健康后端InvenTree REST API 实战指南认证、授权、Schema 与接口调用全解析InvenTree REST API 实战指南认证、授权、Schema 与接口调用全解析 InvenTree 作为开源库存管理系统为服务器端的所有库存数据提后端前端企业应用ERPDogecoin 无认证 REST 接口REST-interface完整指南启用、端点详解与源码级原理Dogecoin 无认证 REST 接口REST interface完整指南启用、端点详解与源码级原理 Dogecoin 全节点内置一套无认证Unaut区块链上一篇Oryx Lets Encrypt 实战指南给 SRS 免费开通 HTTPS证书自动续期下一篇US.KG免费域名NS委托全解外部DNS避坑指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表