├── .gitignore ├── CRUD operations ├── img │ ├── curl.png │ ├── pic1.png │ ├── pic10.png │ ├── pic11.png │ ├── pic12.png │ ├── pic13.png │ ├── pic2.png │ ├── pic3.png │ ├── pic4.png │ ├── pic5.png │ ├── pic6.png │ ├── pic7.png │ ├── pic8.png │ ├── pic9.png │ ├── post-clients.png │ └── postman-example.png └── lesson.md ├── FHIRPath └── lesson.md ├── Profiling ├── images │ ├── Conformance_resources_relationship.png │ └── Profiling_context.png ├── lesson.md └── profile_examples │ ├── ObservationProfile.json │ ├── PatientProfile.json │ └── PractitionerProfile.json ├── README.md ├── SearchParameter ├── images │ ├── DefaultSearchParameterPatient.png │ ├── SearchParameterDeclaration.png │ └── SearchParameterResource.png └── lesson.md ├── Search_References_ChainHasIncludeRevinclude ├── images │ └── graph.png └── lesson.md ├── Terminology └── CodeSystem_and_ValueSet │ ├── img │ └── ValueSet.svg │ └── lesson.md ├── Transactions ├── img │ ├── bundle-types.png │ ├── fhir-bundle.png │ └── paging.png └── lesson.md └── examples └── Search_References_ChainHasIncludeRevinclude ├── FHIR_Tutorial_Series_FHIR_Search_References_Flow.svg ├── test-data-1.json └── test-data-2.json /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # IDEs and editors 4 | /.idea 5 | .project 6 | .classpath 7 | .c9/ 8 | *.launch 9 | .settings/ 10 | *.sublime-workspace 11 | 12 | # IDE - VSCode 13 | .vscode/* 14 | !.vscode/settings.json 15 | !.vscode/tasks.json 16 | !.vscode/launch.json 17 | !.vscode/extensions.json 18 | 19 | # System Files 20 | .DS_Store 21 | Thumbs.db 22 | .vscode/settings.json 23 | -------------------------------------------------------------------------------- /CRUD operations/img/curl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hapifhir/fhir-tutorial/0f64c6fdfc24752a591d870cdb98554ab8a754b0/CRUD operations/img/curl.png -------------------------------------------------------------------------------- /CRUD operations/img/pic1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hapifhir/fhir-tutorial/0f64c6fdfc24752a591d870cdb98554ab8a754b0/CRUD operations/img/pic1.png -------------------------------------------------------------------------------- /CRUD operations/img/pic10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hapifhir/fhir-tutorial/0f64c6fdfc24752a591d870cdb98554ab8a754b0/CRUD operations/img/pic10.png -------------------------------------------------------------------------------- /CRUD operations/img/pic11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hapifhir/fhir-tutorial/0f64c6fdfc24752a591d870cdb98554ab8a754b0/CRUD operations/img/pic11.png -------------------------------------------------------------------------------- /CRUD operations/img/pic12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hapifhir/fhir-tutorial/0f64c6fdfc24752a591d870cdb98554ab8a754b0/CRUD operations/img/pic12.png -------------------------------------------------------------------------------- /CRUD operations/img/pic13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hapifhir/fhir-tutorial/0f64c6fdfc24752a591d870cdb98554ab8a754b0/CRUD operations/img/pic13.png -------------------------------------------------------------------------------- /CRUD operations/img/pic2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hapifhir/fhir-tutorial/0f64c6fdfc24752a591d870cdb98554ab8a754b0/CRUD operations/img/pic2.png -------------------------------------------------------------------------------- /CRUD operations/img/pic3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hapifhir/fhir-tutorial/0f64c6fdfc24752a591d870cdb98554ab8a754b0/CRUD operations/img/pic3.png -------------------------------------------------------------------------------- /CRUD operations/img/pic4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hapifhir/fhir-tutorial/0f64c6fdfc24752a591d870cdb98554ab8a754b0/CRUD operations/img/pic4.png -------------------------------------------------------------------------------- /CRUD operations/img/pic5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hapifhir/fhir-tutorial/0f64c6fdfc24752a591d870cdb98554ab8a754b0/CRUD operations/img/pic5.png -------------------------------------------------------------------------------- /CRUD operations/img/pic6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hapifhir/fhir-tutorial/0f64c6fdfc24752a591d870cdb98554ab8a754b0/CRUD operations/img/pic6.png -------------------------------------------------------------------------------- /CRUD operations/img/pic7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hapifhir/fhir-tutorial/0f64c6fdfc24752a591d870cdb98554ab8a754b0/CRUD operations/img/pic7.png -------------------------------------------------------------------------------- /CRUD operations/img/pic8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hapifhir/fhir-tutorial/0f64c6fdfc24752a591d870cdb98554ab8a754b0/CRUD operations/img/pic8.png -------------------------------------------------------------------------------- /CRUD operations/img/pic9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hapifhir/fhir-tutorial/0f64c6fdfc24752a591d870cdb98554ab8a754b0/CRUD operations/img/pic9.png -------------------------------------------------------------------------------- /CRUD operations/img/post-clients.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hapifhir/fhir-tutorial/0f64c6fdfc24752a591d870cdb98554ab8a754b0/CRUD operations/img/post-clients.png -------------------------------------------------------------------------------- /CRUD operations/img/postman-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hapifhir/fhir-tutorial/0f64c6fdfc24752a591d870cdb98554ab8a754b0/CRUD operations/img/postman-example.png -------------------------------------------------------------------------------- /CRUD operations/lesson.md: -------------------------------------------------------------------------------- 1 | # FHIR CRUD operations 2 | 3 | 4 | ## FHIR CRUD references: 5 | 6 | - Introduction 7 | - HTTP post clients 8 | - Getting first resource from the FHIR server 9 | - Updating resource in the FHIR server 10 | - Adding a new resource to the FHIR server 11 | - Deleting the resource in the FHIR server 12 | - Group Discussion and Q&A 13 | 14 | 15 | ## Introduction 16 | 17 | In this tutorial, we will walk through the basic CRUD operations. 18 | 19 | CRUD stands for Create, Read, Update & Delete. These are the four main actions that you will use to interact with the FHIR resources within a FHIR server. 20 | 21 | REST stands for 'Representational state transfer' and RESTFul just means a system that conforms to the constraints of REST. 22 | 23 | Understanding these four operations is essential to working with any RESTful service which a FHIR server is an implementation of. 24 | 25 | 26 | ## Step 1: Http post clients 27 | 28 | The simplest way to retrieve and send FHIR resources to and from a FHIR server is to use a Http post client. 29 | The most popular clients are Postman and Insomnia. Each of them has pros and cons. 30 | 31 | ![POST clients](img/post-clients.png) 32 | 33 | What is a post client? It is a tool that allows you to talk to servers using Hypertext Transfer Protocol (HTTP). 34 | When you use an internet browser the browser is converting your clicks and text into HTTP to send to the web server and the server returns content, 35 | your web page, back via HTTP. The browser then interprets the content as a web page and displays it on screen. When we work with FHIR the content is not a web page but rather XML or JSON. 36 | Our web browser is not very good at displaying raw XML or JSON so we need a HTTP client so that we can talk in HTTP and view the XML or JSON returned. 37 | 38 | If you don’t want to use any post clients, you can use curl. 39 | Curl is a tool which can be used to execute HTTP requests from the command line, and is commonly installed on Linux/OSX systems. 40 | Terminal command: man curl 41 | 42 | ![curl](img/curl.png) 43 | 44 | Example of GET request with curl: curl -v GET https://try.smilecdr.com:8000/Patient/37078 45 | 46 | - -v [options] provide more details 47 | 48 | The good example of using the Postman application 49 | 50 | ![postman example](img/postman-example.png) 51 | 52 | ## Step 2: Getting your first resource from the FHIR server 53 | 54 | ### FHIR Read / vRead 55 | If you know the ID of a resource on a FHIR server, you can read back the most recent version of that resource by performing a read operation. 56 | The read uses an HTTP GET against the URL [baseUrl]/[resourceType]/[id]. 57 | 58 | ![example1](img/pic1.png) 59 | 60 | You can also include a version string in the URL in order to request a specific version of the resource by performing a vread operation. 61 | The vread uses an HTTP GET against the URL [baseUrl]/[resourceType]/[id]/_history/[versionId]. 62 | You can execute this request with cURL using the following command: 63 | 64 | ![example2](img/pic2.png) 65 | 66 | ## Step 3: Updating your resource in the FHIR server 67 | 68 | ### FHIR update 69 | You can update an existing resource on a FHIR server by performing an update operation. The update uses an HTTP PUT against the URL [baseUrl]/[resourceType]/[id]. 70 | This PUT should have (at a minimum) a Content-Type header that specifies the MIME type of the payload. 71 | We used the Accept property to tell the server the format (XML or JSON) we wanted to be returned by the server. 72 | 73 | ![example3](img/pic3.png) 74 | 75 | The following example shows a simple update using a JSON payload. In this example, we are taking the previously created resource from above and updating it. 76 | We will change the birth date and add an address. Note the ID 37078 in the URL, resource body and headers. When you are trying this yourself, 77 | make sure to use the ID that was returned from the server in the steps above. 78 | 79 | ![example4](img/pic4.png) 80 | 81 | Curl example: 82 | 83 | ![example5](img/pic5.png) 84 | 85 | ### FHIR Patch 86 | You can patch a resource on a FHIR server by performing a patch operation. The patch uses an HTTP PATCH agaisnt the URL [baseUrl]/[resourceType]/[id]. 87 | This operation requries a Content-Type header that specifies the MIME type of the payload. For a JSON patch payload the header value would be: application/json-patch+json. 88 | For a XML patch payload the header value would be: application/xml-patch+xml. The body of the PATCH payload must be in a specific format for JSON and XML requests. 89 | 90 | ![example6](img/pic6.png) 91 | 92 | ## Step 4: Adding a new resource to the FHIR server 93 | 94 | ### FHIR Create 95 | A client may create a new resource on a FHIR server by performing a Create operation. The create uses an HTTP POST against the URL [baseUrl]/[resourceType]. 96 | This POST should have (at a minimum) a Content-Type header which specifies the mimetype of the payload. The following example shows a simple create using a JSON Payload. 97 | 98 | ![example7](img/pic7.png) 99 | 100 | Curl example: 101 | 102 | ![example8](img/pic8.png) 103 | 104 | ## Step 5: Deleting a resource from the FHIR server 105 | 106 | ### FHIR Delete 107 | You can delete a resource on a FHIR server by performing a delete operation. The delete uses an HTTP DELETE against the URL [baseUrl]/[resourceType]/[id]. 108 | This operation performs a logical delete, which has a specific set of semantics: The resource is marked as deleted, and it will no longer appear in search results. 109 | The version number of the resource is incremented (essentially, a new deleted version is created). Previous versions of the resource are not physically deleted. 110 | The resource may be un-deleted by updating it again. The following example shows a simple delete of the resource created and updated in the examples above. 111 | Curl example: curl -v -X DELETE https://try.smilecdr.com:8000/Patient/37078 112 | 113 | ![example9](img/pic9.png) 114 | 115 | ### Cascading Delete 116 | With cascading deletes enabled, a user can perform the delete on Patient/A and all of the child resources will be deleted as well. 117 | In order to perform a cascading delete, three things must occur: Cascading Deletes Enabled setting must be enabled on the FHIR Storage module. 118 | Then, the user performing the operation must have the FHIR_DELETE_CASCADE_ALLOWED permission, as well as a specific permission allowing the child resource to be deleted. 119 | For example, you might grant the user the FHIR_DELETE_CASCADE_ALLOWED and FHIR_ALL_DELETE permissions. 120 | Finally, to perform a cascaded delete, the client HTTP request must include either a special URL parameter (_cascade) or a special header to indicate that a cascading delete is desired. 121 | 122 | Example: DELETE /Patient/123?_cascade=delete 123 | 124 | ### Transactional Delete 125 | The FHIR Transaction operation can be used to delete multiple resources at the same time. 126 | This is useful if you have chains or collections of resources to delete at ones, but also can be used to delete circular references. 127 | To delete multiple resources in a transaction, POST a Bundle such as the following to the root of your FHIR endpoint. 128 | 129 | ![example10](img/pic10.png) 130 | 131 | ### Expunge operation ($expunge) 132 | In some cases we need to completely delete data from the server. 133 | The $expunge operation is a powerful operation that can physically delete old versions of resources, deleted resources, or even all data in the database. 134 | 135 | ![example11](img/pic11.png) 136 | 137 | ### Instance level expunge 138 | The $expunge operation can be invoked against a single resource instance, or even an individual version of a resource instance. If invoked at the instance level 139 | 140 | ![example12](img/pic12.png) 141 | 142 | ### Type level expunge 143 | The $expunge operation can be invoked at the type level. In this mode, all resources of a given type will be processed with the same rules as at the instance level. 144 | 145 | ![example13](img/pic13.png) 146 | 147 | ## Group discussions and QA: 148 | 149 | 1. What does idempotent means in REST api? 150 | 1. What are the basic methods used for CRUD operations? 151 | 1. Which method is used to update the resource? 152 | 1. PUT and PATCH method difference? 153 | 1. PUT and POST method difference? 154 | 1. How to update Organisation resource, any example request? 155 | 1. Write the URL to delete the patient resource. 156 | 1. Mention which markup language can be used in restful api? 157 | 158 | 159 | 160 | 161 | 162 | 163 | -------------------------------------------------------------------------------- /FHIRPath/lesson.md: -------------------------------------------------------------------------------- 1 | # FHIRPath: JsonPath/XPath for Fhir! 2 | 3 | ## What is it 4 | FHIRPath is a standard by which a formal representation of logic can be applied to FHIR Resources in a reproducible manner. It is used for both resource navigation and extraction of data from resources. FHIRPath allows you to programmatically retrieve only portions of data you care about, or portions that fulfill some given criteria. All official implementations are listed [here](https://wiki.hl7.org/index.php?title=FHIRPath_Implementations), and if you want a playground to play around in, you can check out [this online tool](https://hl7.github.io/fhirpath.js/). If you are familiar with JSONPath or XMLPath, you are already halfway towards understanding the abilities and purpose of FHIRPath. 5 | 6 | ## Resource Navigation 7 | 8 | FHIRPath can be used for navigating through resources. Consider the following Patient 9 | ```json 10 | { 11 | "resourceType": "Patient", 12 | "id": "1553", 13 | "name": [ 14 | { 15 | "family": "Smith", 16 | "given": [ 17 | "John", 18 | "Scott" 19 | ] 20 | } 21 | ], 22 | "telecom": [ 23 | { 24 | "use": "home", 25 | "system": "email" 26 | }, 27 | { 28 | "use": "work", 29 | "value": "(1) 226 791 5555", 30 | "system": "phone" 31 | } 32 | } 33 | ``` 34 | To use FHIRPath to list the Patient's given names, the query would look like this: 35 | ```bash 36 | > Patient.name.given 37 | {"John", "Scott"} 38 | ``` 39 | The FHIRPath evaluator will return the requested query as a collection of elements. Note that it is always a collection that is returned, even if it is only a single element: 40 | ```bash 41 | > Patient.name.family 42 | {"Smith"} 43 | ``` 44 | This may seem like an odd thing to do; The reason for this is in the documentation: 45 | ``` 46 | Collection-centric: FHIRPath deals with all values as collections, allowing it to easily deal with information models with repeating elements. 47 | ``` 48 | Since everything is a collection, you can safely call collection methods on the results of a FHIRPath query: 49 | ```bash 50 | > Patient.name.given.first() 51 | {"John"} 52 | ``` 53 | Some examples of such methods are `first()`, `last()`,`tail()`,`skip()`, and `children()`. Documentation for these can be found in the [functions documentation](http://hl7.org/fhirpath/#functions). 54 | While everything in FHIRPath evaluation is a collection, it also does singleton collection evaluation. This allows you to perform the following expressions without having to select precisely which index of value you want: 55 | ```bash 56 | > Patient.name.family + " " + Patient.name.family 57 | {"Smith Smith"} 58 | ``` 59 | `Warning`: This only works when the elements are actually singletons. In the following case, the FHIRPath evaluator will throw an error: 60 | ```bash 61 | > Patient.name.given + " " + Patient.name.family 62 | ERROR 63 | ``` 64 | This happens since `Patient.name.first` is not a singleton collection, but contains two elements. To correct this, you need to specify which index of the collection you want to use. 65 | ```bash 66 | > Patient.name.given[0] + " " + Patient.name.family 67 | {"John Smith"} 68 | > Patient.name.given.last() + " " + Patient.name.family 69 | {"Scott Smith"} 70 | ``` 71 | 72 | ## Polymorphism in navigation and selection 73 | Oftentimes collections of data in a FHIR resource are not all of the same type. For example, an `Observation` may have several type options for `value`. It could potentially be `Quantity`, or may be `boolean`, and a host of other options. Consider the following Query: 74 | ``` 75 | > Observation.value.unit #This will return units for all value types. 76 | > Observation.value.ofType(Quantity).unit #This will return units only if the value is a Quantity 77 | ``` 78 | `ofType()` will add only elements matching the type to the returned collection. 79 | 80 | ## Expressions 81 | 82 | When you query a FHIRPath evaluator, what you are passing it is called an `Expression`. FHIRPath expressions can consist of paths, literals, operators, and function invocations, 83 | 84 | * Paths are things like `Patient.name.given`, `Observation.value` 85 | * Literals are things like `'a'`, `true`, `0`, `@2020-02-04` 86 | * Operators are things like `/`, `>`, `|` 87 | * Function invocations are things like `.where()` , `.count()` , `.substring()` 88 | 89 | ```bash 90 | > Observation.value is Quantity 91 | true 92 | ``` 93 | 94 | ### Filtering and projection of results in expressions 95 | There are cases where you may not want _all_ of a collection. For example, what if you want all of a Patient's Telecom nodes, but only the ones which have a value of `system=phone` (e.g. you only want their phone numbers: 96 | ```bash 97 | > Patient.telecom.where(system='phone').value 98 | {"(1) 226 791 5555"} 99 | ``` 100 | the `.where()` function will be called on each element in the collection, and add it to the resulting collection if the criteria in the `.where()` evaluates to true. 101 | 102 | Similarly, if you have a collection of elements and want to select with criteria from it, you can use the projection function `select()` in order to select from the collection stream. For example, imagine for a moment that our patient from above had another name on top of their first name entry: 103 | 104 | 105 | ```bash 106 | > Bundle.entry.select(resource as Patient) 107 | # This returns a collection of patients that were entries in the bundle, and ignores all non-patient resources. 108 | 109 | > Bundle.entry.select((resource as Patient).telecom.where(system = 'phone')) 110 | # This returns a collection of telecoms where system=phone from each resource in the bundle that was a patient. 111 | ``` 112 | Now let's imagine our patient from earlier had a second name on top of their first one, like so: 113 | ```json 114 | { 115 | "family": "Smith2", 116 | "given": [ 117 | "Frank" 118 | ] 119 | } 120 | ``` 121 | 122 | ### Crossing Resource Boundaries 123 | Occasionally there are contained resources held within a given resource. Normally, FHIRPath cannot resolve these automatically, so there is a function in the spec called `resolve()` which will allow you to resolve a contained resource. The actual implementation and functionality is up to the FHIRContext evaluating the request, so it is not strictly defined in the spec. However, here is a sample query showing the usage of resolve: 124 | ```bash 125 | CareTeam.member.resolve().ofType(Practitioner).name.given.first() 126 | ``` 127 | This query returns a collection of all the first given names of all the Practitioners that are members of a CareTeam. 128 | 129 | 130 | Consider this query which will generate a collection of two strings, each representing a full name from a name element. 131 | ```bash 132 | > Patient.name.select(given.first() + ' ' + family) 133 | {"John Smith", "Frank Smihth2"} 134 | 135 | ``` 136 | 137 | ### Aggregations 138 | 139 | You can write general purpose aggregations, which follow the same rules as other functions, but you also have access to the special $total variable while inside. The signature of such a method is `.aggregate(aggregator: expression [, init: value])` 140 | For example, this will generate a sum of all the data of all SampledData values in all observations in a bundle. 141 | ```bash 142 | Bundle.entry 143 | .select(resource as Observation).value 144 | .ofType(SampledData) 145 | .aggregate($this.data + $total, 0) 146 | 147 | ``` 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | -------------------------------------------------------------------------------- /Profiling/images/Conformance_resources_relationship.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hapifhir/fhir-tutorial/0f64c6fdfc24752a591d870cdb98554ab8a754b0/Profiling/images/Conformance_resources_relationship.png -------------------------------------------------------------------------------- /Profiling/images/Profiling_context.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hapifhir/fhir-tutorial/0f64c6fdfc24752a591d870cdb98554ab8a754b0/Profiling/images/Profiling_context.png -------------------------------------------------------------------------------- /Profiling/lesson.md: -------------------------------------------------------------------------------- 1 | # [FHIR Profiling](https://www.hl7.org/fhir/profiling.html) 2 | 3 | 4 | ## Definition 5 | 6 | * Adapting the FHIR specifications to a particular context of use. 7 | * Variation in context across the world in the healthcare ecosystem 8 | 9 | ![Profiling Context](./images/Profiling_context.png) 10 | 11 | ## Conformance Module 12 | 13 | * Conformance resources represent the adaptations in a computable fashion 14 | * **Implementation Guide (IG)** :- describes how FHIR is adapted to support a certain use case. 15 | * **Capability Statement** :- Uses Conformance resource to document how a client or server has implemented FHIR 16 | 17 | ## Conformance Resource 18 | 19 | * **StructureDefinition Resource** :- Defines how resources, extensions and data types are used. 20 | * **MessageDefinition Resource** :- Describes messages that can be sent or received 21 | * **OperationDefinition Resource** :- Describes addition operations in addition to the base specifications 22 | * **SearchParameter Resource** :- Describes additional search capabilities in addition to the base definition 23 | * **CompartmentDefinition Resource** :- Describes a logical grouping for resources (used in access control or search) 24 | 25 | 26 | ![Conformance Resources Relationship](./images/Conformance_resources_relationship.png) 27 | 28 | ## StructureDefinition Resource 29 | 30 | * This resource is used to define FHIR data structures :- 31 | * Resource 32 | * Extension 33 | * DataTypes 34 | * Implementors can use this resource to make constraints on the base definition 35 | 36 | #### StructureDefinition Resource Properties 37 | 38 | * **url** :- Unique identifier for StructureDefinition 39 | * **name** :- Name of the StructureDefinition 40 | * **baseDefinition** :- base of the current StructureDefinition 41 | * **Snapshot** :- This is a fully calculated form of structure 42 | * **Differential** :- Only contains constraints made onto the base structure, anything not mentioned in statement is implied to have no changes from the base 43 | 44 | ## $snapshot operation 45 | 46 | * Generates a StructureDefinition instance with a `snapshot` based on the differential in a specified StructureDefinition. 47 | * In orde to generate a valid `snapshot`, `baseDefinition` of a StrcutureDefinition must have a valid snapshot. 48 | * Query Structure :- 49 | * POST :- [base]/StructureDefinition/$snapshot 50 | * GET, PUT :- [base]/StructureDefinition/[id]/$snapshot 51 | 52 | ## Slicing 53 | 54 | * Slicing is basically restrictions on each element of a resource property with `cardinality >= 1`. 55 | * **Discriminator** :- In order to differentiate between slices, each resource element which is slices will include a property known as the `discriminator` to tell them apart. The `discriminator` consists of two mandatory fields :- 56 | * Type :- Slice Type 57 | * Path :- FHIRPath expression 58 | 59 | #### Slice Types 60 | 61 | | Type | Use | Scenario | 62 | |---------|-------------------------------------------------|----------------------------------------------------------------------------------------------| 63 | | value | Static comparison | Usually used for comparing static codes | 64 | | exists | If the property exists & then another condition | Usually used for Backboneelements | 65 | | pattern | Comparing pattern | Usually used for CodeSystems like LOINC, SNOMED CT | 66 | | type | value[x]/pattern[x] | Usually used for resource properties which support more than one datatype or primitive types | 67 | | profile | Validate data type against profile | Used for validating datatype with a custom profile | 68 | 69 | #### Slicing Rules 70 | 71 | When an element of a fixed cardinality m..n is sliced, the following rules apply: - 72 | * Each slice cannot have a greater cardinality than the maximum number of slices allowed. 73 | * The sum of the maximum cardinalities can be larger than n. 74 | * The sum of the minimum cardinalities must be less or equal to n. 75 | * Each individual slice can have a minimum cardinality of 0 (less than m - the only situation where this is allowed), but the total number of elements in the instance must still be greater or equal to m. 76 | 77 | 78 | ## $validate Operation 79 | 80 | * The validate operation checks whether the attached content would be acceptable while performing CRUD operations. 81 | * Query structure :- 82 | * POST :- [base]/Resource/$validate 83 | * GET, PUT, DELETE :- [base]/Resource/[id]/$validate 84 | 85 | ## Extensions 86 | 87 | * Creating extensions inside a profile by using a StructureDefinition resource 88 | * Define context i.e. where can it be used, target structure: resource, datatype, extension 89 | * Example :- [US Core Patient Profile](https://www.hl7.org/fhir/us/core/StructureDefinition-us-core-patient.html) 90 | -------------------------------------------------------------------------------- /Profiling/profile_examples/ObservationProfile.json: -------------------------------------------------------------------------------- 1 | { 2 | "resourceType": "StructureDefinition", 3 | "url": "http://hapi.fhir.org/baseR4/StructureDefinition/DiabetesObservationProfile", 4 | "name": "DiabetesObservationProfile", 5 | "status": "active", 6 | "kind": "resource", 7 | "abstract": false, 8 | "derivation": "specialization", 9 | "baseDefinition": "http://hl7.org/fhir/StructureDefinition/Observation", 10 | "type": "Observation", 11 | "differential": { 12 | "element": [ 13 | { 14 | "min": 0, 15 | "max": "3", 16 | "id": "Observation.category", 17 | "path": "Observation.category", 18 | "definition": "A code that classifies the general type of observation being made.", 19 | "slicing": { 20 | "discriminator": [ 21 | { 22 | "type": "pattern", 23 | "path": "coding" 24 | }, 25 | { 26 | "type": "pattern", 27 | "path": "coding" 28 | } 29 | ], 30 | "rules": "open", 31 | "ordered": false 32 | } 33 | }, 34 | { 35 | "min": 0, 36 | "max": "1", 37 | "id": "Observation.category:Systolic", 38 | "path": "Observation.category", 39 | "sliceName": "Systolic", 40 | "patternCodeableConcept": { 41 | "coding": [ 42 | { 43 | "code": "8480-6", 44 | "display": "Systolic" 45 | } 46 | ] 47 | } 48 | }, 49 | { 50 | "min": 0, 51 | "max": "1", 52 | "id": "Observation.category:Diastolic", 53 | "path": "Observation.category", 54 | "sliceName": "Diastolic", 55 | "patternCodeableConcept": { 56 | "coding": [ 57 | { 58 | "code": "8462-4", 59 | "display": "Diastolic" 60 | } 61 | ] 62 | } 63 | } 64 | ] 65 | } 66 | } -------------------------------------------------------------------------------- /Profiling/profile_examples/PatientProfile.json: -------------------------------------------------------------------------------- 1 | { 2 | "resourceType": "StructureDefinition", 3 | "url": "http://hapi.fhir.org/baseR4/StructureDefinition/PatientProfile", 4 | "name": "PatientProfile", 5 | "status": "active", 6 | "kind": "resource", 7 | "abstract": false, 8 | "derivation": "specialization", 9 | "baseDefinition": "http://hl7.org/fhir/StructureDefinition/Patient", 10 | "type": "Patient", 11 | "differential": { 12 | "element": [ 13 | { 14 | "min": 0, 15 | "max": "2", 16 | "id": "Patient.extension", 17 | "path": "Patient.extension", 18 | "definition": "Optional Extension Element - found in all resources.", 19 | "slicing": { 20 | "discriminator": [ 21 | { 22 | "type": "type", 23 | "path": "$this" 24 | } 25 | ], 26 | "rules": "open", 27 | "ordered": false 28 | } 29 | }, 30 | { 31 | "min": 1, 32 | "max": "1", 33 | "id": "Patient.extension.value[x]:BirthPlaceSlice", 34 | "path": "Patient.extension.value[x]", 35 | "sliceName": "BirthPlaceSlice", 36 | "type": [ 37 | { 38 | "code": "string" 39 | } 40 | ] 41 | } 42 | ] 43 | } 44 | } -------------------------------------------------------------------------------- /Profiling/profile_examples/PractitionerProfile.json: -------------------------------------------------------------------------------- 1 | { 2 | "resourceType": "StructureDefinition", 3 | "url": "http://hapi.fhir.org/baseR4/StructureDefinition/PractitionerProfile", 4 | "name": "PractitionerProfile", 5 | "status": "active", 6 | "kind": "resource", 7 | "abstract": false, 8 | "derivation": "specialization", 9 | "baseDefinition": "http://hl7.org/fhir/StructureDefinition/Practitioner", 10 | "type": "Practitioner", 11 | "differential": { 12 | "element": [ 13 | { 14 | "min": 1, 15 | "max": "3", 16 | "id": "Practitioner.telecom", 17 | "path": "Practitioner.telecom", 18 | "definition": "A contact detail for the practitioner, e.g. a telephone number or an email address.", 19 | "slicing": { 20 | "discriminator": [ 21 | { 22 | "type": "value", 23 | "path": "use" 24 | } 25 | ], 26 | "rules": "open", 27 | "ordered": false 28 | } 29 | }, 30 | { 31 | "min": 1, 32 | "max": "1", 33 | "id": "Practitioner.telecom:practitioner_home_phone", 34 | "path": "Practitioner.telecom", 35 | "sliceName": "practitioner_home_phone", 36 | "fixedContactPoint": { 37 | "use": "home" 38 | } 39 | } 40 | ] 41 | } 42 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FHIR Tutorial 2 | 3 | This is the home of the FHIR Tutorial, an open collaborative effort to develop a training package, led by the team at [Smile CDR](https://smilecdr.com). 4 | 5 | Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License. 6 | 7 | # Table of Contents 8 | 9 | Note: These are not being created in their final order, so they are not (yet) intended to be read sequentially. 10 | 11 | * [Search / References / Chain, *_has*, *_include*, *_revinclude*](Search_References_ChainHasIncludeRevinclude/lesson.md) 12 | 13 | * [FHIRPath](FHIRPath/lesson.md) 14 | 15 | * [Transactions](Transactions/lesson.md) 16 | 17 | * [REST CRUD operations - Create, Read, Update, Delete](CRUD%20operations/lesson.md) 18 | 19 | * [Search Parameter Types](SearchParameter/lesson.md) 20 | 21 | * [Profiling](Profiling/lesson.md) 22 | 23 | * [Terminology - CodeSystem & ValueSet](Terminology/CodeSystem_and_ValueSet/lesson.md) 24 | -------------------------------------------------------------------------------- /SearchParameter/images/DefaultSearchParameterPatient.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hapifhir/fhir-tutorial/0f64c6fdfc24752a591d870cdb98554ab8a754b0/SearchParameter/images/DefaultSearchParameterPatient.png -------------------------------------------------------------------------------- /SearchParameter/images/SearchParameterDeclaration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hapifhir/fhir-tutorial/0f64c6fdfc24752a591d870cdb98554ab8a754b0/SearchParameter/images/SearchParameterDeclaration.png -------------------------------------------------------------------------------- /SearchParameter/images/SearchParameterResource.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hapifhir/fhir-tutorial/0f64c6fdfc24752a591d870cdb98554ab8a754b0/SearchParameter/images/SearchParameterResource.png -------------------------------------------------------------------------------- /SearchParameter/lesson.md: -------------------------------------------------------------------------------- 1 | # FHIR Search Parameters 2 | 3 | ## Definition 4 | 5 | - A search parameter defines a named search item that can be used to search/filter on a FHIR resource. 6 | - A SearchParameter resource is a FHIR resource that can be used to define/describe a search parameter supported by a given server. 7 | 8 | 9 | ## What does SearchParameter resource declare ? 10 | 11 | ![What does SearchParameter resource declare](./images/SearchParameterDeclaration.png) 12 | 13 | ## Default SearchParameter for Patient.gender 14 | 15 | ![Default SearchParameter for Patient.gender](./images/DefaultSearchParameterPatient.png) 16 | 17 | Default Search Parameter Registry :- [http://hl7.org/fhir/searchparameter-registry.html](http://hl7.org/fhir/searchparameter-registry.html). 18 | 19 | 20 | ## SearchParameter Types 21 | 22 | | Type | Definition | 23 | |---------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 24 | | Number | Whole number or decimal | 25 | | Date/DateTime | Date and time parameter formatted as: | 26 | | String | Simple string. Case and accent insensitive. May contain spaces. | 27 | | URI | Uniform Resource Identifier. Example: | 28 | | Token | Used for values that are part of a code system or namespace.
Includes: Can include both a code system and code value or just a code value.
Examples. | 29 | | Quantity | Used for quantity values that include a numeric value and possibly a unit of measure code.The unit of measure code will include a code value and optionally a code system.
Examples: | 30 | | Reference | Used for values that represent references between resources. For example an Observation resource will normally have a subject element which references a Patient resource for the patient that then Observation relates to.
Can include :Examples: | 31 | | Composite | Used in cases where a single search definition requires two or more values. SearchParameter values appear in the search request as a list of single values joined with a `$` character.
Examples: In the above example, the SearchParameter consists of two values, joined by `$`: | 32 | | _filter | Used to specify a query expression that can be used in a Search operation.
Example: | 33 | | near | Used only with Location resource. Specifies a set of coordinates expressed as coordinates expressed as [latitude]\|[longitude]\|[distance]\|[units] | 34 | 35 | ## SearchParameter Modifiers 36 | 37 | 39 | 40 | | Parameter Type | Operator | Description | 41 | |---------------------|-------------|------------------------------------------------------------------------------------------| 42 | | All Parameter types | :missing | | 43 | | String Parameter | :exact | Resources which have an exact match for the parameter, including case and character. | 44 | | Token Parameter | :text | Matches on text portion of CodeableConcept or Coding element. | 45 | | Token Parameter | :not | Match resources that do not have the code value. | 46 | | Token Parameter | :above | Match where coding subsumes the search code parameter. | 47 | | Token Parameter | :below | Match where coding is subsumed by the search code parameter. | 48 | | Token Parameter | :in | Match where coding is in a value set specified by the parameter. | 49 | | Token Parameter | :not-in | Match where coding is not in the value set specified by the parameter | 50 | | Token Parameter | :of-type | Match where identifier element is of specified type. | 51 | | Reference Parameter | :[type] | Specify the name of the resource type for reference | 52 | | Reference Parameter | :identifier | Search by identifier rather than literal reference. | 53 | | Reference Parameter | :above | Search for references in hierarchy | 54 | | Reference Parameter | :below | Search for references in hierarchy | 55 | | URI Parameter | :above | Partial matching (e.g. URLs that include a version number) | 56 | | URI Parameter | :below | Partial matching | 57 | 58 | ## SearchParameter Prefixes 59 | 60 | 61 | 62 | | Operator | Description | 63 | |----------|---------------------------------------------------------------------------| 64 | | eq | Value in resource matches or is contained in value for parameter | 65 | | gt | Value in resource is greater than value in parameter. | 66 | | lt | Value in resource is less than value parameter. | 67 | | ge | Value in resource is greater than or equal to value in parameter. | 68 | | le | Value in resource is less than or equal to value in parameter. | 69 | | sa | Value in the resource starts after value in parameter. | 70 | | eb | Value in the resource ends before value in parameter. | 71 | | ap | Value in the resource is approximately the same as that in the parameter. | 72 | 73 | 74 | ## SearchParameter Resource 75 | 76 | ![SearchParameter Resource](./images/SearchParameterResource.png) 77 | 78 | #### Required Elements 79 | 80 | | Element Name | Type | Description | 81 | |--------------|----------|-----------------------------------------------------------------| 82 | | url | uri | Canonical identifier for the resource | 83 | | name | string | Computer friendly name for the resource | 84 | | status | code | Status of the resource | 85 | | description | markdown | Natural language description for the search parameter | 86 | | code | code | Code used to reference the search parameter in a search request | 87 | | base | code | Resource type(s) that this search parameter applies to | 88 | | type | code | The data type for the search parameter value | 89 | 90 | #### Optional Elements 91 | 92 | | Element Name | Type | Description | 93 | |--------------|-----------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 94 | | expression | string | FHIRPath expression used to extract an element from a resource. | 95 | | xpath | string | XPath expression used to extract an element from a resource. | 96 | | multipleOr | boolean | Whether to allow multiple values (or) | 97 | | multipleAnd | boolean | Whether to allow multiple values (and) | 98 | | comparator | code | A list of one or more comparators that can be supported by the SearchParameter:
eq \| ne \| gt \| lt \| ge \| le \| sa \| eb \| ap | 99 | | modifier | code | A list of one or more modifiers that can be supported by the SearchParameter:
missing \| exact \| contains \| not \| text \| in \| not-in \| below \| above \| type \| identifier \| ofType | 100 | | chain | string | Names of one or more SearchParameters that will be chained together to form the current SearchParameter. | 101 | | component | BackboneElement | Used for composite SearchParameters. Defines each of the components that can be included in the SearchParameter type. Each component includes: