Skip to content

Latest commit

 

History

History
573 lines (416 loc) · 14 KB

FHIR_README.md

File metadata and controls

573 lines (416 loc) · 14 KB

OpenEMR FHIR API Documentation

Overview

Easy-to-use JSON-based REST API for OpenEMR FHIR. All code is done in classes and separate from the view to help with codebase modernization efforts. See standard OpenEMR API docs here

Implementation

FHIR endpoints are defined in the primary routes file. The routes file maps an external, addressable endpoint to the OpenEMR FHIR controller which handles the request, and also handles the JSON data conversions.

"POST /fhir/Patient" => function () {
    RestConfig::authorization_check("patients", "demo");
    $data = (array)(json_decode(file_get_contents("php://input"), true));
    return (new FhirPatientRestController())->post($data);
}

At a high level, the request processing flow consists of the following steps:

JSON Request -> FHIR Controller Component -> FHIR Validation -> Parsing FHIR Resource -> Standard Service Component -> Validation -> Database

The logical response flow begins with the database result:

Database Result -> Service Component -> FHIR Service Component -> Parse OpenEMR Record -> FHIR Controller Component -> RequestControllerHelper -> JSON Response

Sections

Prerequisite

Enable the Standard FHIR service (/fhir/ endpoints) in OpenEMR menu: Administration->Globals->Connectors->"Enable OpenEMR Standard FHIR REST API" Enable the Patient Portal FHIR service (/portalfhir/ endpoints) in OpenEMR menu: Administration->Globals->Connectors->"Enable OpenEMR Patient Portal FHIR REST API"

Using FHIR API Internally

There are several ways to make API calls from an authorized session and maintain security:

  • See the script at tests/api/InternalApiTest.php for examples of internal API use cases.

FHIR Endpoints

Standard FHIR endpoints Use http://localhost:8300/apis/fhir as base URI.

Example: http://localhost:8300/apis/fhir/Patient returns a Patient's bundle resource, etc

FHIR Authorization

POST [base]/auth

The OpenEMR FHIR API utilizes the OAuth2 password credential flow for authentication. To obtain an API token, submit your login credentials and requested scope. The scope must match a site that has been setup in OpenEMR, in the /sites/ directory. If additional sites have not been created, set the scope to 'default'.

Request:

curl -X POST -H 'Content-Type: application/json' 'http://localhost:8300/apis/fhir/auth' \
-d '{
    "grant_type":"password",
    "username": "ServiceUser",
    "password": "password",
    "scope":"site id"
}'

Response:

{
    "token_type": "Bearer",
    "access_token": "eyJ0b2tlbiI6IjAwNmZ4TWpsNWhsZmNPelZicXBEdEZVUlNPQUY5KzdzR1Jjejc4WGZyeGFjUjY2QlhaaEs4eThkU3cxbTd5VXFBeTVyeEZpck9mVzBQNWc5dUlidERLZ0trUElCME5wRDVtTVk5bE9WaE5DTHF5RnRnT0Q0OHVuaHRvbXZ6OTEyNmZGUmVPUllSYVJORGoyZTkzTDA5OWZSb0ZRVGViTUtWUFd4ZW5cL1piSzhIWFpJZUxsV3VNcUdjQXR5dmlLQXRXNDAiLCJzaXRlX2lkIjoiZGVmYXVsdCIsImFwaSI6Im9lbXIifQ==",
    "expires_in": "3600",
    "user_data": {
        "user_id": "1"
    }
}

The Bearer token is required for each OpenEMR API request, and is conveyed using an Authorization header.

Request:

curl -X GET 'http://localhost:8300/apis/fhir/Patient' \
  -H 'Authorization: Bearer eyJ0b2tlbiI6IjAwNnZ3eGJZYmFrOXlxUjF4U290Y1g4QVVDd3JOcG5yYXZEaFlqaHFjWXJXRGNDQUtFZmJONkh2cElTVkJiaWFobHBqOTBYZmlNRXpiY2FtU01pSHk1UzFlMmgxNmVqZEhcL1ZENlNtaVpTRFRLMmtsWDIyOFRKZzNhQmxMdUloZmNJM3FpMGFKZ003OXdtOGhYT3dpVkx5b3BFRXQ1TlNYNTE3UW5TZ0dsUVdQbG56WjVxOVYwc21tdDlSQ3RvcDV3TEkiLCJzaXRlX2lkIjoiZGVmYXVsdCIsImFwaSI6ImZoaXIifQ=='

Patient Resource


GET [base]/Patient

Request:

curl -X GET 'http://localhost:8300/apis/fhir/Patient'

GET [base]/Patient[id]

Request:

curl -X GET 'http://localhost:8300/apis/fhir/Patient/90a8923c-0b1c-4d0a-9981-994b143381a7'
  • Supported Search Parameters
    • address
    • address-city
    • address-postalcode
    • address-state
    • birthdate
    • email
    • family
    • gender
    • given
    • name
    • phone
    • telecom

POST [base]/Patient

Request:

curl -X POST -H 'Content-Type: application/fhir+json' 'http://localhost:8300/apis/fhir/Patient' -d \
'{
  "resourceType": "Patient",
  "identifier": [ { "system": "urn:oid:1.2.36.146.595.217.0.1", "value": "12345" } ],
  "name": [ {
      "family": "Chalmers",
      "given": [ "Peter", "James" ]
  } ],
  "gender": "male",
  "birthDate": "1974-12-25"
}'

PUT [base]/Patient/[id]

Request:

curl -X PUT -H 'Content-Type: application/fhir+json' 'http://localhost:8300/apis/fhir/Patient/90a8923c-0b1c-4d0a-9981-994b143381a7' -d \
'{
  "resourceType": "Patient",
  "id": "1",
  "identifier": [ { "system": "urn:oid:1.2.36.146.595.217.0.1", "value": "12345" } ],
  "name": [ {
      "family": "Chalmers",
      "given": [ "Peter", "James" ]
  } ],
  "gender": "male",
  "birthDate": "1974-01-13",
  "address": [ {
      "line": [ "534 Erewhon St" ],
      "city": "PleasantVille",
      "state": "Vic",
      "postalCode": "3999"
  } ]
}'

PATCH [base]/Patient/[id]

Request:

curl -X PATCH -H 'Content-Type: application/fhir+json' 'http://localhost:8300/apis/fhir/Patient/90a8923c-0b1c-4d0a-9981-994b143381a7' -d \
'[
 {
   "op": "replace",
   "path": "/address/0/postalCode",
   "value": "M5C 2X8"
 },
 {
   "op": "replace",
   "path": "/birthDate",
   "value": "1974-02-13"
 }
]'

Encounter Resource


GET [base]/Encounter

Request:

curl -X GET 'http://localhost:8300/apis/fhir/Encounter'

GET [base]/Encounter[id]

Request:

curl -X GET 'http://localhost:8300/apis/fhir/Encounter/90c196f2-51cc-4655-8858-3a80aebff3ef'
  • Supported Search Parameters
    • _id
    • patient
    • date {gt|lt|ge|le}

Practitioner Resource


GET [base]/Practitioner

Request:

curl -X GET 'http://localhost:8300/apis/fhir/Practitioner'

GET [base]/Practitioner[id]

Request:

curl -X GET 'http://localhost:8300/apis/fhir/Practitioner/90a8923c-0b1c-4d0a-9981-994b143381a7'
  • Supported Search Parameters
    • address
    • address-city
    • address-postalcode
    • address-state
    • email
    • active
    • family
    • given
    • name
    • phone
    • telecom

POST [base]/Practitioner

Request:

curl -X POST -H 'Content-Type: application/fhir+json' 'http://localhost:8300/apis/fhir/Practitioner' -d \
'{
  "resourceType": "Practitioner",
  "identifier": [ { "system": "http://hl7.org/fhir/sid/us-npi", "value": "1122334499" } ],
  "name": [ {
      "use": "official",
      "family": "Chalmers",
      "given": [ "Peter", "James" ]
  } ]
}'

PATCH [base]/Practitioner/[id]

Request:

curl -X PATCH -H 'Content-Type: application/fhir+json' 'http://localhost:8300/apis/fhir/Practitioner/90a8923c-0b1c-4d0a-9981-994b143381a7' -d \
'{
  "resourceType": "Practitioner",
  "identifier": [ { "system": "http://hl7.org/fhir/sid/us-npi", "value": "1155667799" } ],
  "name": [ {
      "use": "official",
      "family": "Theil",
      "given": [ "Katy", "Wilson" ]
  } ],
  "address": [ {
      "line": [ "534 Erewhon St" ],
      "city": "PleasantVille",
      "state": "Vic",
      "postalCode": "3999"
  } ]
}'

GET [base]/PractitionerRole

Request:

curl -X GET 'http://localhost:8300/apis/fhir/PractitionerRole'

GET [base]/PractitionerRole/[id]

Request:

curl -X GET 'http://localhost:8300/apis/fhir/PractitionerRole/90de091a-91e9-4bbe-9a81-75ed623f65bf'
  • Supported Search Parameters
    • speciality
    • practitioner

GET [base]/Immunization

Request:

curl -X GET 'http://localhost:8300/apis/fhir/Immunization'

GET [base]/Immunization/[id]

Request:

curl -X GET 'http://localhost:8300/apis/fhir/Immunization/90feaaa2-4097-4437-966e-c425d1958dd6'
  • Supported Search Parameters
    • patient

GET [base]/AllergyIntolerance

Request:

curl -X GET 'http://localhost:8300/apis/fhir/AllergyIntolerance'

GET [base]/AllergyIntolerance/[id]

Request:

curl -X GET 'http://localhost:8300/apis/fhir/AllergyIntolerance//90feaaa2-4097-4437-966e-c425d1958dd6'

GET /fhir/Organization

Request:

curl -X GET 'http://localhost:8300/apis/fhir/Organization'

GET /fhir/Organization/:id

Request:

curl -X GET 'http://localhost:8300/apis/fhir/Organization/1'

GET /fhir/Observation

Request:

curl -X GET 'http://localhost:8300/apis/fhir/Observation'

GET /fhir/Observation/:uuid

Request:

curl -X GET 'http://localhost:8300/apis/fhir/Observation/9150635b-0705-4a27-8820-df8b56cf07eb'

POST /fhir/QuestionnaireResponse

Request:

curl -X POST -H 'Content-Type: application/fhir+json' 'http://localhost:8300/apis/fhir/QuestionnaireResponse' -d \
'{
  "resourceType": "QuestionnaireResponse",
  "id": "697485",
  "meta": {
    "versionId": "1",
    "lastUpdated": "2020-03-22T09:11:45.181+00:00",
    "source": "#L0otRLyoImuOVD2S"
  },
  "status": "completed",
  "item": [ {
    "linkId": "1",
    "text": "Do you have allergies?"
  }, {
    "linkId": "2",
    "text": "General questions",
    "item": [ {
      "linkId": "2.1",
      "text": "What is your gender?"
    }, {
      "linkId": "2.2",
      "text": "What is your date of birth?"
    }]
  }]
  } ]
}'

GET [base]/Condition

Request:

curl -X GET 'http://localhost:8300/apis/fhir/Condition'

GET [base]/Condition/[id]

Request:

curl -X GET 'http://localhost:8300/apis/fhir/Condition/9109890a-6756-44c1-a82d-bdfac91c7424'

GET /fhir/Procedure

Request:

curl -X GET 'http://localhost:8300/apis/fhir/Procedure'

GET /fhir/Procedure/:uuid

Request:

curl -X GET 'http://localhost:8300/apis/fhir/Procedure/9109890a-6756-44c1-a82d-bdfac91c7424'

GET /fhir/MedicationRequest

Request:

curl -X GET 'http://localhost:8300/apis/fhir/MedicationRequest'

GET /fhir/MedicationRequest/:uuid

Request:

curl -X GET 'http://localhost:8300/apis/fhir/MedicationRequest/9128a1ec-95be-4649-8a66-d3686b7ab0ca'

GET /fhir/Medication

Request:

curl -X GET 'http://localhost:8300/apis/fhir/Medication'

GET /fhir/Medication/:uuid

Request:

curl -X GET 'http://localhost:8300/apis/fhir/Medication/9109890a-6756-44c1-a82d-bdfac91c7424'

GET /fhir/Location

Request:

curl -X GET 'http://localhost:8300/apis/fhir/Location'

GET /fhir/Location/:uuid

Request:

curl -X GET 'http://localhost:8300/apis/fhir/Location/90f3d0e9-2a19-453b-84bd-1fa2b533f96c'

GET /fhir/CareTeam

Request:

curl -X GET 'http://localhost:8300/apis/fhir/CareTeam'

GET /fhir/CareTeam/:uuid

Request:

curl -X GET 'http://localhost:8300/apis/fhir/CareTeam/915e8fb4-86b2-4365-a420-d46fc07d5aed'

/portalfhir/ Endpoints

OpenEMR patient portal fhir endpoints Use http://localhost:8300/apis/portalfhir as base URI.

Example: http://localhost:8300/apis/portalfhir/Patient returns a resource of the patient.

POST /portalfhir/auth

The OpenEMR Patient Portal FHIR service utilizes the OAuth2 password credential flow for authentication. To obtain an API token, submit your login credentials and requested scope. The scope must match a site that has been setup in OpenEMR, in the /sites/ directory. If additional sites have not been created, set the scope to 'default'. If the patient portal is set to require email address on authenticate, then need to also include an email field in the request.

Request:

curl -X POST -H 'Content-Type: application/json' 'http://localhost:8300/apis/portalfhir/auth' \
-d '{
    "grant_type":"password",
    "username": "ServiceUser",
    "password": "password",
    "scope":"site id"
}'

Response:

{
    "token_type": "Bearer",
    "access_token": "eyJ0b2tlbiI6IjAwNmZ4TWpsNWhsZmNPelZicXBEdEZVUlNPQUY5KzdzR1Jjejc4WGZyeGFjUjY2QlhaaEs4eThkU3cxbTd5VXFBeTVyeEZpck9mVzBQNWc5dUlidERLZ0trUElCME5wRDVtTVk5bE9WaE5DTHF5RnRnT0Q0OHVuaHRvbXZ6OTEyNmZGUmVPUllSYVJORGoyZTkzTDA5OWZSb0ZRVGViTUtWUFd4ZW5cL1piSzhIWFpJZUxsV3VNcUdjQXR5dmlLQXRXNDAiLCJzaXRlX2lkIjoiZGVmYXVsdCIsImFwaSI6Im9lbXIifQ==",
    "expires_in": "3600",
    "user_data": {
        "user_id": "1"
    }
}

The Bearer token is required for each OpenEMR Patient Portal FHIR service request, and is conveyed using an Authorization header.

Request:

curl -X GET 'http://localhost:8300/apis/portalfhir/Patient' \
  -H 'Authorization: Bearer eyJ0b2tlbiI6IjAwNmZ4TWpsNWhsZmNPelZicXBEdEZVUlNPQUY5KzdzR1Jjejc4WGZyeGFjUjY2QlhaaEs4eThkU3cxbTd5VXFBeTVyeEZpck9mVzBQNWc5dUlidERLZ0trUElCME5wRDVtTVk5bE9WaE5DTHF5RnRnT0Q0OHVuaHRvbXZ6OTEyNmZGUmVPUllSYVJORGoyZTkzTDA5OWZSb0ZRVGViTUtWUFd4ZW5cL1piSzhIWFpJZUxsV3VNcUdjQXR5dmlLQXRXNDAiLCJzaXRlX2lkIjoiZGVmYXVsdCIsImFwaSI6Im9lbXIifQ=='

GET /portalfhir/Patient

Request:

curl -X GET 'http://localhost:8300/apis/portalfhir/Patient'