Click here to Skip to main content
Click here to Skip to main content

eHealthCareFramework - Framework for HealthCare apps

, 23 Sep 2013
Rate this:
Please Sign up or sign in to vote.
Reusable framework for HealthCare domain based applications.

Introduction

This article we will see the various aspects needed for the eHealthCare Framework. The entire framework is implemented for helping developers to easily implement applications by re-using or extending this framework.  

Benefits of using the eHealthCare Framework:

  1. Efficient, easy to maintain, and reliable. 
  2. Reusable context for components.  
  3. Design reuse.

Framework requirements

The framework purely depends on third party APIs. Most of them are CarePass APIs from Aetna. We have to register for the API and get keys in order to make use of the framework.

Why do we need a healthcare framework?

Frameworks help developers in building their apps easily with less overhead in understanding, designing, and implementing the underlying logic required to make their apps to work. By using a framework we can concentrate on the application needs rather than breaking our heads in search for APIs and implementing them. Imagine if you decided to build a health-care app, there are times where you have to consume and use third party APIs. You have to do some research and make use of APIs that suit your requirements. You will now understand some of the common patterns all developers do, here's why I decided to come up with a health-care framework for solving some of the common needs of healthcare domain based developers who wish to implement healthcare apps.

Thousand foot view of the healthcare domain

People involved in building, or analysts, developers, and designers will work in one of the following areas of the healthcare domain:

  1. Providers or Doctors – Application developers focus in implementing their apps targeting providers or doctors. Consider an example of an Enterprise Health Record (EHR), Enterprise Medical Record (EMR), or Personal Health Record (PHR) system where you will be more focused towards automating the needs for doctors.
  2. Clearing Houses – Clearing houses build healthcare applications for processing claims, to handle patient eligibility requests, manage patient billings, etc. Clearing houses act as an intermediate between providers and payers. 
  3. Here's what the clearing houses do:

    • Claim Processing and Status Reports – Electronically process patient's insurance claims and submit to payers as per their required claim format. Lets providers know the status of a claim at all times.
    • Rejection Analysis - Have error codes displayed in a simple, easily understandable language.
    • Online Claims Correction - Edit and correct claims day or night online.
    • Printed Claims - When necessary, have medical claims automatically dropped to paper but still be able to track them electronically.
    • Eligibility Verification – Used to determine patient health coverage before treatment, handle real-time batch eligibility requests and response.
    • Electronic Remittance (ERA) – Handle electronic version of patients' claim payments, provide details or explanations about payments denied or paid.
    • Patient Statement Services – Electronically handle patient statements. Post electronic statements directly to patients.
  4. Payers – Individuals who are working for payers will be involved in handling patient claims. Payers will have a tie up with one or more payers, payers like Aetna will solely handle their patient claims and manage reimbursements.

What are we focusing here?

We will be focusing on the framework for providers. We will be targeting developers implementing applications for providers. Note – This is an ongoing implementation, I will be updating and adding more framework modules as and when I encounter common needs. 

Developers who are involved in implementing apps are more focused on implementing their apps by using a free or paid third party API. Say for example, to get healthcare topics, drug information, clinical trials, food and nutrition information, etc. There are companies who build APIs, some of them are in beta and allow developers to consume their APIs with certain limitations, e.g., the number of calls that developers can make. Our framework will internally consume and make use of third party free APIs and that's how we are solving some of the common needs.

We will be using Aetna's CarePass Developer APIs, it's a REST based API. We need to first register ourselves and get the API Keys. Most of the APIs that are being used are in https://developer.carepass.com/api_gallery.

How are we making sure the framework is reliable or consistent?

A Unit Test project is maintained and each and every framework feature is unit tested to make sure we are getting what we are expecting for the given inputs.

Features of the eHealthcare framework:

  1. Clinical Trials – We might be interested in performing a clinical trail search. We are making use of the CarePass clinical trials API and fetch clinical trial information based on the search criteria.
  2. Drug Info – There are times we might be interested to get drug related information by searching for a specific drug by NDC/NDA, getting drug alternatives or drug images. 
  3. Rx Pricing – Good Rx Pricing API is being used to retrieve Rx pricing for a specified drug.
  4. Food Care – Get dish information, search nearby restaurants based on location latitude and longitude, etc. 
  5. Food Essentials – Search for products and get label information, label summary. 
  6. Fooducate – Perform food search and know more information, say food ingredients, nutrition, etc. 
  7. Nutrition Info – Get nutrition information by making use of the Nutritionix API.   
  8. Rx Norm – Get drug information, spelling suggestions, etc.

Background

Understanding and implementation knowledge of healthcare applications.

Using the code

Let us see the framework implementation. Below is the code snippet for the Web Request and Response. We will be mostly using JSON response. Note – The header collection is optional. There are service requests which require explicit authentication tokens to be set in the header and passed in the requests. 

public class WebRequestHelper
{
  public XDocument GetXmlResponse(string url, WebHeaderCollection headerCollection = null)
  {
    var client = new WebClient();
    if (headerCollection != null)
        client.Headers = headerCollection;
    var response = client.DownloadData(new Uri(url));

    TextReader tr = new StringReader(System.Text.Encoding.UTF8.GetString(response));
    XDocument doc = XDocument.Load(tr);
    return doc;
  }

  public string GetJsonResponse(string url, WebHeaderCollection headerCollection = null)
  {
    var client = new WebClient();
    if (headerCollection != null)
        client.Headers = headerCollection;
    var response = client.DownloadData(new Uri(url));
    return System.Text.Encoding.Default.GetString(response);
  }
}

Code snippet for fetching clinical trial information:

public ClinicalTrialSearchInfo SearchForClinicalTrialInfo(string status, 
    string condition, string state, string country, 
    string firstReceivedFromMMDDYYYY, string lastUpdateFromMMDDYYYY)
{
    var queryStringBuilder = new StringBuilder();
    if (!string.IsNullOrEmpty(status))
        queryStringBuilder.AppendFormat("status={0}&", status);
    if (!string.IsNullOrEmpty(condition))
        queryStringBuilder.AppendFormat("condition={0}&", condition);
    if (!string.IsNullOrEmpty(state))
        queryStringBuilder.AppendFormat("state1={0}&", state);
    if (!string.IsNullOrEmpty(country))
        queryStringBuilder.AppendFormat("country1={0}&", country);
    if (!string.IsNullOrEmpty(firstReceivedFromMMDDYYYY))
        queryStringBuilder.AppendFormat("firstreceivedfrom={0}&", firstReceivedFromMMDDYYYY);
    if (!string.IsNullOrEmpty(lastUpdateFromMMDDYYYY))
        queryStringBuilder.AppendFormat("lastupdatedfrom={0}&", lastUpdateFromMMDDYYYY);
    string url = "https://api.carepass.com/hhs-directory-api/clinicaltrials/search?" + 
      queryStringBuilder.ToString() + "apikey=" + HealthDataInitiativeApiKey;
    var webRequestClient = new WebRequestHelper();
    var jsonResponse = webRequestClient.GetJsonResponse(url);
    var clinicalTrialSearchInfo = JsonConvert.DeserializeObject<ClinicalTrialSearchInfo>(jsonResponse);
    return clinicalTrialSearchInfo;
} 

Below is the code snippet for fetching drug information. The code is self explanatory, all we do is make an HTTP web request with a few required parameters. Once we get the JSON response we will de-serialize and return the output as a strongly typed object.

public List<Druginfo> DrugSearchByName(string drugName)
{
    string url = string.Format("https://api.carepass.com/hhs-directory-" + 
      "api/drugs/search?name={0}&apikey={1}", drugName, HealthDataInitiativeApiKey);
    var webRequestClient = new WebRequestHelper();
    var jsonResponse = webRequestClient.GetJsonResponse(url);
    var drugInfo = JsonConvert.DeserializeObject<druginfo[]>(jsonResponse);
    return drugInfo.ToList();
}
 
public List<Druginfo> DrugSearchByNDC(string ndc)
{
    string url = string.Format("https://api.carepass.com/hhs-directory" + 
      "-api/drugs/{0}?apikey={1}", ndc, HealthDataInitiativeApiKey);
    var webRequestClient = new WebRequestHelper();
    var jsonResponse = webRequestClient.GetJsonResponse(url);
    var drugInfo = JsonConvert.DeserializeObject<druginfo[]>(jsonResponse);
    return drugInfo.ToList();
}

public List<NDADruginfo> DrugSearchByNDA(string nda)
{
    string url = string.Format("https://api.carepass.com/hhs-directory" + 
      "-api/applications/{0}?apikey={1}", nda, HealthDataInitiativeApiKey);
    var webRequestClient = new WebRequestHelper();
    var jsonResponse = webRequestClient.GetJsonResponse(url);
    var drugInfo = JsonConvert.DeserializeObject<ndadruginfo[]>(jsonResponse);
    return drugInfo.ToList();
}

public List<Drugalternativeinfo> DrugAlternativesByNDA(string nda)
{
    string url = string.Format("https://api.carepass.com/hhs-directory" + 
      "-api/applications/{0}/alternatives?apikey={1}", nda, HealthDataInitiativeApiKey);
    var webRequestClient = new WebRequestHelper();
    var jsonResponse = webRequestClient.GetJsonResponse(url);
    var drugAlternativesInfo = JsonConvert.DeserializeObject<drugalternativeinfo[]>(jsonResponse);
    return drugAlternativesInfo.ToList();
}
 
public List<string> DrugImagesByNDA(string nda)
{
    string url = string.Format("https://api.carepass.com/hhs-directory" + 
      "-api/drugs/{0}/images?apikey={1}", nda, HealthDataInitiativeApiKey);
    var webRequestClient = new WebRequestHelper();
    var jsonResponse = webRequestClient.GetJsonResponse(url);
    var drugImages = JsonConvert.DeserializeObject<string[]>(jsonResponse);
    return drugImages.ToList();
}

Below is the code snippet for fetching the Rx price for the specified drug. We are making use of the Good Rx API for fetching the drug price by drug name, dosage, or form - tablet, capsule, etc.

public List<GoodRxPriceInfo> GoodRxPricing(string drugName, 
    string form, string dosage, string manufacturer)
{
    var queryStringBuilder = new StringBuilder();
    if (!string.IsNullOrEmpty(drugName))
        queryStringBuilder.AppendFormat("name={0}&",drugName);
    if (!string.IsNullOrEmpty(form))
        queryStringBuilder.AppendFormat("form={0}&", form);
    
    if (!string.IsNullOrEmpty(dosage))
        queryStringBuilder.AppendFormat("dosage={0}&", dosage);
    if (!string.IsNullOrEmpty(manufacturer))
        queryStringBuilder.AppendFormat("manufacturer={0}&", manufacturer);
    string url = "https://api.carepass.com/good-rx-api/drugprices/low?" + 
      queryStringBuilder.ToString() + "apikey="+ GoodRxPricingApiKey;
    var webRequestClient = new WebRequestHelper();
    var jsonResponse = webRequestClient.GetJsonResponse(url);
    var rxPriceInfo = JsonConvert.DeserializeObject<GoodRxPriceInfo[]>(jsonResponse);
    return rxPriceInfo.ToList();
}

We will see some of the Food Care API features. Below is the code snippet for fetching nearby restaurants and getting menu information.

public FoodCareRestaurantsInfo SearchNearByRestaurants(
    string zipCode, string distance, string latitude, string longitude)
{
    var queryStringBuilder = new StringBuilder();
    if (!string.IsNullOrEmpty(zipCode))
        queryStringBuilder.AppendFormat("zip={0}&", zipCode);
    if (!string.IsNullOrEmpty(distance))
        queryStringBuilder.AppendFormat("distance={0}&", distance);
    if (!string.IsNullOrEmpty(latitude))
        queryStringBuilder.AppendFormat("latitude={0}&", latitude);
    if (!string.IsNullOrEmpty(longitude))
        queryStringBuilder.AppendFormat("longitude={0}&", longitude);
    string url = "http://api.foodcare.me/restaurants/search/?"+ queryStringBuilder.ToString();
    var headerCollection = new WebHeaderCollection();
    headerCollection.Add("X-Auth-Token", FoodCareXAuthToken);
    headerCollection.Add("X-Access-Token", FoodCareXAccessToken);
    var webRequestClient = new WebRequestHelper();
    var jsonResponse = webRequestClient.GetJsonResponse(url, headerCollection);
    return JsonConvert.DeserializeObject<FoodCareRestaurantsInfo>(jsonResponse);
}
 
public DishInfo GetDishInfo(int dishId)
{
    string url = "http://api.foodcare.me/dishes/show/" + dishId;
    var headerCollection = new WebHeaderCollection();
    headerCollection.Add("X-Auth-Token", FoodCareXAuthToken);
    headerCollection.Add("X-Access-Token", FoodCareXAccessToken);
    var webRequestClient = new WebRequestHelper();
    var jsonResponse = webRequestClient.GetJsonResponse(url, headerCollection);
    return JsonConvert.DeserializeObject<DishInfo>(jsonResponse);
}

Below is the code snippet for Food Essentials. We can search products and get more information about the product, get label and summary information.

public FoodEssentialProducts SearchProducts(string productName, string sessionId, 
                                             int searchCount)
{
    string url = string.Format("http://api.foodessentials.com/searchprods?q={0}&sid=" + 
      "{1}&n={2}&s=0&f=json&api_key={3}", 
      productName, sessionId, searchCount, FoodEssentialsApiKey);
    var webRequestClient = new WebRequestHelper();
    var jsonResponse = webRequestClient.GetJsonResponse(url);
    return JsonConvert.DeserializeObject<FoodEssentialProducts>(jsonResponse);
}

public FoodEssentialLabelInfo GetLabelInfo(string upcId, string sessionId, string longitude, 
                                           string latitude)
{
    string url = string.Format("http://api.foodessentials.com/label?u={0}&sid" + 
      "={1}&appid={2}&f=json&long={3}&lat={4}&api_key={5}", 
      upcId, sessionId, FoodEssentialsApiKey, longitude, latitude, FoodEssentialsApiKey);
    var webRequestClient = new WebRequestHelper();
    var jsonResponse = webRequestClient.GetJsonResponse(url);
    return JsonConvert.DeserializeObject<FoodEssentialLabelInfo>(jsonResponse);
}
        
public FoodEssentialLabelSummary GetLabelSummary(string upcId, string sessionId, 
                                                 string longitude, string latitude)
{
    string url = string.Format("http://api.foodessentials.com/" + 
      "label?u={0}&sid={1}&appid={2}&f=json&long={3}&lat" + 
      "={4}&api_key={5}", upcId, sessionId, FoodEssentialsApiKey, 
      longitude, latitude, FoodEssentialsApiKey);
    var webRequestClient = new WebRequestHelper();
    var jsonResponse = webRequestClient.GetJsonResponse(url);
    return JsonConvert.DeserializeObject<FoodEssentialLabelSummary>(jsonResponse);
} 

Points of interest

Before building this framework, I was looking for various healthcare APIs for implementing an app. After developing several healthcare apps, I realized and felt the necessity to build a re-usable framework so that we can easily code apps by re-using the core logic within the framework.

I know it's hard to make a generic framework which can solve various healthcare needs or requirements but we can sure re-use, extend this framework depending on their requirements.

History 

  • Version 1.0 - 09/08/2014 - Coded eHealthCare Framework with basic features targeting providers.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Ranjan.D
Web Developer
United States United States
Profile
 
Around 9 years of professional software development experience in analysis, design, development, testing and implementation of enterprise web applications for healthcare domain with good exposure to object-oriented design, software architectures, design patterns, test-driven development and agile practices.
 
In Brief
 
Analyse and create High Level , Detailed Design documents.
Use UML Modelling and create Use Cases , Class Diagram , Component Model , Deployment Diagram, Sequence Diagram in HLD.
 
Area of Working : Dedicated to Microsoft .NET Technologies
Experience with : C# , J2EE , J2ME, Windows Phone 8, Windows Store App
Proficient in: C# , XML , XHTML, XML, HTML5, Javascript, Jquery, CSS, SQL, LINQ, EF
 
Software Development
 
Database: Microsoft SQL Server, FoxPro
Development Frameworks: Microsoft .NET 1.1, 2.0, 3.5, 4.5
UI: Windows Forms, Windows Presentation Foundation, ASP.NET Web Forms and ASP.NET MVC3, MVC4
Coding: WinForm , Web Development, Windows Phone, WinRT Programming, WCF, WebAPI
 
Healthcare Domain Experience
 
CCD, CCR, QRDA, HIE, HL7 V3, Healthcare Interoperability
 
Others:
 
TTD, BDD
 
Education
 
B.E (Computer Science)
 
CodeProject Contest So Far:
 
1. Windows Azure Developer Contest - HealthReunion - A Windows Azure based healthcare product , link - http://www.codeproject.com/Articles/582535/HealthReunion-A-Windows-Azure-based-healthcare-pro
 
2. DnB Developer Contest - DNB Business Lookup and Analytics , link - http://www.codeproject.com/Articles/618344/DNB-Business-Lookup-and-Analytics
 
3. Intel Ultrabook Contest - Journey from development, code signing to publishing my App to Intel AppUp , link - http://www.codeproject.com/Articles/517482/Journey-from-development-code-signing-to-publishin
 
4. Intel App Innovation Contest 2013 - eHealthCare - http://www.codeproject.com/Articles/635815/eHealthCare
 
5. Grand Prize Winner of CodeProject HTML5 &CSS3 Article Content 2014

Comments and Discussions

 
QuestionGreat description of the API PinprofessionalAbhishek Nandy10-Nov-13 17:24 
AnswerRe: Great description of the API PinprofessionalRanjan.D11-Nov-13 0:19 
QuestionAPI PinmemberJrPacheco23-Sep-13 7:34 
GeneralMy vote of 3 Pinmemberstefanveliki9-Sep-13 5:42 
GeneralRe: My vote of 3 PinprofessionalRanjan.D9-Sep-13 5:48 
GeneralMy vote of 3 Pinmemberme.ajaykumar9-Sep-13 3:27 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.140721.1 | Last Updated 23 Sep 2013
Article Copyright 2013 by Ranjan.D
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid