FHIR

FHIR Search - Part 1: Introduction to Search

Part 1 - FHIR Documentation Bundle type: searchset

00

Most Go to FHIR homepage,
https://build.fhir.org/
and click search

01

The official request method for FHIR is POST but GET is often used, most other apis. Info located in the documentation here ,
https://www.hl7.org/fhir/search.html
A server that does not support search via GET will return links in the same style as a server that does not support search via POST. Note that this makes the self link special in the context of bundle links, as all other links are intended to be resolvable by a client.

 All resource types: Note that if the _type parameter is included, all other search parameters SHALL be common to all provided types, and if _type is not included, all parameters SHALL be common to all resource types.

GET [base]?parameter(s)

A specified resource type:

GET [base]/[type]?parameter(s)

A specified compartment, perhaps with a specified resource type in that compartment. Note that the literal * (asterisk) is valid as the [type] in a GET-based compartment search. This syntax is for disambiguation between an instance read and a compartment search, which would otherwise share the same URL.

GET [base]/[compartment]/[id]/[type]?parameter(s)

02

A full example of a search using POST and GET requests can be found in the rest api section in search

This contains the POST 'Body' and can be found here,
https://www.hl7.org/fhir/http.html#search
example for resource type search below

POST [base]/[resource-type]/_search
Content-Type: application/x-www-form-urlencoded
param1=value&...{&_format=[mime-type]}

03

FHIR returns a Bundle with the type searchset. This allows us access to different attributes related to the search query,

https://build.fhir.org/search

04

You can see the type searchset in the Bundle Resource page,
https://hl7.org/fhir/bundle.html

Part 2 - GET POST

01

POST is the official HTTP request Verb, but GET can be used and is more common amoung other REST apis. (**Important ) it seems, GET is the new standard

02

Ths GET example on the search page isn't good, Go to search from the hompage in the RESTFUL API section, https://hl7.org/fhir/http.html#search

03

Again, the link and example code for POST, https://hl7.org/fhir/http.html#search

    POST [base]/_search
    Content-Type: application/x-www-form-urlencoded
    param1=value&...{&_format=[mime-type]}

Part 3 - Visual Studio REST Client Extention and HTTP vs Python

01

To use REST APIs in VS code, Save a file as filename.http in vs code, download the REST CLIENT extension.

02

http

The following code file makes a reuqest to the Patient Resource. Click Send Request to make request

GET [base]/[type]?parameter(s)
    @fhirUrl = http://hapi.fhir.org/baseR4/

    GET {{fhirUrl}}/Patient
    Accept: application/fhir+json

This returns a bundle full of patients

03

python -m -venv venv & pip list

Must install a 'virtual enviorment' venv and import the request library

    python -m venv venv
    ./venv/Script/activate.bat
    pip install request

04

python

This python code does the same as the HTTP request in 02 above

    import requests
    fhir_url = 'http://hapi.fhir.org/baseR4/'
    endpoint = f'{fhir_url}/Patient'
    headers = {'Accept': 'application/fhir+json'}

    response = requests.get(endpoint,headers=headers)
    if response.status_code == 200:
        fhir_data = response.json()
        print(fhir_data)
    else:
        print(f'Error: {response.status_code}')
        print(response.text)
        

Part 4 - GET & POST HTTP response.text ( Bundle & url links: self,previous,next)


 (import json (in python))

01

We can see from the previous code in Part 3 that in the response, there is a Bundle. Inside the bundle there is a resource(right word??) named link which contains the propeties(right word??) relation: and url
https://hl7.org/fhir/bundle.html

02

import json use pretty

The json from the HTTP request in the console, has no line breaks, is difficult to read. import the json and use the function json.dumps()

    import requests
    import json

    fhir_url = 'http://hapi.fhir.org/baseR4/'
    endpoint = f'{fhir_url}/Patient'
    headers = {'Accept': 'application/fhir+json'}

    response = requests.get(endpoint, headers=headers)
    if response.status_code == 200:
        fhir_data = response.json()
        pretty_fhir_data = json.dumps(fhir_data,indent=2)
        print(pretty_fhir_data)
    else:
        print(f'Error: {response.status_code}')
        print(f'{response.text}')

                            

The returned bundle contains the (parameter right word?) link with the propeties(right word??)

  • relative
  • url

03

HTTP

 You can do the same thing as the examples above using POST in HTTP,
but with POST,
we have to use the _search parameter
and,  Add a Content-Type with the x-www-form-urlencoded directory

    @fhirUrl = http://hapi.fhir.org/baseR4/Patient
    POST {{fhirUrl}}/Patient/_search
    Accept: application/fhir+json
    Content-type:  x-www-form-urlencoded
    

04

python

 In python, Place Accept: 'application/fhir+json' and Content-Type: 'application/x-www-form-urlencoded' in the header
Add a dictionary called playload, by convention, to make a POST in python.

    import requests
    import json 

    fhir_url = 'http://hapi.fhir.org/baseR4/'
    endpoint = f'{fhir_url}/Patient/_search'
    headers = {
        'Accept': 'application/fhir+json',
        'Content-Type': 'application/x-www-form-urlencoded'
    }
    payload = {
        # place search parameters here
    }
    response = requests.post(endpoint, headers=headers, data=payload)
    if response.status_code == 200:
        fhir_data = response.json()
        pretty_fhir_data = json.dumps(fhir_data, indent=2)
        print(pretty_fhir_data)
    else:
        print(f'Error: {response.status_code}')
        print(f'{response.text}')

Part 5 - 'Common search Parameters' and 'Search control parameters' HTTP vs Python

01

 Here are all the 'Common Parameters for all resources' and 'Search control parameters'
https://hl7.org/fhir/search.html
 The Common Parameters for all resources apply to he 1st level of resources They are not required for any data bases but typically FHIR apis have these Parameters.

Common Parameters for all resources work on any resource if available in database, Search control parameters work on certain specific resources if available.

02

HTTP search parameter _id

In HTTP we can add the Common search Parameters such as _id, after the fhir_url in the GET request.

    @fhirUrl = http://hapi.fhir.org/baseR4/
    GET {{fhirUrl}}/Patient/592912
    Accept: application/fhir+json

This format returns the Patient type

03

This format returns the resources as a bundle

    @fhirUrl = http://hapi.fhir.org/baseR4
    GET {{fhirUrl}}/Patient?_id=592912
    Accept: application/fhir+json

You can access multiple ids with this format

    @fhirUrl = http://hapi.fhir.org/baseR4
    GET {{fhirUrl}}/Patient?_id=592912,592913
    Accept: application/fhir+json    

04

python search parameter _id GET

In python,

    import requests
    import json
    fhir_url = 'http://hapi.fhir.org/baseR4'
    patient_id = '592912'
    endpoint = f'{fhir_url}/Patient/{patient_id}'
    headers = {'Accept': 'application/fhir+json'}

    response = requests.get(endpoint,headers=headers)
    if response.status_code == 200:
        fhir_data = response.json()
        pretty_fhir_data = json.dumps(fhir_data, indent=2)
        print(pretty_fhir_data)
    else:
        print(f'Error: {response.status_code}')
        print(f'{response.text})

05

mulitple _ids in python

Here is one way of getting multiple _id numbers in python

    import requests
    import json
    fhir_url = 'http://hapi.fhir.org/baseR4'
    patient_ids = ['592912','592913']

    url = f"{fhir_url}/Patient?_id={','.join(patient_ids)}"
    headers = {
        'Accept': 'application/fhir+json'
    }
    response = reuqests.get(url,headers=headers)
    if response.status_code == 200:
        fhir_data = resonse.json()
        pretty_fhir_data = json.dumps(fhir_data, indent=2)
        print(pretty_fhir_data)
    else:
        print(f'Error: {response.status_code}')
        print(f'response.text')

06

Here is another way of using multiple patient _ids. using params

    import requests
    import json
    fhir_url = 'http://hapi.fhir.org/baseR4'
    patient_ids = ['592912','592913']
    url = f'{fhir_url}/Patient'
    query_params = {'_id': ','.join(patient_ids)}
    headers = {
    'Accept': 'application.fhir+json'
    }
    response = requests.get(url, params=query_params, headers=headers)
    if response.status_code == 200:
    fhir_data = response.json()
    pretty_fhir_data = json.dumps(fhir_data, indent=2)
    print(pretty_fhir_data)
    else:
    print(f'Error, {response.status_code}')
    print(f'{response.text}')

Part 6 - _format in url vs header (applicaiton/fhir+json or applicaiton/fhir+xml)

01

in xml http

You can place the _format in the url or in the headers argument. (The url will overide the header)

    @fhirUrl = http://hapi.fhir.org/baseR4
    GET {{fhirUrl}}/Patient?_id=592912,592913&_format=application/fhir+xml
    Accept: application/fhir+json

Part 7 - -Search Paramters of Resource 'Patient' ?given for name

01

Go to the bottom of a resource to find the resource's Search Parametes
https://hl7.org/fhir/patient.html

02

Use given as for the 'Search parameters' name
https://hl7.org/fhir/search.html#string

03

in http xml

    @fhirUrl = http://hapi.fhir.org/baseR4
    GET {{fhirUrl}}/Patient?given=eve
    Accept: application/fhir+json

04

in python

    import requests
    import json
    fhir_url = 'http://hapi.fhir.org/baseR4/'
    search_params = {
        'given':'eve'
    }
    url = f'{fhir_url}Patient'
    headers = {
        'Accept': 'application/fhir+json'
    }
    response = requests.get(url, params=search_params,headers=headers)
    if response.status_code == 200:
        fhir_data = response.json()
        pretty_data = json.dumps(fhir_data,indent=2)
        print(pretty_data)
    else:
        print(f'Error: {response.status_code}')
        print(f'{response.text}')

Part 8 - 'Common search Parameters' _ and 'Search control parameters' _nounderscore Documentation

01

Anyting with _ is a top level 'Common Parameters'
is top level search parameter that should work on any resource such as:
_id, _has, _security, _lastUpdated
Link to page seach for:

    Summary table

at https://hl7.org/fhir/search.html

02

Put metadata at the end of the base url

    http://hapi.fhir.org/baseR4

You can find these parameters in
CapabilityStatment → 'rest' → 'resource' → 'searchParam'

Anything without a under score is something i don't get yet

03

The CapabilityStatment documentaion can be found here
https://hl7.org/fhir/capabilitystatement.html
I'm a little confused here I think ones without the _ are search parameters for the specific resource

Part 9 - everything

01

Certain Search Parameters not part of the fhir spec and part of the servers will be found

    import requests
    import json
    fhir_url = 'http://hapi.fhir.org/baseR4/'
    # search_params = {
    #     'given':'eve'
    # }
    url = f'{fhir_url}Patient'
    headers = {
        'Accept': 'application/fhir+json'
    }
    # response = requests.get(url, params=search_params,headers=headers)
    response = requests.get(url,headers=headers)
    if response.status_code == 200:
        fhir_data = response.json()
        pretty_data = json.dumps(fhir_data,indent=2)
        with open('CapabilityStatent.json','w') as f:
            f.write(pretty_data)
            f.close()
        print(pretty_data)
    else:
        print(f'Error: {response.status_code}')
        print(f'{response.text}')

Patient → 'entry' → 'resource' → 'operation'