0% found this document useful (0 votes)
63 views35 pages

Gqbyu 201117 AbelEnthoven FHIR REST API

This presentation provides an overview of how to use the FHIR RESTful API including how to create, update, delete and fetch FHIR resources and how to perform searches. It covers CRUD operations on resources using HTTP methods and transactions as well as search parameters, included references, and concurrency control.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
63 views35 pages

Gqbyu 201117 AbelEnthoven FHIR REST API

This presentation provides an overview of how to use the FHIR RESTful API including how to create, update, delete and fetch FHIR resources and how to perform searches. It covers CRUD operations on resources using HTTP methods and transactions as well as search parameters, included references, and concurrency control.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 35

FHIR REST API

Abel Enthoven, Firely

HL7 FHIR DevDays 2020, Virtual Edition, November 17–20, 2020 | @FirelyTeam | #fhirdevdays | www.devdays.com/november-2020

HL7®, FHIR® and the flame Design mark are the registered trademarks of Health Level Seven International and are used with permission.
Who am I?
• Abel Enthoven
• FHIR Technical Specialist @ : Vonk, Forge

1
FHIR RESTful API FHIR REST endpoint
• RESTful web service http://test.fhir.org/r4
• frontend for FHIR server https://vonk.fire.ly
• comparable to OData, GraphQL, https://vonk.fire.ly/r4
ORDS http://hapi.fhir.org/baseR4
• FHIR resources as ‘data model’
GET {endpoint}/Patient
GET /Patient

2
This presentation Just briefly

How to...
• Create, update and delete resources
• Transactions
• Validation
• Concurrency
• Fetch resources
• Resource versions
• Search
• Include referenced resources

3
Create a resource
• HTTP method POST is used
• Resource ID is assigned by the server
• ID is available in the Location header

4
< POST a Patient >

5
< POST a patient-related Observation >

6
Upsert a resource
• HTTP method PUT is used
• If the resource exists, it is completely replaced (200 OK)
• If it does not exist, it is created* using your ID (201 Created)

*) additional server capability

7
< PUT a Patient >

8
Partially update a resource
• HTTP method PATCH is used
• Updates only selected elements, not the entire resource like PUT
• Uses: low-bandwidth or partial resource access
• Not all servers currently implement PATCH

9
Delete a resource
• HTTP method DELETE is used
• If the resource does not exist, DELETE still returns success
• Previous versions* of a resource continue to exist (HIPAA, GDPR)

10
< DELETE a Patient >

11
A batch of requests
• POST a Bundle to the server root: /
• The Bundle contains a collection of requests
• The requests are processed in order
• Temporary references between bundled resources possible
• A bundle of type ‘batch’ is processed non-atomically
• A bundle of type ‘transaction’ is processed atomically*

12
< POST a transaction >

13
Resource validation types/profiles

serialization format application/json


Content-Type header

FHIR basics application/fhir+json


missing type, invalid meta

FHIR ‘type’
(e.g. Patient)
Resource.resourceType

FHIR ‘profile’
(e.g. US Core Patient)
Resource.meta.profile[] resources
14
< POST with validation >

15
Response
HTTP headers
Location URL of (new) resource, resource ID
Content-Type* Resource serialization format, e.g. ‘application/fhir+xml; fhirVersion=4.0’
ETag* Optimistic concurrency

HTTP content – defaults are server-specific


Prefer: return=minimal No content, just headers
Prefer: return=representation The created, updated or deleted resource(s)
{

Prefer: return=OperationOutcome "resourceType": "OperationOutcome",


"id": "00eab784-f87a-414c-b522-e98129a1b2fc",
"meta": {
"versionId": "fdb7e1d9-5c27-4bd7-8ccd-2e9b38609541",
"lastUpdated": "2020-06-04T08:33:29.997+00:00"
},
"issue": [
{
"severity": "error",
"code": "invalid",
"details": {
"coding": [
{
"system": "http://hl7.org/fhir/dotnet-api-operation-outcome",
"code": "5000"
}
],
"text": "Invalid Json encountered. Details: Error parsing boolean value. Path 'name', line 4, position 11."
}
]
}

16
Serialization format and FHIR versions
• in URL /Patient/1?_format=application/fhir+turtle
Content-Type: application/fhir+turtle; fhirVersion=4.0

• in header Accept: application/fhir+xml;fhirVersion=3.0


Content-Type: application/fhir+xml; fhirVersion=3.0
( content
)
negotiation

• on endpoint* /R4/Patient?_format=application/json
Content-Type: application/fhir+json; fhirVersion=4.0

request.Accept
request.ContentType

17
Concurrency
Optimistic concurrency via HTTP standard mechanism
Response header
Last-Modified Last modification on the resource, equal to Resource.meta.lastUpdated
ETag Server-assigned version tag, equal to Resource.meta.versionId (W/”{version}”)

Request header
If-Modified-Since Read resource if it has been modified after timestamp, or 304 Not Modified
If-None-Match Read resource if its ETag changed, or 304 Not Modified
If-Match Update resource if its ETag did not change, or 412 Precondition Failed

Pessimistic concurrency (server-specific resource locking)


409 Conflict

18
Fetch a resource by ID
GET /Patient/1
GET /Patient?_id=1 (search)

19
< GET Patient by ID >

20
Fetch resource history
GET /Patient/1/_history
resource current
/Patient/_history
/_history version 3

history
GET /Patient/1/_history/3 version 2

single version of the resource use


version 1
- auditing (with AuditEvent)
- polling synchronization (delta)
- undo

21
Search
• using URL parameters (GET)
GET /Patient?family=Enthoven&birthdate=1975-12-21

• using a form POST, because


POST /Patient/_search
Content-Type: application/x-www-form-urlencoded

with content:
family=Enthoven&birthdate=1975-12-21

22
Search parameters
• defined for all resources in FHIR standard
e.g. _id, _profile, _type

• defined per resource in FHIR standard and custom


e.g. Patient.name, Observation.code, Patient.my_search_param, MyType.my_search_param

• multiple parameter types (see: Cheat Sheet)

23
< simple search >

24
Search parameter modifiers
• Adds an extra constraint to your search
• Notation: {param name}:{modifier}={value}

GET /Patient?family:exact=Enthoven

GET /Observation?patient:missing=true

25
Search parameter value prefixes
• Only for ordered parameter types (number, date, quantity)
• Prefixes are based on range comparison
e.g. the date 2019-11 is a range containing an entire month
• Notation: {param name}={prefix}{value}

GET /Patient?birthdate=ge1975-01-01

GET /Observation?valueInteger=lt4

26
Chained search parameters
• step into referenced resources
GET /Observation?patient.family=Enthoven&patient.birthdate=1975-12-21

27
Include referenced resources
• use the _include or _revinclude parameters
• can only refer to search parameters of type Reference
• the value looks like: <resource type>:<search parameter name>
GET /Observation/1?_include=Observation:patient

• include references of referenced resources (using :iterate)

28
< complex search >

29
Capability statement
• A server advertises its FHIR capabilities at /metadata
• Allows you to:
• compare servers
• automatically hide functionality (UI)
• progressively use better/faster methods
• Per-server, per-resource, per-operation

30
Contact
• During DevDays, you can find / reach me here:
• Via Whova App – Speaker’s Gallery
• Email: [email protected]

31
Questions
• In the Q&A section of Whova

• Hit me up any time during DevDays via Whova or e-mail


• Official FHIR documentation: https://www.hl7.org/fhir/http.html

32
Search cheat sheet
parameter types number date string url token quantity reference

220 2013-01-14 hi http://hl7.org 50197-3 2.2 125

3.67 2013-01-14T13:00 any string urn:oid:165.2 http://loinc.org|50197-3 6.3||mg Patient/125

3.4e12 2013-01-14T13:00Z hello\, welcome |50197-3 1.20e-2|http://unitsofmeasure.org|mg http://server/Patient/125

http://loinc.org| http://server/Patient/125|2.0

search modifiers modifier param types true if

:missing={bool} all value is missing (null)

:exact={string} string string matches value exactly (including case)

:contains={string} string string is present anywhere in the value

:text={string} token string is present in Coding.display or CodeableConcept.text

:in={valueset ref} many value is present in the ValueSet

:not-in={valueset ref} many value is not present in the ValueSet

:below={node} code, uri, other value represents a node in a hierarchy and is ‘below’ node

:above={string} code, uri, other value represents a node in a hierarchy and is ‘above’ node

value prefixes prefix true if

=eq{range} the property range* is within the range* of the search value *) a parameter value is a single value and, often, so is a property value.
But a single value has a ‘range’ because of its precision. For example:
=ap{range} the property range is within the range of the search value, but approximately (up to 10% deviation) the range of date value 2020-11 is 2020-11-01T00:00:00 until 2020-11-
30T23:59:59
=ne{range} the property range is not completely within the range of the search value

=gt{range} the property range overlaps the search range at the greater end Value prefixes can only be used on ordinal parameter types

=ge{range} the property range overlaps the search range at the greater end or is within the range of the search value

=sa{range} the ranges do not overlap and the property range is greater than the search range

=lt{range} the property range overlaps the search range at the lower end

=le{range} the property range overlaps the search range at the lower end or is within the range of the search value

=eb{range} the ranges do not overlap and the property range is lower than the search range

33
Conditional CRUD
• PUT or DELETE using a Search URL
PUT /Patient?identifier=820-05-1120

• POST using header ‘If-None-Exist’ containing Search URL query part


# results POST PUT without ID PUT with ID DELETE
0 create create create with id* none
1 ignored update update or 400 (id unequal) delete
2+ 412 Precon Fail 412 Precon Fail 412 Precondition Failed delete all or 412**

**) see CapabilityStatement.rest.resource.conditionalDelete

34

You might also like