In Chapter 4, API Creation, and Chapter 5, Modernizing SOAP Services, you learned how to set up the Local Testing Environment (LTE) and began developing APIs with the designer. You also learned how to take advantage of your existing SOAP assets and convert those into APIs.
In this chapter, you will learn about how to begin implementing APIs that utilize the Health Level Seven International (HL7) Fast Healthcare Interoperability Resources (FHIR) standard (pronounced fire) that is now being mandated by the Centers for Medicare & Medicaid Services (CMS).
FHIR is an HL7 standard that supports providing resources using REST APIs and JSON. This chapter introduces how to develop REST APIs that support the FHIR specification. You can read more on FHIR by visiting the website: https://www.hl7.org/fhir/overview.html.
In this chapter, we will cover the following main topics:
When you complete this chapter, you will know how to create RESTful services using API Connect with a focus on delivering FHIR APIs and embedded logic. You will also have a good understanding of how FHIR is a good example of digital transformation.
With this chapter, you will be referencing a number of Swagger files to assist you with the learning experience. You will find these files in GitHub using the following URL: https://github.com/PacktPublishing/Digital-Transformation-and-Modernization-with-IBM-API-Connect.
You should copy the files for this chapter to your development environment. We will be utilizing the LTE and API Manager to perform the development tasks. If you prefer to use some of the skills you learned from Chapter 2, Introducing API Connect, you can use the CLI commands to push the sample files up to API Connect. The assumption going forward is you will begin utilizing the API Manager to draft new APIs.
Now that you understand what you will be attempting, let's begin with understanding the business use case for FHIR.
Interoperability between healthcare organizations has been like the search for the holy grail. The HL7 organization has been around since 1987 and has tackled the task of establishing standards for sharing healthcare information. There have been many levels of maturity of the standard over the years, with the most prominent being HL7v2.
Version 2 is an exchange of data that is delimited with pipes. Unfortunately, at the time, this method was too lenient, and some fields were left up to the provider to declare. These fields then created issues for consumers because they didn't have the consistency needed to receive the same type of file from different sources. Fields were of different types and values. Version 3 was introduced by HL7 to improve the data exchange quality by using XML and XML schemas. The adoption of version 3 was not as successful as they had hoped. XML schemas were difficult to digest and made implementations complicated. The goal was still to develop an improved version, but there needed to be something more digital that took advantage of Web 2.0, APIs, and JSON. That is how Fast Healthcare Interoperability Resources (FHIR) got started. The current version is FHIR v4.0.1. Although you can implement FHIR in various ways, the predominant way is by creating an FHIR server and accessing the FHIR resource data with APIs. Remember that the goal is to exchange data. Let's explore how that is accomplished by creating FHIR resources.
A resource in FHIR represents small and locally distinct units of exchanged data. Each resource has a defined behavior and meaning. Contained within the resource are elements and extensions of elements, some narrative, and other extensions to the resource.
It also has metadata, which has elements such as known identity and the location of the data. Of course, each resource has some interest in healthcare (patients, observations, diagnostic reports, and so on). Figure 6.1 shows the relationship between resources and elements:
There are hundreds of resources defined by FHIR. You can visit the HL7 FHIR website, https://www.hl7.org/fhir/resourcelist.html, to peruse the various resource definitions.
When you review a resource, you will find a data structure that it supports. You might wonder how you support this structure if your data is in relational databases. Your FHIR architecture may vary based on the approach you wish to take, given the tools you have at your disposal. You have various options for implementing your interoperability interface:
Something to keep in mind is the number of API endpoints you may be exposing. Let's look at the patient operations:
There are approximately 144 FHIR resources. If we support the 5 endpoints listed on all the resources, your number of endpoints totals 720, and that doesn't include custom endpoints based on consumer/business requirements.
Assuming you may be only addressing a small number of resources, let's discuss where the data resides after you have utilized one of the various options.
The FHIR server is where you will initiate your API calls to begin the exchange of data. You might think of it as the repository of the resource data accessed via the APIs you create. Many of the FHIR servers are built on Java but other languages exist. There are a number of test FHIR servers on the web and many others that you can download and use as models. The HL7 application programming interface (HAPI) FHIR server is one of them:
In this chapter, we will be running tests on a HAPI FHIR server that is prepopulated with test resources. You can access the HAPI FHIR test server at this URL:
Before you start developing your first FHIR API, it will be beneficial to understand the motivation of using API Connect to implement your RESTful FHIR APIs.
As mentioned in the chapter introduction, CMS has mandated payers (insurance companies) to implement a Patient Access API and a Provider Directory API for consumption by third-party entities using the FHIR standard. While the implementation date was moved from January 1, 2021, to July 1, 2021, nevertheless, payers will need to comply.
The benefits proposed by these two requirements are as follows:
These two benefits to consumers are just what the doctor ordered. Having information readily available is critical to healthcare and patient care. Now that we will be learning how to create RESTful FHIR APIs, it is important to note the reasons why using API Connect is a good choice.
Figure 6.4 highlights reasons for building APIs, managing the FHIR API lifecycle, and maintaining the integrity of data:
You now have a good overview of FHIR and how CMS mandates implementing capabilities for the Patient Access and the Provider Directory using FHIR. It's time to start playing with FHIR.
As you may recall, your APIs will be accessing an FHIR server that provides healthcare resources. Given that, when you create your FHIR RESTful API, you will need an endpoint. For the examples provided in this section, you will be referencing the online HAPI Test FHIR server that is at this location:
http://hapi.fhir.org/baseR4/swagger-ui/
You have learned to use the LTE and have been introduced to the API Manager Drafts Designer. You'll be using the LTE initially and then switch to the API Manager so that you can learn the other capabilities of the API Manager.
If you haven't already downloaded the chapter files from the URL mentioned in the Technical requirements section of this chapter, you should do that now and place them in a directory/folder on your local device.
Now that you have the files, you can log in and begin developing APIs.
Everyone has a lot of fun utilizing FHIR in puns, but when it gets down to interoperability in healthcare, utilizing FHIR APIs is just what the doctor ordered. What you will be creating is the FHIR Patient resource as an API and retrieving data from an FHIR server on the web. The endpoint you will be calling is http://hapi.fhir.org/baseR4/Patient?_pretty=true.
If you were to call this from your browser, you would see all the patients in JSON data format returned, as shown in Figure 6.5:
You will be working with the Patient-swagger.json file that you downloaded from the book's GitHub repository.
To create the FHIR, perform these steps:
apic-lte start
With a successful start of the LTE, you will receive some valuable information that you will need to log in to API Connect. They are shown as follows:
For now, that is all you will be needing to log in.
Notice that the Version is 4.0.1. This represents the version of FHIR that this API supports. You can also see that it supports OpenAPI 2.0 specifications.
Tip
If you do not find the patient API file loaded, please download it from the GitHub site and use the LTE to add a new API using the existing OpenAPI import. You will find these files in GitHub using this URL: https://github.com/PacktPublishing/Digital-Transformation-and-Modernization-with-IBM-API-Connect. Once completed, you can continue with these steps.
Click on Design and then the General drop-down menu. Click on Base Path to review the base path. This is shown in Figure 6.10:
Another important section relating to the URL is the parameters. Click on Design | Parameter Definitions. This is where you will see all the parameters defined within the API. Figure 6.11 shows some of the parameters:
Another important section is your schema definitions. Click on Design | Definitions to observe what is already defined. These are the elements for the FHIR resource. This is shown in Figure 6.12:
Next, you can review how API Connect provides the ability to enhance the runtime of the API.
Click on the Gateway tab and then select Gateway and portal settings. Scroll until you see the Gateway (option) label. Notice the two gateway types (datapower-api-gateway and datapower-gateway). Figure 6.13 shows the location of the Gateway dropdown:
The two gateways allow the API developer to choose which implementation of gateway will satisfy the type of API developed. For APIs migrated from the previous version 5 release of API Connect, datapower-gateway provides version 5 compatibility. For newly developed APIs, datapower-api-gateway provides additional functionality and an increase in the API performance.
Also on the Gateway tab is the Properties section. Notice the default endpoint. It is named target-url and its associated value is https://hapi.fhir.org:
As you can see, a lot has already been defined for you and there are places where you can add documentation about your API. If you were doing this with an empty OpenAPI Swagger file, you would have had to create all of those details. Luckily for you, it was all handled previously.
Now that you have familiarized yourself with the default implementation, it's time to make some updates so we can test our API. The changes you will make will be adjusting the target URL and the basepath, so it adheres to the endpoint: http://hapi.fhir.org/baseR4/Patient?_pretty=true:
Figure 6.16 shows the results of your change. What you just did was adjust the base path to match the target endpoint URI to specify /baseR4 versus the default that was provided in the download. When the API executes, API Connect will then append the new base path to the host endpoint. Next, you'll update the target host within the targetURL property.
Notice that the default value is https://localhost/fhir-server/api/v4/. You will be changing this to http://hapi.fhir.org. Make that change and click Update, and then click Save once again.
You should see the single invoke policy. Click on the policy itself to open the property editor:
As you can see in Figure 6.17, the URL property has the following replacement properties:
$(targeturl)$(api.operation.path)$(request.search)
You are already familiar with target-url. The other two are context variables. You were introduced to context variables in Chapter 4, API Creation. When you want to utilize the submitted path to an operation, you reference the api.operation.path context variable. If you reference request.search, you are essentially taking the request details after the question mark. An example would be http://hapi.fhir.org/baseR4/Patient?_pretty=true.
You will adjust these to reflect the changes you want to make. In the URL property, change the value of $(targeturl)$(api.operation.path)$(request.search) to $(targeturl)$(api.root)$(api.operation.path).
This will now call the backend API using the values you changed. You should test it to verify it is working. Ensure your API is online. If it shows offline, slide the button to online.
Once your API is online, click on the Test tab and perform the following steps:
You may have noticed that API Connect had all of the HTTP methods support – a real timesaver. Click Send to invoke the API.
You have successfully created and tested an FHIR GET request and have seen data returned. You did that with very minimal steps.
Before you learn about adding logic policies, let's first move your API up to the API Manager so you can experience development and testing on that platform.
Important Note
It is an assumption that you have access to the API Manager and belong to a provider organization. If you have yet to get access to the API Manager, please request access from the provider organization owner. To get to the API Manager user interface, use this URL: https://[api-manager-server-ui]/auth/manager/sign-in/.
You will be presented with a list of existing APIs. This is a list of all the APIs within the provider organization.
Your API is now available for additional development in the API Manager. You might notice that the page display is very similar to the LTE environment:
Now, it's time to add some logic constructs to your API to allow greater flexibility.
When you were working within the Gateway policies, you may have noticed the logic policies that were listed in the left panel under Logic. While the options are specific to conditional operation, the Throw policy is also provided for conditional error handling. Depending upon the gateway, the number of options differs. Actually, the logic policies have been simplified between the DataPower V5 Compatible Gateway and DataPower API Gateway. The If logic policy is implemented within the Switch logic policy of the DataPower API Gateway. Figure 6.22 shows that change:
If you are confused about how these options change within the Gateway policies, simply click on the Gateway tab and then Gateway and portal settings:
On the Gateway and portal settings, scroll down and you will see the Gateway (optional) label, showing what you have selected for this API:
Now that you are aware of the types of logic you can add, we'll put that into practice. You'll start with If and Switch.
In the near future, the DataPower Gateway V5 Compatible offering will be used very little, as the DataPower API Gateway is touted to perform 10x faster. That being said, since the DataPower API Gateway supports If logic, with the Switch policy, you'll learn how to do both logics with the Switch policy.
Let's add some simple logic that is actually useful while you are doing development. The scenario would be that whenever you are testing your API, you would like to have the endpoint changed based on the APIm_Debug header value. You only want to debug if you are executing your test case data. So how would you do that?
You just specified that if the APIm_Debug flag is not on, process as normal. This is representing the If statement. Now, we can create the Add otherwise case, as shown here:
It is within the Otherwise branch that you will add a new invoke policy, specifying a patient that you will be allowed to debug.
You have updated your API to apply some logic that will run debugging only if the debug header is set to true. You are ready to run a test. You will accomplish that by using the Test tab, as shown here:
Perform the following steps here:
Now you have successfully applied If logic to an API. While that was a simple example to introduce you to logic switches, you will probably be more interested in seeing how to apply a switch that routes to the proper operations you have created for your API. You will do that next.
The operation switch policy is used to separate the programming logic by the HTTP operation verb (POST, GET, PUT, DELETE, and so on). By splitting it this way, it provides you with the opportunity to supplement each operation with additional policies, such as security or transformations. Before we implement the operational switch, let's review where the operations are set up by looking at a completed example:
Your file will be uploaded as follows:
You can see the paths already created in this API. These RESTful paths were created using the FHIR specifications on how you interact with an FHIR server.
In Figure 6.37, you can see the plus sign (next to Operations) button visible on the right. This is how you will add new operations. Go ahead and click on the button to see how you would accomplish it:
As you can see, there is a dropdown that has all the operations not currently added. You can choose any of the other operations and provide a description of that operation.
You will now see PATCH added on the left menu under Operations. You are required to add a response for the PATCH operation. Expand PATCH and you will see Responses.
This pops up a new page to add details about the operation:
The default is the 200 HTTP response code. You'll accept this default and click Create. Ensure you enter a descriptive message, such as Success. Click Create to create the response code.
In the Schema section, click on Create to define a new schema. There are two method tabs to choose from. The first is Definition. When you choose Definition, you create the schema from scratch. You can add a title and a description, but you must select a type. Since the response is a simple text response, you will select string. The other option is Reference. Since our imported API already has existing definitions, we want to choose this. Click on Reference:
The screen refreshes and you will notice that the schema shows an error. You can choose Fix Reference or Create.
You'll notice you still have one error:
You also need to reference the {id} parameter for the PATCH operation. Click on the parameter plus sign again and add the idParam reference. Figure 6.45 shows that you select Reference and #/parameters/idParam:
As you can see in Figure 6.47, similar to the PATCH operation we just created, a body of Evidence type was required for this API, and it is allowing two status codes that represent what actually happened in the FHIR server. Before we return to the operation-switch example, let's first review the Evidence schema:
Now, you should have a good understanding of what is contained within the path and how operations are part of it, as well as references to definitions and how to add items using the Source icon. Let's return to operation-switch to show how we implement those paths.
You have learned that the Evidence API has four operations within the /Evidence/{id} path. Since each may have different requirements upon execution, it would be good to separate those in the assembly so that you can apply different policies to them. We'll use operation-switch to set that demarcation.
Warning
Nesting an operation-switch component inside an if or switch construct, or another operation-switch component, is not supported.
To use the operation-switch, perform the following steps:
From the Logic menu, drag and drop the Operation Switch component and release it before invoke, as shown in the following screenshot:
The operation-switch component will then show before invoke, as shown in Figure 6.50. You will notice that there is an empty case displayed. You will start providing those cases:
What you may have noticed is the operators you thought would show up (GET, PUT, DELETE, and so on) are not there. Instead, there are various values, such as readEvidence, updateEvidence, and so on. How did they get there? You'll learn shortly, but you should finish this first.
Continue to scroll down the page until you see the Operation (optional) label:
Notice how the Operation (optional) field is showing readEvidence. You saw this optional field when you added the PATCH method earlier, but you left it blank. Since you didn't supply any Operation (optional) fields to PATCH, it will create a default name and list it on the case properties field on the invoke policy. Now you know how an Operation (optional) field works, you can continue.
When you click on Add case, it will add a new case field ready for your selection:
You will choose updateEvidence to assign the PUT method to Case 1. Notice how readEvidence is not shown and the PATCH method you added is displayed in the dropdown. It shows your PATCH method and the path, instead of a readable operation (optional) name.
Tip
Having an Operation (optional) name makes your visual programming more readable.
As you can see, operation-switch shows readable cases so that you can understand what they will be doing. We can make it more readable by changing the invoke policy to a more descriptive name. To do so, perform the following steps:
After you make that change, operation-switch will be updated:
It is definitely more readable. Now, you will need to place the get Evidence by id invocation under the readEvidence case. Drag and drop the get Evidence by id invoke policy on the line under readEvidence:
Now, whenever a readEvidence operation (GET) is called, get Evidence by Id will be invoked.
You will now need to test the conditional switch, but first, you need to update the base path and invoke URL. Since you are still on the Invoke pane, you should update the invoke properties now.
You'll be presented with a page that will allow testing. One of the benefits of using the Test facility is it already has all of your operations available for execution – a real timesaver. It also knows the parameters that are required and displays them:
You have successfully executed one of the operation-switch cases. But what about the other two that you set up? If you test them, nothing happens. It's because we need to add invoke policies to the other two. You'll do that next:
After saving your changes, your final operation-switch should look like Figure 6.65:
You have now successfully implemented an operation-switch. With this pattern of developing with the operation-switch, you can now add additional policies before and after your new invokes (get Evidence by id, put Evidence by id, and delete Evidence by id).
Information
The HAPI FHIR server is available for testing online. If you will be testing using operations that update and delete resources, it is suggested that you create a new resource first, save the return identifier, and use that identifier in future operations.
This concludes the steps to creating RESTful services using API Connect. You've learned a lot, so let's review the key skills learned.
While this chapter was rather lengthy, it was packed with good information. You were introduced to FHIR and how that digital framework is helping healthcare companies successfully exchange information securely. You even learned with actual FHIR resources defined with data definitions.
You learned more about how RESTful services are created in API Connect and utilized the API Manager drafts to perform the visual development. Within the Develop APIs and products tile, you learned how to add existing APIs, modify those APIs with the designer, and add logic to flows such as operation-switch. The skills you learned in this chapter will make you very comfortable adding new or existing APIs, and then enhancing the flow of the API using logic constructs.
Finally, you were introduced to the Test facility where you can run a test directly from API Connect and how that facility improved your agility by generating your operation calls.
Your knowledge is building rapidly. The next chapter will build on this one by adding security to your APIs.