SlideShare uma empresa Scribd logo
1 de 62
HAPI-FHIR for 
Java Developers 
James Agnew 
FHIR Developer Days 
November 24, 2014 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
Who am I? 
 Name: James Agnew 
 Company: University 
Health Network 
 Background: 
 Software development 
manager for a large 
hospital network 
 Project lead for HAPI for 9 
years 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office. 
2
About this Presentation 
 All code samples are available on GitHub in 
fully working form 
 HAPI is too big a topic for 1.5 hours :) 
so… 
 I will be around all day Monday to 
Wednesday to expand on topics I don’t cover 
here and help you with your projects 
3 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
FHIR: A Quick Recap 
 There are two key parts of FHIR to consider: 
 The first is a data model for healthcare Resources 
and supporting 
Datatypes 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office. 
4
 The second is a RESTful API for interacting 
with that model 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office. 
5 
FHIR: A Quick Recap (2)
The HAPI Project 
 HAPI started in 2001 as an HL7 v2 Library 
 Built to support a simple web portal, now used 
in applications around the world 
HL7 v2 - http://hl7api.sourceforge.net 
FHIR - http://jamesagnew.github.io/hapi-fhir/ 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office. 
6
HAPI FHIR: What? 
 Not a client or a server, but a toolkit for 
building either 
7 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
HAPI FHIR: Why? 
 HAPI FHIR was started to simplify access to our internal 
data sources 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office. 
8
Design Goals 
 Use Anywhere 
 Apache 2.0 License for all components 
 Minimal dependencies 
 Be Flexible 
 Loosely coupled, pluggable components 
 Be Powerful 
 “Steal” all the best ideas from existing frameworks: 
JAX-WS, Springframework, .NET FHIR API  
..etc.. 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office. 
9
HAPI: The Key 
Components 
 Structure Classes (represent FHIR model) 
 Parsers (convert model into XML/JSON) 
 Client (use HTTP to access FHIR servers) 
 Server (build a FHIR server) 
 Utilities: 
 Validator 
 Narrative Generator 
10 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
Structures Classes: 
The FHIR Model 
 HAPI Defines several sets 
of classes which form the 
data model 
 Resource definition 
classes implement 
IResource 
 Examples: Patient, 
CarePlan, Encounter, 
Practitioner, Medication 
11 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
Structures Classes: 
The FHIR Model (2) 
 HAPI also defines a class 
for each data type 
 Datatype classes are 
named [name]Dt 
 Primitive types include: 
StringDt, AgeDt, BooleanDt 
 Composite types include: 
AddressDt, RatioDt 
12 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
Structures Classes: 
The FHIR Model (3) 
 JavaDocs for structures are available here: 
http://jamesagnew.github.io/hapi-fhir/apidocs-dstu/index.html 
13 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
Taking the Structures for 
a spin 
 Patient Resource (http://hl7.org/implement/standards/fhir/patient.html) 
14 
 HumanName Datatype 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
Taking the Structures for 
a spin (2) 
15 
public class Example01_CreateAPatient { 
public static void main(String[] theArgs) { 
// Create a resource instance 
Patient pat = new Patient(); 
// Add a "name" element 
HumanNameDt name = pat.addName(); 
name.addFamily("Simpson").addGiven("Homer").addGiven("J"); 
// Add an "identifier" element 
IdentifierDt identifier = pat.addIdentifier(); 
identifier.setSystem("http://acme.org/MRNs").setValue("7000135"); 
// Model is designed to be chained 
pat.addIdentifier().setLabel("Library Card 12345").setValue("12345"); 
} 
} 
https://github.com/jamesagnew/hapi-fhir/tree/master/hapi-fhir-tutorial/skeleton-project 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
Taking the Structures for 
a spin (3) 
16 
public class Example01_CreateAPatient { 
public static void main(String[] theArgs) { 
// Create a resource instance 
Patient pat = new Patient(); 
// Add a "name" element 
HumanNameDt name = pat.addName(); 
name.addFamily("Simpson").addGiven("Homer").addGiven("J"); 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
Taking the Structures for 
a spin (4) 
17 
public class Example02_CreateAPatient { 
public static void main(String[] theArgs) { 
Patient pat = new Patient(); 
pat.addName().addFamily("Simpson").addGiven("Homer").addGiven("J"); 
pat.addIdentifier().setSystem("http://acme.org/MRNs").setValue("7000135"); 
pat.addIdentifier().setLabel("Library Card 12345").setValue("12345"); 
// Enumerated types are provided for many coded elements 
ContactDt contact = pat.addTelecom(); 
contact.setUse(ContactUseEnum.HOME); 
contact.setSystem(ContactSystemEnum.PHONE); 
contact.setValue("1 (416) 340-4800"); 
pat.setGender(AdministrativeGenderCodesEnum.M); 
} 
} 
https://github.com/jamesagnew/hapi-fhir/tree/master/hapi-fhir-tutorial/skeleton-project 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
HAPI: The Key 
Components 
 Structure Classes (represent FHIR model) 
 Parsers (convert model into XML/JSON) 
 Client (use HTTP to access FHIR servers) 
 Server (build a FHIR server) 
 Utilities: 
 Validator 
 Narrative Generator 
18 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
Playing with Parsers 
19 
 The starting point for much of the HAPI-FHIR 
API is the FhirContext class 
 FhirContext acts as a factory for the rest of 
the API, including the two parsers: 
 XmlParser 
 JsonParser 
 FhirContext is designed to be created once and 
reused (important for performance!) 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
Playing with Parsers: 
Encoding Resources 
20 
public class Example03_EncodeResource { 
public static void main(String[] theArgs) { 
// Create a Patient 
Patient pat = new Patient(); 
pat.addName().addFamily("Simpson").addGiven("Homer").addGiven("J"); 
pat.addIdentifier().setSystem("http://acme.org/MRNs").setValue("7000135"); 
// [.. snip ..] 
// Create a context 
FhirContext ctx = new FhirContext(); 
// Create a XML parser 
IParser p = ctx.newXmlParser(); 
p.setPrettyPrint(true); 
String encode = p.encodeResourceToString(pat); 
System.out.println(encode); 
} 
} 
https://github.com/jamesagnew/hapi-fhir/tree/master/hapi-fhir-tutorial/skeleton-project 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
Playing with Parsers: 
Encoding Resources (2) 
21 
// Create a context 
FhirContext ctx = new FhirContext(); 
// Create a XML parser 
IParser parser = ctx.newXmlParser(); 
parser.setPrettyPrint(true); 
String encode = parser 
.encodeResourceToString(pat); 
System.out.println(encode); 
<Patient xmlns="http://hl7.org/fhir"> 
<identifier> 
<system value=“http://acme.org/MRNs"/> 
<value value="7000135"/> 
</identifier> 
<name> 
<family value="Simpson"/> 
<given value="Homer"/> 
<given value="J"/> 
</name> 
<telecom> 
<system value="phone"/> 
<value value="1 (416) 340-4800"/> 
<use value="home"/> 
</telecom> 
<gender> 
<coding> 
<system value="http://hl7.org/fhir/v3/AdministrativeGender"/> 
<code value="M"/> 
</coding> 
</gender> 
</Patient> 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
Playing with Parsers: 
Parsing Resources 
22 
public class Example04_ParseResource { 
public static void main(String[] theArgs) { 
String resourceBody = 
"{"resourceType":"Patient","identifier":[{"system":"http://acme.org/MRNs","value":"7000135"}], 
"name":[{"family":["Simpson"],"given":["Homer","J"]}]}"; 
// Create a context 
FhirContext ctx = new FhirContext(); 
// Create a JSON parser 
IParser parser = ctx.newJsonParser(); 
Patient pat = parser.parseResource(Patient.class, resourceBody); 
List<IdentifierDt> identifiers = pat.getIdentifier(); 
String idSystemString = identifiers.get(0).getSystem().getValueAsString(); 
String idValueString = identifiers.get(0).getValue().getValueAsString(); 
System.out.println(idSystemString + " " + idValueString); 
} 
} 
http://acme.org/MRNs - 7000135 
https://github.com/jamesagnew/hapi-fhir/tree/master/hapi-fhir-tutorial/skeleton-project 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
HAPI: The Key 
Components 
 Structure Classes (represent FHIR model) 
 Parsers (convert model into XML/JSON) 
 Client (use HTTP to access FHIR servers) 
 Server (build a FHIR server) 
 Utilities: 
 Validator 
 Narrative Generator 
23 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
FHIR Clients: 
Recap on REST 
 FHIR defines basic CRUD operations that 
can be performed on a FHIR compliant 
server (*not a complete list) 
24 
Name HTTP URL 
type create POST http://base/[type] 
instance read GET http://base/[type]/[id] 
instance update PUT http://base/[type]/[id] 
instance delete DELETE http://base/[type]/[id] 
type search GET http://base/[type]?[params] 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
FHIR Clients: 
Basic CRUD - Create 
25 
public class Example05_ClientCreate { 
public static void main(String[] theArgs) { 
Patient pat = new Patient(); 
pat.addName().addFamily("Simpson").addGiven("Homer").addGiven("J"); 
pat.addIdentifier().setSystem("http://acme.org/MRNs").setValue("7000135"); 
pat.setGender(AdministrativeGenderCodesEnum.M); 
// Create a context 
FhirContext ctx = new FhirContext(); 
// Create a client 
String serverBaseUrl = "http://fhirtest.uhn.ca/base"; 
IGenericClient client = ctx.newRestfulGenericClient(serverBaseUrl); 
// Use the client to store a new resource instance 
MethodOutcome outcome = client.create().resource(pat).execute(); 
// Print the ID of the newly created resource 
System.out.println(outcome.getId()); 
} 
} 
http://fhirtest.uhn.ca/base/Patient/4529/_history/1 
https://github.com/jamesagnew/hapi-fhir/tree/master/hapi-fhir-tutorial/skeleton-project 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
FHIR Clients: 
Basic CRUD - Read/Update 
public class Example06_ClientReadAndUpdate { 
public static void main(String[] theArgs) { 
// Create a client 
String serverBaseUrl = "http://fhirtest.uhn.ca/base"; 
FhirContext ctx = new FhirContext(); 
IGenericClient client = ctx.newRestfulGenericClient(serverBaseUrl); 
// Use the client to read back the new instance using the 
// ID we retrieved from the read 
Patient patient = client.read(Patient.class, "4529"); 
// Print the ID of the newly created resource 
System.out.println(patient.getId()); 
http://fhirtest.uhn.ca/base/Patient/4529/_history/1 
// Change the gender and send an update to the server 
patient.setGender(AdministrativeGenderCodesEnum.F); 
MethodOutcome outcome = client.update().resource(patient).execute(); 
System.out.println(outcome.getId()); 
} 
} 
26 
http://fhirtest.uhn.ca/base/Patient/4529/_history/2 
https://github.com/jamesagnew/hapi-fhir/tree/master/hapi-fhir-tutorial/skeleton-project 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
FHIR Clients: 
Searching 
 FHIR defines a powerful search mechanism 
 Searches are specially crafted URLs to 
express queries such as: 
 Find a Patient with the given Identifier 
 Find all Patients with given gender and 
DOB 
 Find all lab reports for a given patient 
identifier with an “abnormal” interpretation 
27 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
FHIR Clients: 
Searching (2) 
 Searching is powerful, for lots more 
information please attend FHIR Search for 
Client Developers in Q4 
 For now, let’s imagine a search for a Patient 
named “Test” whose birthdate is before 2014 
28 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
FHIR Clients: 
Searching (3) 
public class Example06_ClientReadAndUpdate { 
public static void main(String[] theArgs) { 
// Create a client 
FhirContext ctx = new FhirContext(); 
String serverBaseUrl = "http://fhirtest.uhn.ca/base"; 
IGenericClient client = ctx.newRestfulGenericClient(serverBaseUrl); 
// Build a search and execute it 
Bundle response = client.search() 
.forResource(Patient.class) 
.where(Patient.NAME.matches().value("Test")) 
.and(Patient.BIRTHDATE.before().day("2014-01-01")) 
.limitTo(100) 
.execute(); 
// How many resources did we find? 
System.out.println("Responses: " + response.size()); 
7 
// Print the ID of the first one 
IdDt firstResponseId = response.getEntries().get(0).getResource().getId(); 
System.out.println(firstResponseId); 
} 
} 
29 
http://fhirtest.uhn.ca/base/Patient/pt59/_history/1 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
FHIR Clients: 
Searching (4) 
public class Example06_ClientReadAndUpdate { 
public static void main(String[] theArgs) { 
// Create a client 
FhirContext ctx = new FhirContext(); 
String serverBaseUrl = "http://fhirtest.uhn.ca/base"; 
IGenericClient client = ctx.newRestfulGenericClient(serverBaseUrl); 
// Build a search and execute it 
Bundle response = client.search() 
.forResource(Patient.class) 
.where(Patient.NAME.matches().value("Test")) 
.and(Patient.BIRTHDATE.before().day("2014-01-01")) 
.limitTo(100) 
.execute(); 
} 
} 
30 
Many more options available for searching: 
http://jamesagnew.github.io/hapi-fhir/ 
doc_rest_client.html#Type_-_SearchQuery 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
FHIR Clients: 
Lots More 
 You can follow a similar pattern to do many 
more operations: 
 Delete, Validate, History, Tags, etc… 
 Client logging interceptor can be very helpful 
 http://jamesagnew.github.io/hapi-fhir/ 
doc_rest_client_interceptor.html#Logging:_Log_Request 
s_and_Responses 
31 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
HAPI: The Key 
Components 
 Structure Classes (represent FHIR model) 
 Parsers (convert model into XML/JSON) 
 Client (use HTTP to access FHIR servers) 
 Server (build a FHIR server) 
 Utilities: 
 Validator 
 Narrative Generator 
32 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
FHIR Server: 
Architecture 
 HAPI provides a REST Server framework 
 Based on standard JEE/Servlet 2.5+ 
(Tomcat, Glassfish, Websphere, JBoss, etc) 
33 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
FHIR Server: 
Architecture (2) 
 Architecture is 
based on 
“Resource 
Providers” which 
are custom classes 
you write to 
interact with your 
resources 
 This is a “low level” 
API for building 
servers, not an “off 
the shelf” solution 
34 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
FHIR Server: 
Defining Resource Providers 
 Resource Providers are classes you create with specially 
annotated methods (one class per resource type) 
35 
public class Example01_ResourceProviders implements IResourceProvider { 
@Read 
public Patient read(@IdParam IdDt theId) { 
return null; // populate this 
} 
@Create 
void create(@ResourceParam Patient thePatient) { 
// save the resource 
} 
@Search 
List<Patient> search( 
@OptionalParam(name="family") StringParam theFamily, 
@OptionalParam(name="given") StringParam theGiven 
) { 
return null; // populate this 
} 
} 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
FHIR Server: 
A Simple Example 
 The following slides show a simple example 
building a FHIR server using HAPI 
 Resources are stored in a HashMap (could 
just as easily be a database or something 
else!) 
 These samples can be downloaded and 
executed on your laptop very easily 
36 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
FHIR Server: 
A simple resource provider 
37 
public class Example02_PatientResourceProvider implements IResourceProvider { 
private Map<Long, Patient> myPatients = new HashMap<Long, Patient>(); 
/** Constructor */ 
public Example02_PatientResourceProvider() { 
Patient pat1 = new Patient(); 
pat1.addIdentifier().setSystem("http://acme.com/MRNs").setValue("7000135"); 
pat1.addName().addFamily("Simpson").addGiven("Homer").addGiven("J"); 
myPatients.put(1L, pat1); 
} 
/** Simple implementation of the "read" method */ 
@Read() 
public Patient read(@IdParam IdDt theId) { 
Patient retVal = myPatients.get(theId.getIdPartAsLong()); 
if (retVal == null) { 
throw new ResourceNotFoundException(theId); 
} 
return retVal; 
} 
} https://github.com/jamesagnew/hapi-fhir/tree/master/hapi-fhir-tutorial/simple-server 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
FHIR Server: 
A simple server 
38 
 The servlet is very simple: it creates an instance of each 
resource provider and declares the servlet path 
@WebServlet("/example02/*") 
public class Example02_SimpleRestfulServer extends RestfulServer { 
private static final long serialVersionUID = 1L; 
@Override 
protected void initialize() throws ServletException { 
setResourceProviders(new Example02_PatientResourceProvider()); 
} 
} 
https://github.com/jamesagnew/hapi-fhir/tree/master/hapi-fhir-tutorial/simple-server 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
FHIR Server: 
Trying the server out 
 Console 1: Start Server 
39 
james$ mvn jetty:run 
[INFO] Scanning for projects... 
2014-11-21 12:27:37.622:WARN:oejsh.RequestLogHandler:main: !RequestLog 
2014-11-21 12:27:37.669:INFO:oejs.ServerConnector:main: Started ServerConnect 
[INFO] Started Jetty Server 
 Console 2: Try it out! 
james$ curl “http://localhost:8080/example02/Patient/1" 
<Patient xmlns="http://hl7.org/fhir"><identifier><system 
value="http://acme.com/MRNs"/><value 
value="7000135"/></identifier><name><family value="Simpson"/><given 
value="Homer"/><given value="J"/></name></Patient> 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
FHIR Server: 
Trying the server out (2) 
 Console 1: Start Server 
40 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
FHIR Server: 
Adding Create and Search 
41 
public class Example03_PatientResourceProvider implements IResourceProvider { 
// [ … some methods not shown … ] 
@Create 
public MethodOutcome create(@ResourceParam Patient thePatient) { 
// Give the resource the next sequential ID 
long id = myNextId++; 
thePatient.setId(new IdDt(id)); 
// Store the resource in memory 
myPatients.put(id, thePatient); 
// Inform the server of the ID for the newly stored resource 
return new MethodOutcome(thePatient.getId()); 
} 
@Search 
public List<Patient> search() { 
List<Patient> retVal = new ArrayList<Patient>(); 
retVal.addAll(myPatients.values()); 
return retVal; 
} 
} 
https://github.com/jamesagnew/hapi-fhir/tree/master/hapi-fhir-tutorial/simple-server 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
FHIR Server: 
Testing out Create 
 The following command executes a ‘create’ 
42 
curl -H "Content-Type: application/xml+fhir"  
-X POST  
-d '<Patient xmlns="http://hl7.org/fhir"><name><family value="Fireman"/><given value=""http://localhost:8080/example03/Patient" 
 Now perform a search 
$ curl “http://localhost:8080/example03/Patient?_pretty=true” 
<feed xmlns="http://www.w3.org/2005/Atom"> 
<os:totalResults>2</os:totalResults> 
<entry> 
<title>Patient 1</title> 
[ … snip … ] 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
http://acme.com/Patient?family=SMITH 
@Search 
public List<Patient> search(@RequiredParam(name="family") StringParam theParam) { 
} 
43 
FHIR Server: 
Adding Search Params 
List<Patient> retVal = new ArrayList<Patient>(); 
// Loop through the patients looking for matches 
for (Patient next : myPatients.values()) { 
String familyName = next.getNameFirstRep().getFamilyAsSingleString().toLowerCase(); 
if (familyName.contains(theParam.getValue().toLowerCase()) == false) { 
continue; 
} 
retVal.add(next); 
return retVal; 
https://github.com/jamesagnew/hapi-fhir/tree/master/hapi-fhir-tutorial/simple-server 
} 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
FHIR Server: 
Much more is available 
 Combining multiple parameters 
 Parameters for sorting, limiting, paging, etc. 
44 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
45 
FHIR Server: 
Learn More 
 Implementing a server which supports the full 
FHIR functionality is tricky! For some good 
insight, please attend “FHIR Search for 
Server Developers” in Q4 
https://github.com/jamesagnew/hapi-fhir/tree/master/hapi-fhir-tutorial/simple-server 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
HAPI: The Key 
Components 
 Structure Classes (represent FHIR model) 
 Parsers (convert model into XML/JSON) 
 Client (use HTTP to access FHIR servers) 
 Server (build a FHIR server) 
 Utilities: 
 Validator 
 Narrative Generator 
46 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
FHIR Validation 
 FHIR distributes a set of Schema (XSD) and 
Schematron (SCH) files containing FHIR 
validation rules 
 These are included with HAPI and may be 
applied using the validation framework 
 Rules include: 
 Coded element must have valid code 
 Date “from” must be before date “to” 
47 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
FHIR Validation: 
A simple example 
48 
public class Example08_ValidateResource { 
public static void main(String[] args) { 
// Create an encounter with an invalid status and no class 
Encounter enc = new Encounter(); 
enc.getStatus().setValueAsString("invalid_status"); 
// Create a new validator 
FhirContext ctx = new FhirContext(); 
FhirValidator validator = ctx.newValidator(); 
// Did we succeed? 
ValidationResult result = validator.validateWithResult(enc); 
System.out.println("Success: " + result.isSuccessful()); 
// What was the result 
OperationOutcome outcome = result.getOperationOutcome(); 
IParser parser = ctx.newXmlParser().setPrettyPrint(true); 
System.out.println(parser.encodeResourceToString(outcome)); 
} 
} https://github.com/jamesagnew/hapi-fhir/tree/master/hapi-fhir-tutorial/skeleton-project 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
FHIR Validation: 
A simple example 
49 
<OperationOutcome xmlns="http://hl7.org/fhir"> 
<issue> 
public class Example08_ValidateResource { 
public static void main(String[] args) { 
<severity value="error"/> 
<details value="cvc-enumeration-valid: Value 'invalid_status' is 
// Create an encounter with an invalid status and no class 
Encounter enc = new Encounter(); 
enc.getStatus().setValueAsString("invalid_status"); 
not facet-valid with respect to enumeration '[planned, in progress, 
onleave, finished, cancelled]'. It must be a value from the 
enumeration."/> 
// Create a new validator 
FhirContext ctx = new FhirContext(); 
FhirValidator validator = ctx.newValidator(); 
<location value="Line[1] Col[72]"/> 
</issue> 
// <Did issue> 
we succeed? 
ValidationResult result = validator.validateWithResult(enc); 
System.<severity out.println("value="Success: error"/> 
" + result.isSuccessful()); 
<details value="cvc-attribute.3: The value 'invalid_status' of 
attribute 'value' on element 'status' is not valid with respect to its 
type, 'EncounterState-list'."/> 
// What was the result 
OperationOutcome outcome = result.getOperationOutcome(); 
IParser parser = ctx.newXmlParser().setPrettyPrint(true); 
System.out.println(parser.encodeResourceToString(outcome)); 
} 
} 
<location value="Line[1] Col[72]"/> 
</issue> 
<issue> 
<severity value="error"/> 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
FHIR Validation: 
Scope 
50 
 Validator currently validates against Schema 
and Schematron only 
 Still to come: 
 ValueSet validation 
 Profile validation 
 We would love help on these! :) 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
The Narrative Generator 
 HAPI comes with a module for generating 
HTML narratives based on resources 
 Generator uses Thymeleaf templating engine 
from http://www.thymeleaf.org/ 
51 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
Using the Narrative 
Generator 
public class Example09_NarrativeGenerator { 
} 
52 
public static void main(String[] args) { 
// Create an encounter with an invalid status and no class 
Patient pat = new Patient(); 
pat.addName().addFamily("Simpson").addGiven("Homer").addGiven("Jay"); 
pat.addAddress().addLine("342 Evergreen Terrace").addLine("Springfield"); 
pat.addIdentifier().setLabel("MRN: 12345"); 
// Create a new context and enable the narrative generator 
FhirContext ctx = new FhirContext(); 
ctx.setNarrativeGenerator(new DefaultThymeleafNarrativeGenerator()); 
String res = ctx.newJsonParser().setPrettyPrint(true).encodeResourceToString(pat); 
System.out.println(res); 
} 
https://github.com/jamesagnew/hapi-fhir/tree/master/hapi-fhir-tutorial/skeleton-project 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
Using the Narrative 
Generator 
public class Example09_NarrativeGenerator { 
} 
53 
public static void main(String[] args) { 
A narrative generator is configured against a single FhirContext and 
// Create an encounter with an invalid status and no class 
Patient pat = new Patient(); 
applies to everything generated by it 
pat.addName().addFamily("Simpson").addGiven("Homer").addGiven("Jay"); 
pat.addAddress().addLine("342 Evergreen Terrace").addLine("Springfield"); 
pat.addIdentifier().setLabel("MRN: 12345"); 
// Create a new context and enable the narrative generator 
FhirContext ctx = new FhirContext(); 
ctx.setNarrativeGenerator(new DefaultThymeleafNarrativeGenerator()); 
String res = ctx.newJsonParser().setPrettyPrint(true).encodeResourceToString(pat); 
System.out.println(res); 
} 
https://github.com/jamesagnew/hapi-fhir/tree/master/hapi-fhir-tutorial/skeleton-project 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
Using the Narrative 
Generator 
[ … snip … ] 
<div><div class="hapiHeaderText"> Homer Jay <b>SIMPSON 
</b></div><table 
class="hapiPropertyTable"><tbody><tr><td>Identifier</td><td>MRN: 
12345</td></tr><tr><td>Address</td><td><span>342 Evergreen 
Terrace </span><br/><span>Springfield 
</span><br/></td></tr></tbody></table></div> 
[ … snip … ] 
public class Example09_NarrativeGenerator { 
} 
54 
public static void main(String[] args) { 
// Create an encounter with an invalid status and no class 
Patient pat = new Patient(); 
pat.addName().addFamily("Simpson").addGiven("Homer").addGiven("Jay"); 
pat.addAddress().addLine("342 Evergreen Terrace").addLine("Springfield"); 
pat.addIdentifier().setLabel("MRN: 12345"); 
// Create a new context and enable the narrative generator 
FhirContext ctx = new FhirContext(); 
ctx.setNarrativeGenerator(new DefaultThymeleafNarrativeGenerator()); 
String res = ctx.newJsonParser().setPrettyPrint(true).encodeResourceToString(pat); 
System.out.println(res); 
} 
https://github.com/jamesagnew/hapi-fhir/tree/master/hapi-fhir-tutorial/skeleton-project 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
Sample Generated 
Narrative 
 Generated narratives can be seen on our test 
server: 
http://fhirtest.uhn.ca/read?serverId=home&re 
source=DiagnosticReport&action=read&id=8 
4&vid=1 
55 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
Extensions: The Easy 
Way 
 Every element has a collection of 
“undeclared” extensions 
56 
public class Example10_Extensions { 
public static void main(String[] args) { 
Patient pat = new Patient(); 
pat.addName().addFamily("Simpson").addGiven("Homer"); 
String url = "http://acme.org#eyeColour"; 
boolean isModifier = false; 
pat.addUndeclaredExtension(isModifier, url).setValue(new CodeDt(“blue")); 
IParser p = new FhirContext().newXmlParser().setPrettyPrint(true); 
String encoded = p.encodeResourceToString(pat); 
System.out.println(encoded); 
} 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office. 
}
Extensions: The Easy 
Way 
 Every element has a collection of 
“undeclared” extensions 
57 
public class Example10_Extensions { 
public static void main(String[] args) { 
Patient pat = new Patient(); 
pat.addName().addFamily("Simpson").addGiven("Homer"); 
String url = "http://acme.org#eyeColour"; 
boolean isModifier = false; 
pat.addUndeclaredExtension(isModifier, url).setValue(new CodeDt(“blue")); 
IParser p = new FhirContext().newXmlParser().setPrettyPrint(true); 
String encoded = p.encodeResourceToString(pat); 
System.out.println(encoded); 
} 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office. 
} 
<Patient xmlns="http://hl7.org/fhir"> 
<extension url="http://acme.org#eyeColour"> 
<valueCode value="blue"/> 
</extension> 
<name> 
<family value="Simpson"/> 
<given value="Homer"/> 
</name> 
</Patient>
Extensions: The “Hard” 
Way 
 HAPI also provides a set of annotations for 
creating statically typed extensions 
58 
@ResourceDef(name="Patient") 
public class Example11_ExtendedPatient extends Patient { 
@Child(name = "eyeColour") 
@Extension(url="http://acme.org/#extpt", definedLocally = false, isModifier = false) 
private CodeDt myEyeColour; 
public CodeDt getEyeColour() { 
if (myEyeColour == null) { 
myEyeColour = new CodeDt(); 
} 
return myEyeColour; 
} 
public void setEyeColour(CodeDt theEyeColour) { 
myEyeColour = theEyeColour; 
} 
} 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
Get Help! 
 See our website for documentation: 
http://jamesagnew.github.io/hapi-fhir/ 
 We also have a Google Group / Mailing List 
https://groups.google.com/d/forum/hapi-fhir 
59 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
Get Involved! 
 HAPI is a large worldwide community of 
developers 
 Today most are working on HL7 v2, but this 
is changing fast 
 We are very grateful to the many people who 
have contributed so far, maybe you could be 
next? 
60 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
HAPI: Other Topics 
 Web Testing UI: The testing interface shown 
on our test server may be added to your own 
server 
 JPA: HAPI has a JPA module which stores 
and indexes resources in a relational 
database using Hibernate 
61 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
Thank You! 
 jamesagnew@gmail.com 
 jamesagnew214 on Skype 
62 
© 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.

Mais conteúdo relacionado

Mais procurados

Object Oriented Programming with Laravel - Session 2
Object Oriented Programming with Laravel - Session 2Object Oriented Programming with Laravel - Session 2
Object Oriented Programming with Laravel - Session 2
Shahrzad Peyman
 

Mais procurados (20)

FHIR Profiles
FHIR ProfilesFHIR Profiles
FHIR Profiles
 
HL7 New Zealand: FHIR for developers
HL7 New Zealand: FHIR for developersHL7 New Zealand: FHIR for developers
HL7 New Zealand: FHIR for developers
 
Authoring Profiles in FHIR
Authoring Profiles in FHIRAuthoring Profiles in FHIR
Authoring Profiles in FHIR
 
Pavel Smirnov. FHIR-first application development.
Pavel Smirnov. FHIR-first application development.Pavel Smirnov. FHIR-first application development.
Pavel Smirnov. FHIR-first application development.
 
Fhir dev days 2017 fhir profiling - overview and introduction v07
Fhir dev days 2017   fhir profiling - overview and introduction v07Fhir dev days 2017   fhir profiling - overview and introduction v07
Fhir dev days 2017 fhir profiling - overview and introduction v07
 
FIWARE Global Summit - NGSI-LD – an Evolution from NGSIv2
FIWARE Global Summit - NGSI-LD – an Evolution from NGSIv2FIWARE Global Summit - NGSI-LD – an Evolution from NGSIv2
FIWARE Global Summit - NGSI-LD – an Evolution from NGSIv2
 
Introduction à Neo4j - La base de données de graphes - 2016
Introduction à Neo4j - La base de données de graphes - 2016Introduction à Neo4j - La base de données de graphes - 2016
Introduction à Neo4j - La base de données de graphes - 2016
 
Extending the Power of Consent with User-Managed Access & OpenUMA
Extending the Power of Consent with User-Managed Access & OpenUMAExtending the Power of Consent with User-Managed Access & OpenUMA
Extending the Power of Consent with User-Managed Access & OpenUMA
 
How to Import JSON Using Cypher and APOC
How to Import JSON Using Cypher and APOCHow to Import JSON Using Cypher and APOC
How to Import JSON Using Cypher and APOC
 
webMethods 10.5 and webMethods.io Integration: Everything You Must Know
webMethods 10.5 and webMethods.io Integration: Everything You Must KnowwebMethods 10.5 and webMethods.io Integration: Everything You Must Know
webMethods 10.5 and webMethods.io Integration: Everything You Must Know
 
Apache web server
Apache web serverApache web server
Apache web server
 
Base de données graphe et Neo4j
Base de données graphe et Neo4jBase de données graphe et Neo4j
Base de données graphe et Neo4j
 
Spring Cloud Function: Where We Were, Where We Are, and Where We’re Going
Spring Cloud Function: Where We Were, Where We Are, and Where We’re GoingSpring Cloud Function: Where We Were, Where We Are, and Where We’re Going
Spring Cloud Function: Where We Were, Where We Are, and Where We’re Going
 
Microsoft Power Platform en Action
Microsoft Power Platform en Action Microsoft Power Platform en Action
Microsoft Power Platform en Action
 
How Graph Algorithms Answer your Business Questions in Banking and Beyond
How Graph Algorithms Answer your Business Questions in Banking and BeyondHow Graph Algorithms Answer your Business Questions in Banking and Beyond
How Graph Algorithms Answer your Business Questions in Banking and Beyond
 
MuleSoft Online Meetup a Guide to RTF application deployment - October 2020
MuleSoft Online Meetup   a Guide to RTF application deployment  - October 2020MuleSoft Online Meetup   a Guide to RTF application deployment  - October 2020
MuleSoft Online Meetup a Guide to RTF application deployment - October 2020
 
Object Oriented Programming with Laravel - Session 2
Object Oriented Programming with Laravel - Session 2Object Oriented Programming with Laravel - Session 2
Object Oriented Programming with Laravel - Session 2
 
北護大/FHIR 開發簡介與應用
北護大/FHIR 開發簡介與應用北護大/FHIR 開發簡介與應用
北護大/FHIR 開發簡介與應用
 
Session 14 - Hive
Session 14 - HiveSession 14 - Hive
Session 14 - Hive
 
HL7 FHIR For Medical Professionals.pdf
HL7 FHIR For Medical Professionals.pdfHL7 FHIR For Medical Professionals.pdf
HL7 FHIR For Medical Professionals.pdf
 

Semelhante a FHIR API for Java programmers by James Agnew

Semelhante a FHIR API for Java programmers by James Agnew (20)

Validation in net and java (ewout james)
Validation in net and java (ewout james)Validation in net and java (ewout james)
Validation in net and java (ewout james)
 
Fhir path (ewout)
Fhir path (ewout)Fhir path (ewout)
Fhir path (ewout)
 
Advanced .NET API (Ewout)
Advanced .NET API (Ewout)Advanced .NET API (Ewout)
Advanced .NET API (Ewout)
 
Advanced .net api (ewout)
Advanced .net api (ewout)Advanced .net api (ewout)
Advanced .net api (ewout)
 
FHIR Tutorial - Morning
FHIR Tutorial - MorningFHIR Tutorial - Morning
FHIR Tutorial - Morning
 
Structure definition 101 (ewout)
Structure definition 101 (ewout)Structure definition 101 (ewout)
Structure definition 101 (ewout)
 
FHIR Search for client developers by Mirjam Baltus
FHIR Search for client developers by Mirjam BaltusFHIR Search for client developers by Mirjam Baltus
FHIR Search for client developers by Mirjam Baltus
 
Terminology, value-sets, codesystems by Lloyd McKenzie
Terminology, value-sets, codesystems by Lloyd McKenzieTerminology, value-sets, codesystems by Lloyd McKenzie
Terminology, value-sets, codesystems by Lloyd McKenzie
 
Introduction to FHIR™
Introduction to FHIR™Introduction to FHIR™
Introduction to FHIR™
 
Profile and validation by Grahame Grieve
Profile and validation by Grahame GrieveProfile and validation by Grahame Grieve
Profile and validation by Grahame Grieve
 
Vitalis 2016 FHIR Introduction
Vitalis 2016 FHIR IntroductionVitalis 2016 FHIR Introduction
Vitalis 2016 FHIR Introduction
 
The FHIR burns brighter (what's new in DSTU2)
The FHIR burns brighter (what's new in DSTU2)The FHIR burns brighter (what's new in DSTU2)
The FHIR burns brighter (what's new in DSTU2)
 
SMART on FHIR by Scot Post van der Burg
SMART on FHIR by Scot Post van der BurgSMART on FHIR by Scot Post van der Burg
SMART on FHIR by Scot Post van der Burg
 
SMART on FHIR by Scot Post van der Burg
SMART on FHIR by Scot Post van der BurgSMART on FHIR by Scot Post van der Burg
SMART on FHIR by Scot Post van der Burg
 
FHIR architecture overview for non-programmers by René Spronk
FHIR architecture overview for non-programmers by René SpronkFHIR architecture overview for non-programmers by René Spronk
FHIR architecture overview for non-programmers by René Spronk
 
FHIR architecture overview for non-programmers by René Spronk
FHIR architecture overview for non-programmers by René SpronkFHIR architecture overview for non-programmers by René Spronk
FHIR architecture overview for non-programmers by René Spronk
 
Authoring profiles by Michel Rutten
Authoring profiles by Michel RuttenAuthoring profiles by Michel Rutten
Authoring profiles by Michel Rutten
 
Nhs trusts meeting at salford
Nhs trusts meeting at salfordNhs trusts meeting at salford
Nhs trusts meeting at salford
 
Vitalis 2016 FHIR App Development
Vitalis 2016 FHIR App DevelopmentVitalis 2016 FHIR App Development
Vitalis 2016 FHIR App Development
 
Security in FHIR with OAuth by Grahame Grieve
Security in FHIR with OAuth by Grahame GrieveSecurity in FHIR with OAuth by Grahame Grieve
Security in FHIR with OAuth by Grahame Grieve
 

Último

Best Lahore Escorts 😮‍💨03250114445 || VIP escorts in Lahore
Best Lahore Escorts 😮‍💨03250114445 || VIP escorts in LahoreBest Lahore Escorts 😮‍💨03250114445 || VIP escorts in Lahore
Best Lahore Escorts 😮‍💨03250114445 || VIP escorts in Lahore
Deny Daniel
 
Gorgeous Call Girls In Pune {9xx000xx09} ❤️VVIP ANKITA Call Girl in Pune Maha...
Gorgeous Call Girls In Pune {9xx000xx09} ❤️VVIP ANKITA Call Girl in Pune Maha...Gorgeous Call Girls In Pune {9xx000xx09} ❤️VVIP ANKITA Call Girl in Pune Maha...
Gorgeous Call Girls In Pune {9xx000xx09} ❤️VVIP ANKITA Call Girl in Pune Maha...
Sheetaleventcompany
 
Escorts Lahore || 🔞 03274100048 || Escort service in Lahore
Escorts Lahore || 🔞 03274100048 || Escort service in LahoreEscorts Lahore || 🔞 03274100048 || Escort service in Lahore
Escorts Lahore || 🔞 03274100048 || Escort service in Lahore
Deny Daniel
 
9316020077📞Majorda Beach Call Girls Numbers, Call Girls Whatsapp Numbers Ma...
9316020077📞Majorda Beach Call Girls  Numbers, Call Girls  Whatsapp Numbers Ma...9316020077📞Majorda Beach Call Girls  Numbers, Call Girls  Whatsapp Numbers Ma...
9316020077📞Majorda Beach Call Girls Numbers, Call Girls Whatsapp Numbers Ma...
Goa cutee sexy top girl
 
Call Girl in Bangalore 9632137771 {LowPrice} ❤️ (Navya) Bangalore Call Girls ...
Call Girl in Bangalore 9632137771 {LowPrice} ❤️ (Navya) Bangalore Call Girls ...Call Girl in Bangalore 9632137771 {LowPrice} ❤️ (Navya) Bangalore Call Girls ...
Call Girl in Bangalore 9632137771 {LowPrice} ❤️ (Navya) Bangalore Call Girls ...
mahaiklolahd
 
Call Girls Service Chandigarh Sexy Video ❤️🍑 8511114078 👄🫦 Independent Escort...
Call Girls Service Chandigarh Sexy Video ❤️🍑 8511114078 👄🫦 Independent Escort...Call Girls Service Chandigarh Sexy Video ❤️🍑 8511114078 👄🫦 Independent Escort...
Call Girls Service Chandigarh Sexy Video ❤️🍑 8511114078 👄🫦 Independent Escort...
Sheetaleventcompany
 
💚Chandigarh Call Girls Service 💯Jiya 📲🔝8868886958🔝Call Girls In Chandigarh No...
💚Chandigarh Call Girls Service 💯Jiya 📲🔝8868886958🔝Call Girls In Chandigarh No...💚Chandigarh Call Girls Service 💯Jiya 📲🔝8868886958🔝Call Girls In Chandigarh No...
💚Chandigarh Call Girls Service 💯Jiya 📲🔝8868886958🔝Call Girls In Chandigarh No...
Sheetaleventcompany
 
👉Bangalore Call Girl Service👉📞 9179660964 👉📞 Just📲 Call Rajveer Call Girls Se...
👉Bangalore Call Girl Service👉📞 9179660964 👉📞 Just📲 Call Rajveer Call Girls Se...👉Bangalore Call Girl Service👉📞 9179660964 👉📞 Just📲 Call Rajveer Call Girls Se...
👉Bangalore Call Girl Service👉📞 9179660964 👉📞 Just📲 Call Rajveer Call Girls Se...
Sheetaleventcompany
 
Low Rate Call Girls Pune {9xx000xx09} ❤️VVIP NISHA Call Girls in Pune Maharas...
Low Rate Call Girls Pune {9xx000xx09} ❤️VVIP NISHA Call Girls in Pune Maharas...Low Rate Call Girls Pune {9xx000xx09} ❤️VVIP NISHA Call Girls in Pune Maharas...
Low Rate Call Girls Pune {9xx000xx09} ❤️VVIP NISHA Call Girls in Pune Maharas...
Sheetaleventcompany
 

Último (20)

Rishikesh Call Girls Service 6398383382 Real Russian Girls Looking Models
Rishikesh Call Girls Service 6398383382 Real Russian Girls Looking ModelsRishikesh Call Girls Service 6398383382 Real Russian Girls Looking Models
Rishikesh Call Girls Service 6398383382 Real Russian Girls Looking Models
 
Vip Call Girls Makarba 👙 6367187148 👙 Genuine WhatsApp Number for Real Meet
Vip Call Girls Makarba 👙 6367187148 👙 Genuine WhatsApp Number for Real MeetVip Call Girls Makarba 👙 6367187148 👙 Genuine WhatsApp Number for Real Meet
Vip Call Girls Makarba 👙 6367187148 👙 Genuine WhatsApp Number for Real Meet
 
Best Lahore Escorts 😮‍💨03250114445 || VIP escorts in Lahore
Best Lahore Escorts 😮‍💨03250114445 || VIP escorts in LahoreBest Lahore Escorts 😮‍💨03250114445 || VIP escorts in Lahore
Best Lahore Escorts 😮‍💨03250114445 || VIP escorts in Lahore
 
Gorgeous Call Girls In Pune {9xx000xx09} ❤️VVIP ANKITA Call Girl in Pune Maha...
Gorgeous Call Girls In Pune {9xx000xx09} ❤️VVIP ANKITA Call Girl in Pune Maha...Gorgeous Call Girls In Pune {9xx000xx09} ❤️VVIP ANKITA Call Girl in Pune Maha...
Gorgeous Call Girls In Pune {9xx000xx09} ❤️VVIP ANKITA Call Girl in Pune Maha...
 
Jaipur Call Girls 9257276172 Call Girl in Jaipur Rajasthan
Jaipur Call Girls 9257276172 Call Girl in Jaipur RajasthanJaipur Call Girls 9257276172 Call Girl in Jaipur Rajasthan
Jaipur Call Girls 9257276172 Call Girl in Jaipur Rajasthan
 
Escorts Lahore || 🔞 03274100048 || Escort service in Lahore
Escorts Lahore || 🔞 03274100048 || Escort service in LahoreEscorts Lahore || 🔞 03274100048 || Escort service in Lahore
Escorts Lahore || 🔞 03274100048 || Escort service in Lahore
 
Gorgeous Call Girls Mohali {7435815124} ❤️VVIP ANGEL Call Girls in Mohali Punjab
Gorgeous Call Girls Mohali {7435815124} ❤️VVIP ANGEL Call Girls in Mohali PunjabGorgeous Call Girls Mohali {7435815124} ❤️VVIP ANGEL Call Girls in Mohali Punjab
Gorgeous Call Girls Mohali {7435815124} ❤️VVIP ANGEL Call Girls in Mohali Punjab
 
9316020077📞Majorda Beach Call Girls Numbers, Call Girls Whatsapp Numbers Ma...
9316020077📞Majorda Beach Call Girls  Numbers, Call Girls  Whatsapp Numbers Ma...9316020077📞Majorda Beach Call Girls  Numbers, Call Girls  Whatsapp Numbers Ma...
9316020077📞Majorda Beach Call Girls Numbers, Call Girls Whatsapp Numbers Ma...
 
Call Girl in Bangalore 9632137771 {LowPrice} ❤️ (Navya) Bangalore Call Girls ...
Call Girl in Bangalore 9632137771 {LowPrice} ❤️ (Navya) Bangalore Call Girls ...Call Girl in Bangalore 9632137771 {LowPrice} ❤️ (Navya) Bangalore Call Girls ...
Call Girl in Bangalore 9632137771 {LowPrice} ❤️ (Navya) Bangalore Call Girls ...
 
Call Girls Service Chandigarh Sexy Video ❤️🍑 8511114078 👄🫦 Independent Escort...
Call Girls Service Chandigarh Sexy Video ❤️🍑 8511114078 👄🫦 Independent Escort...Call Girls Service Chandigarh Sexy Video ❤️🍑 8511114078 👄🫦 Independent Escort...
Call Girls Service Chandigarh Sexy Video ❤️🍑 8511114078 👄🫦 Independent Escort...
 
💚Chandigarh Call Girls Service 💯Jiya 📲🔝8868886958🔝Call Girls In Chandigarh No...
💚Chandigarh Call Girls Service 💯Jiya 📲🔝8868886958🔝Call Girls In Chandigarh No...💚Chandigarh Call Girls Service 💯Jiya 📲🔝8868886958🔝Call Girls In Chandigarh No...
💚Chandigarh Call Girls Service 💯Jiya 📲🔝8868886958🔝Call Girls In Chandigarh No...
 
Dehradun Call Girls 8854095900 Call Girl in Dehradun Uttrakhand
Dehradun Call Girls 8854095900 Call Girl in Dehradun  UttrakhandDehradun Call Girls 8854095900 Call Girl in Dehradun  Uttrakhand
Dehradun Call Girls 8854095900 Call Girl in Dehradun Uttrakhand
 
Kolkata Call Girls Miss Inaaya ❤️ at @30% discount Everyday Call girl
Kolkata Call Girls Miss Inaaya ❤️ at @30% discount Everyday Call girlKolkata Call Girls Miss Inaaya ❤️ at @30% discount Everyday Call girl
Kolkata Call Girls Miss Inaaya ❤️ at @30% discount Everyday Call girl
 
Independent Call Girls Service Chandigarh Sector 17 | 8868886958 | Call Girl ...
Independent Call Girls Service Chandigarh Sector 17 | 8868886958 | Call Girl ...Independent Call Girls Service Chandigarh Sector 17 | 8868886958 | Call Girl ...
Independent Call Girls Service Chandigarh Sector 17 | 8868886958 | Call Girl ...
 
Kochi call girls Mallu escort girls available 7877702510
Kochi call girls Mallu escort girls available 7877702510Kochi call girls Mallu escort girls available 7877702510
Kochi call girls Mallu escort girls available 7877702510
 
(Big Boobs Indian Girls) 💓 9257276172 💓High Profile Call Girls Jaipur You Can...
(Big Boobs Indian Girls) 💓 9257276172 💓High Profile Call Girls Jaipur You Can...(Big Boobs Indian Girls) 💓 9257276172 💓High Profile Call Girls Jaipur You Can...
(Big Boobs Indian Girls) 💓 9257276172 💓High Profile Call Girls Jaipur You Can...
 
👉Bangalore Call Girl Service👉📞 9179660964 👉📞 Just📲 Call Rajveer Call Girls Se...
👉Bangalore Call Girl Service👉📞 9179660964 👉📞 Just📲 Call Rajveer Call Girls Se...👉Bangalore Call Girl Service👉📞 9179660964 👉📞 Just📲 Call Rajveer Call Girls Se...
👉Bangalore Call Girl Service👉📞 9179660964 👉📞 Just📲 Call Rajveer Call Girls Se...
 
Low Rate Call Girls Pune {9xx000xx09} ❤️VVIP NISHA Call Girls in Pune Maharas...
Low Rate Call Girls Pune {9xx000xx09} ❤️VVIP NISHA Call Girls in Pune Maharas...Low Rate Call Girls Pune {9xx000xx09} ❤️VVIP NISHA Call Girls in Pune Maharas...
Low Rate Call Girls Pune {9xx000xx09} ❤️VVIP NISHA Call Girls in Pune Maharas...
 
Budhwar Peth ( Call Girls ) Pune 6297143586 Hot Model With Sexy Bhabi Ready...
Budhwar Peth ( Call Girls ) Pune  6297143586  Hot Model With Sexy Bhabi Ready...Budhwar Peth ( Call Girls ) Pune  6297143586  Hot Model With Sexy Bhabi Ready...
Budhwar Peth ( Call Girls ) Pune 6297143586 Hot Model With Sexy Bhabi Ready...
 
Ludhiana Call Girls Service Just Call 6367187148 Top Class Call Girl Service ...
Ludhiana Call Girls Service Just Call 6367187148 Top Class Call Girl Service ...Ludhiana Call Girls Service Just Call 6367187148 Top Class Call Girl Service ...
Ludhiana Call Girls Service Just Call 6367187148 Top Class Call Girl Service ...
 

FHIR API for Java programmers by James Agnew

  • 1. HAPI-FHIR for Java Developers James Agnew FHIR Developer Days November 24, 2014 © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 2. Who am I?  Name: James Agnew  Company: University Health Network  Background:  Software development manager for a large hospital network  Project lead for HAPI for 9 years © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office. 2
  • 3. About this Presentation  All code samples are available on GitHub in fully working form  HAPI is too big a topic for 1.5 hours :) so…  I will be around all day Monday to Wednesday to expand on topics I don’t cover here and help you with your projects 3 © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 4. FHIR: A Quick Recap  There are two key parts of FHIR to consider:  The first is a data model for healthcare Resources and supporting Datatypes © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office. 4
  • 5.  The second is a RESTful API for interacting with that model © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office. 5 FHIR: A Quick Recap (2)
  • 6. The HAPI Project  HAPI started in 2001 as an HL7 v2 Library  Built to support a simple web portal, now used in applications around the world HL7 v2 - http://hl7api.sourceforge.net FHIR - http://jamesagnew.github.io/hapi-fhir/ © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office. 6
  • 7. HAPI FHIR: What?  Not a client or a server, but a toolkit for building either 7 © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 8. HAPI FHIR: Why?  HAPI FHIR was started to simplify access to our internal data sources © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office. 8
  • 9. Design Goals  Use Anywhere  Apache 2.0 License for all components  Minimal dependencies  Be Flexible  Loosely coupled, pluggable components  Be Powerful  “Steal” all the best ideas from existing frameworks: JAX-WS, Springframework, .NET FHIR API  ..etc.. © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office. 9
  • 10. HAPI: The Key Components  Structure Classes (represent FHIR model)  Parsers (convert model into XML/JSON)  Client (use HTTP to access FHIR servers)  Server (build a FHIR server)  Utilities:  Validator  Narrative Generator 10 © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 11. Structures Classes: The FHIR Model  HAPI Defines several sets of classes which form the data model  Resource definition classes implement IResource  Examples: Patient, CarePlan, Encounter, Practitioner, Medication 11 © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 12. Structures Classes: The FHIR Model (2)  HAPI also defines a class for each data type  Datatype classes are named [name]Dt  Primitive types include: StringDt, AgeDt, BooleanDt  Composite types include: AddressDt, RatioDt 12 © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 13. Structures Classes: The FHIR Model (3)  JavaDocs for structures are available here: http://jamesagnew.github.io/hapi-fhir/apidocs-dstu/index.html 13 © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 14. Taking the Structures for a spin  Patient Resource (http://hl7.org/implement/standards/fhir/patient.html) 14  HumanName Datatype © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 15. Taking the Structures for a spin (2) 15 public class Example01_CreateAPatient { public static void main(String[] theArgs) { // Create a resource instance Patient pat = new Patient(); // Add a "name" element HumanNameDt name = pat.addName(); name.addFamily("Simpson").addGiven("Homer").addGiven("J"); // Add an "identifier" element IdentifierDt identifier = pat.addIdentifier(); identifier.setSystem("http://acme.org/MRNs").setValue("7000135"); // Model is designed to be chained pat.addIdentifier().setLabel("Library Card 12345").setValue("12345"); } } https://github.com/jamesagnew/hapi-fhir/tree/master/hapi-fhir-tutorial/skeleton-project © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 16. Taking the Structures for a spin (3) 16 public class Example01_CreateAPatient { public static void main(String[] theArgs) { // Create a resource instance Patient pat = new Patient(); // Add a "name" element HumanNameDt name = pat.addName(); name.addFamily("Simpson").addGiven("Homer").addGiven("J"); © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 17. Taking the Structures for a spin (4) 17 public class Example02_CreateAPatient { public static void main(String[] theArgs) { Patient pat = new Patient(); pat.addName().addFamily("Simpson").addGiven("Homer").addGiven("J"); pat.addIdentifier().setSystem("http://acme.org/MRNs").setValue("7000135"); pat.addIdentifier().setLabel("Library Card 12345").setValue("12345"); // Enumerated types are provided for many coded elements ContactDt contact = pat.addTelecom(); contact.setUse(ContactUseEnum.HOME); contact.setSystem(ContactSystemEnum.PHONE); contact.setValue("1 (416) 340-4800"); pat.setGender(AdministrativeGenderCodesEnum.M); } } https://github.com/jamesagnew/hapi-fhir/tree/master/hapi-fhir-tutorial/skeleton-project © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 18. HAPI: The Key Components  Structure Classes (represent FHIR model)  Parsers (convert model into XML/JSON)  Client (use HTTP to access FHIR servers)  Server (build a FHIR server)  Utilities:  Validator  Narrative Generator 18 © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 19. Playing with Parsers 19  The starting point for much of the HAPI-FHIR API is the FhirContext class  FhirContext acts as a factory for the rest of the API, including the two parsers:  XmlParser  JsonParser  FhirContext is designed to be created once and reused (important for performance!) © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 20. Playing with Parsers: Encoding Resources 20 public class Example03_EncodeResource { public static void main(String[] theArgs) { // Create a Patient Patient pat = new Patient(); pat.addName().addFamily("Simpson").addGiven("Homer").addGiven("J"); pat.addIdentifier().setSystem("http://acme.org/MRNs").setValue("7000135"); // [.. snip ..] // Create a context FhirContext ctx = new FhirContext(); // Create a XML parser IParser p = ctx.newXmlParser(); p.setPrettyPrint(true); String encode = p.encodeResourceToString(pat); System.out.println(encode); } } https://github.com/jamesagnew/hapi-fhir/tree/master/hapi-fhir-tutorial/skeleton-project © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 21. Playing with Parsers: Encoding Resources (2) 21 // Create a context FhirContext ctx = new FhirContext(); // Create a XML parser IParser parser = ctx.newXmlParser(); parser.setPrettyPrint(true); String encode = parser .encodeResourceToString(pat); System.out.println(encode); <Patient xmlns="http://hl7.org/fhir"> <identifier> <system value=“http://acme.org/MRNs"/> <value value="7000135"/> </identifier> <name> <family value="Simpson"/> <given value="Homer"/> <given value="J"/> </name> <telecom> <system value="phone"/> <value value="1 (416) 340-4800"/> <use value="home"/> </telecom> <gender> <coding> <system value="http://hl7.org/fhir/v3/AdministrativeGender"/> <code value="M"/> </coding> </gender> </Patient> © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 22. Playing with Parsers: Parsing Resources 22 public class Example04_ParseResource { public static void main(String[] theArgs) { String resourceBody = "{"resourceType":"Patient","identifier":[{"system":"http://acme.org/MRNs","value":"7000135"}], "name":[{"family":["Simpson"],"given":["Homer","J"]}]}"; // Create a context FhirContext ctx = new FhirContext(); // Create a JSON parser IParser parser = ctx.newJsonParser(); Patient pat = parser.parseResource(Patient.class, resourceBody); List<IdentifierDt> identifiers = pat.getIdentifier(); String idSystemString = identifiers.get(0).getSystem().getValueAsString(); String idValueString = identifiers.get(0).getValue().getValueAsString(); System.out.println(idSystemString + " " + idValueString); } } http://acme.org/MRNs - 7000135 https://github.com/jamesagnew/hapi-fhir/tree/master/hapi-fhir-tutorial/skeleton-project © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 23. HAPI: The Key Components  Structure Classes (represent FHIR model)  Parsers (convert model into XML/JSON)  Client (use HTTP to access FHIR servers)  Server (build a FHIR server)  Utilities:  Validator  Narrative Generator 23 © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 24. FHIR Clients: Recap on REST  FHIR defines basic CRUD operations that can be performed on a FHIR compliant server (*not a complete list) 24 Name HTTP URL type create POST http://base/[type] instance read GET http://base/[type]/[id] instance update PUT http://base/[type]/[id] instance delete DELETE http://base/[type]/[id] type search GET http://base/[type]?[params] © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 25. FHIR Clients: Basic CRUD - Create 25 public class Example05_ClientCreate { public static void main(String[] theArgs) { Patient pat = new Patient(); pat.addName().addFamily("Simpson").addGiven("Homer").addGiven("J"); pat.addIdentifier().setSystem("http://acme.org/MRNs").setValue("7000135"); pat.setGender(AdministrativeGenderCodesEnum.M); // Create a context FhirContext ctx = new FhirContext(); // Create a client String serverBaseUrl = "http://fhirtest.uhn.ca/base"; IGenericClient client = ctx.newRestfulGenericClient(serverBaseUrl); // Use the client to store a new resource instance MethodOutcome outcome = client.create().resource(pat).execute(); // Print the ID of the newly created resource System.out.println(outcome.getId()); } } http://fhirtest.uhn.ca/base/Patient/4529/_history/1 https://github.com/jamesagnew/hapi-fhir/tree/master/hapi-fhir-tutorial/skeleton-project © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 26. FHIR Clients: Basic CRUD - Read/Update public class Example06_ClientReadAndUpdate { public static void main(String[] theArgs) { // Create a client String serverBaseUrl = "http://fhirtest.uhn.ca/base"; FhirContext ctx = new FhirContext(); IGenericClient client = ctx.newRestfulGenericClient(serverBaseUrl); // Use the client to read back the new instance using the // ID we retrieved from the read Patient patient = client.read(Patient.class, "4529"); // Print the ID of the newly created resource System.out.println(patient.getId()); http://fhirtest.uhn.ca/base/Patient/4529/_history/1 // Change the gender and send an update to the server patient.setGender(AdministrativeGenderCodesEnum.F); MethodOutcome outcome = client.update().resource(patient).execute(); System.out.println(outcome.getId()); } } 26 http://fhirtest.uhn.ca/base/Patient/4529/_history/2 https://github.com/jamesagnew/hapi-fhir/tree/master/hapi-fhir-tutorial/skeleton-project © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 27. FHIR Clients: Searching  FHIR defines a powerful search mechanism  Searches are specially crafted URLs to express queries such as:  Find a Patient with the given Identifier  Find all Patients with given gender and DOB  Find all lab reports for a given patient identifier with an “abnormal” interpretation 27 © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 28. FHIR Clients: Searching (2)  Searching is powerful, for lots more information please attend FHIR Search for Client Developers in Q4  For now, let’s imagine a search for a Patient named “Test” whose birthdate is before 2014 28 © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 29. FHIR Clients: Searching (3) public class Example06_ClientReadAndUpdate { public static void main(String[] theArgs) { // Create a client FhirContext ctx = new FhirContext(); String serverBaseUrl = "http://fhirtest.uhn.ca/base"; IGenericClient client = ctx.newRestfulGenericClient(serverBaseUrl); // Build a search and execute it Bundle response = client.search() .forResource(Patient.class) .where(Patient.NAME.matches().value("Test")) .and(Patient.BIRTHDATE.before().day("2014-01-01")) .limitTo(100) .execute(); // How many resources did we find? System.out.println("Responses: " + response.size()); 7 // Print the ID of the first one IdDt firstResponseId = response.getEntries().get(0).getResource().getId(); System.out.println(firstResponseId); } } 29 http://fhirtest.uhn.ca/base/Patient/pt59/_history/1 © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 30. FHIR Clients: Searching (4) public class Example06_ClientReadAndUpdate { public static void main(String[] theArgs) { // Create a client FhirContext ctx = new FhirContext(); String serverBaseUrl = "http://fhirtest.uhn.ca/base"; IGenericClient client = ctx.newRestfulGenericClient(serverBaseUrl); // Build a search and execute it Bundle response = client.search() .forResource(Patient.class) .where(Patient.NAME.matches().value("Test")) .and(Patient.BIRTHDATE.before().day("2014-01-01")) .limitTo(100) .execute(); } } 30 Many more options available for searching: http://jamesagnew.github.io/hapi-fhir/ doc_rest_client.html#Type_-_SearchQuery © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 31. FHIR Clients: Lots More  You can follow a similar pattern to do many more operations:  Delete, Validate, History, Tags, etc…  Client logging interceptor can be very helpful  http://jamesagnew.github.io/hapi-fhir/ doc_rest_client_interceptor.html#Logging:_Log_Request s_and_Responses 31 © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 32. HAPI: The Key Components  Structure Classes (represent FHIR model)  Parsers (convert model into XML/JSON)  Client (use HTTP to access FHIR servers)  Server (build a FHIR server)  Utilities:  Validator  Narrative Generator 32 © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 33. FHIR Server: Architecture  HAPI provides a REST Server framework  Based on standard JEE/Servlet 2.5+ (Tomcat, Glassfish, Websphere, JBoss, etc) 33 © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 34. FHIR Server: Architecture (2)  Architecture is based on “Resource Providers” which are custom classes you write to interact with your resources  This is a “low level” API for building servers, not an “off the shelf” solution 34 © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 35. FHIR Server: Defining Resource Providers  Resource Providers are classes you create with specially annotated methods (one class per resource type) 35 public class Example01_ResourceProviders implements IResourceProvider { @Read public Patient read(@IdParam IdDt theId) { return null; // populate this } @Create void create(@ResourceParam Patient thePatient) { // save the resource } @Search List<Patient> search( @OptionalParam(name="family") StringParam theFamily, @OptionalParam(name="given") StringParam theGiven ) { return null; // populate this } } © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 36. FHIR Server: A Simple Example  The following slides show a simple example building a FHIR server using HAPI  Resources are stored in a HashMap (could just as easily be a database or something else!)  These samples can be downloaded and executed on your laptop very easily 36 © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 37. FHIR Server: A simple resource provider 37 public class Example02_PatientResourceProvider implements IResourceProvider { private Map<Long, Patient> myPatients = new HashMap<Long, Patient>(); /** Constructor */ public Example02_PatientResourceProvider() { Patient pat1 = new Patient(); pat1.addIdentifier().setSystem("http://acme.com/MRNs").setValue("7000135"); pat1.addName().addFamily("Simpson").addGiven("Homer").addGiven("J"); myPatients.put(1L, pat1); } /** Simple implementation of the "read" method */ @Read() public Patient read(@IdParam IdDt theId) { Patient retVal = myPatients.get(theId.getIdPartAsLong()); if (retVal == null) { throw new ResourceNotFoundException(theId); } return retVal; } } https://github.com/jamesagnew/hapi-fhir/tree/master/hapi-fhir-tutorial/simple-server © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 38. FHIR Server: A simple server 38  The servlet is very simple: it creates an instance of each resource provider and declares the servlet path @WebServlet("/example02/*") public class Example02_SimpleRestfulServer extends RestfulServer { private static final long serialVersionUID = 1L; @Override protected void initialize() throws ServletException { setResourceProviders(new Example02_PatientResourceProvider()); } } https://github.com/jamesagnew/hapi-fhir/tree/master/hapi-fhir-tutorial/simple-server © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 39. FHIR Server: Trying the server out  Console 1: Start Server 39 james$ mvn jetty:run [INFO] Scanning for projects... 2014-11-21 12:27:37.622:WARN:oejsh.RequestLogHandler:main: !RequestLog 2014-11-21 12:27:37.669:INFO:oejs.ServerConnector:main: Started ServerConnect [INFO] Started Jetty Server  Console 2: Try it out! james$ curl “http://localhost:8080/example02/Patient/1" <Patient xmlns="http://hl7.org/fhir"><identifier><system value="http://acme.com/MRNs"/><value value="7000135"/></identifier><name><family value="Simpson"/><given value="Homer"/><given value="J"/></name></Patient> © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 40. FHIR Server: Trying the server out (2)  Console 1: Start Server 40 © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 41. FHIR Server: Adding Create and Search 41 public class Example03_PatientResourceProvider implements IResourceProvider { // [ … some methods not shown … ] @Create public MethodOutcome create(@ResourceParam Patient thePatient) { // Give the resource the next sequential ID long id = myNextId++; thePatient.setId(new IdDt(id)); // Store the resource in memory myPatients.put(id, thePatient); // Inform the server of the ID for the newly stored resource return new MethodOutcome(thePatient.getId()); } @Search public List<Patient> search() { List<Patient> retVal = new ArrayList<Patient>(); retVal.addAll(myPatients.values()); return retVal; } } https://github.com/jamesagnew/hapi-fhir/tree/master/hapi-fhir-tutorial/simple-server © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 42. FHIR Server: Testing out Create  The following command executes a ‘create’ 42 curl -H "Content-Type: application/xml+fhir" -X POST -d '<Patient xmlns="http://hl7.org/fhir"><name><family value="Fireman"/><given value=""http://localhost:8080/example03/Patient"  Now perform a search $ curl “http://localhost:8080/example03/Patient?_pretty=true” <feed xmlns="http://www.w3.org/2005/Atom"> <os:totalResults>2</os:totalResults> <entry> <title>Patient 1</title> [ … snip … ] © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 43. http://acme.com/Patient?family=SMITH @Search public List<Patient> search(@RequiredParam(name="family") StringParam theParam) { } 43 FHIR Server: Adding Search Params List<Patient> retVal = new ArrayList<Patient>(); // Loop through the patients looking for matches for (Patient next : myPatients.values()) { String familyName = next.getNameFirstRep().getFamilyAsSingleString().toLowerCase(); if (familyName.contains(theParam.getValue().toLowerCase()) == false) { continue; } retVal.add(next); return retVal; https://github.com/jamesagnew/hapi-fhir/tree/master/hapi-fhir-tutorial/simple-server } © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 44. FHIR Server: Much more is available  Combining multiple parameters  Parameters for sorting, limiting, paging, etc. 44 © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 45. 45 FHIR Server: Learn More  Implementing a server which supports the full FHIR functionality is tricky! For some good insight, please attend “FHIR Search for Server Developers” in Q4 https://github.com/jamesagnew/hapi-fhir/tree/master/hapi-fhir-tutorial/simple-server © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 46. HAPI: The Key Components  Structure Classes (represent FHIR model)  Parsers (convert model into XML/JSON)  Client (use HTTP to access FHIR servers)  Server (build a FHIR server)  Utilities:  Validator  Narrative Generator 46 © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 47. FHIR Validation  FHIR distributes a set of Schema (XSD) and Schematron (SCH) files containing FHIR validation rules  These are included with HAPI and may be applied using the validation framework  Rules include:  Coded element must have valid code  Date “from” must be before date “to” 47 © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 48. FHIR Validation: A simple example 48 public class Example08_ValidateResource { public static void main(String[] args) { // Create an encounter with an invalid status and no class Encounter enc = new Encounter(); enc.getStatus().setValueAsString("invalid_status"); // Create a new validator FhirContext ctx = new FhirContext(); FhirValidator validator = ctx.newValidator(); // Did we succeed? ValidationResult result = validator.validateWithResult(enc); System.out.println("Success: " + result.isSuccessful()); // What was the result OperationOutcome outcome = result.getOperationOutcome(); IParser parser = ctx.newXmlParser().setPrettyPrint(true); System.out.println(parser.encodeResourceToString(outcome)); } } https://github.com/jamesagnew/hapi-fhir/tree/master/hapi-fhir-tutorial/skeleton-project © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 49. FHIR Validation: A simple example 49 <OperationOutcome xmlns="http://hl7.org/fhir"> <issue> public class Example08_ValidateResource { public static void main(String[] args) { <severity value="error"/> <details value="cvc-enumeration-valid: Value 'invalid_status' is // Create an encounter with an invalid status and no class Encounter enc = new Encounter(); enc.getStatus().setValueAsString("invalid_status"); not facet-valid with respect to enumeration '[planned, in progress, onleave, finished, cancelled]'. It must be a value from the enumeration."/> // Create a new validator FhirContext ctx = new FhirContext(); FhirValidator validator = ctx.newValidator(); <location value="Line[1] Col[72]"/> </issue> // <Did issue> we succeed? ValidationResult result = validator.validateWithResult(enc); System.<severity out.println("value="Success: error"/> " + result.isSuccessful()); <details value="cvc-attribute.3: The value 'invalid_status' of attribute 'value' on element 'status' is not valid with respect to its type, 'EncounterState-list'."/> // What was the result OperationOutcome outcome = result.getOperationOutcome(); IParser parser = ctx.newXmlParser().setPrettyPrint(true); System.out.println(parser.encodeResourceToString(outcome)); } } <location value="Line[1] Col[72]"/> </issue> <issue> <severity value="error"/> © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 50. FHIR Validation: Scope 50  Validator currently validates against Schema and Schematron only  Still to come:  ValueSet validation  Profile validation  We would love help on these! :) © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 51. The Narrative Generator  HAPI comes with a module for generating HTML narratives based on resources  Generator uses Thymeleaf templating engine from http://www.thymeleaf.org/ 51 © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 52. Using the Narrative Generator public class Example09_NarrativeGenerator { } 52 public static void main(String[] args) { // Create an encounter with an invalid status and no class Patient pat = new Patient(); pat.addName().addFamily("Simpson").addGiven("Homer").addGiven("Jay"); pat.addAddress().addLine("342 Evergreen Terrace").addLine("Springfield"); pat.addIdentifier().setLabel("MRN: 12345"); // Create a new context and enable the narrative generator FhirContext ctx = new FhirContext(); ctx.setNarrativeGenerator(new DefaultThymeleafNarrativeGenerator()); String res = ctx.newJsonParser().setPrettyPrint(true).encodeResourceToString(pat); System.out.println(res); } https://github.com/jamesagnew/hapi-fhir/tree/master/hapi-fhir-tutorial/skeleton-project © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 53. Using the Narrative Generator public class Example09_NarrativeGenerator { } 53 public static void main(String[] args) { A narrative generator is configured against a single FhirContext and // Create an encounter with an invalid status and no class Patient pat = new Patient(); applies to everything generated by it pat.addName().addFamily("Simpson").addGiven("Homer").addGiven("Jay"); pat.addAddress().addLine("342 Evergreen Terrace").addLine("Springfield"); pat.addIdentifier().setLabel("MRN: 12345"); // Create a new context and enable the narrative generator FhirContext ctx = new FhirContext(); ctx.setNarrativeGenerator(new DefaultThymeleafNarrativeGenerator()); String res = ctx.newJsonParser().setPrettyPrint(true).encodeResourceToString(pat); System.out.println(res); } https://github.com/jamesagnew/hapi-fhir/tree/master/hapi-fhir-tutorial/skeleton-project © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 54. Using the Narrative Generator [ … snip … ] <div><div class="hapiHeaderText"> Homer Jay <b>SIMPSON </b></div><table class="hapiPropertyTable"><tbody><tr><td>Identifier</td><td>MRN: 12345</td></tr><tr><td>Address</td><td><span>342 Evergreen Terrace </span><br/><span>Springfield </span><br/></td></tr></tbody></table></div> [ … snip … ] public class Example09_NarrativeGenerator { } 54 public static void main(String[] args) { // Create an encounter with an invalid status and no class Patient pat = new Patient(); pat.addName().addFamily("Simpson").addGiven("Homer").addGiven("Jay"); pat.addAddress().addLine("342 Evergreen Terrace").addLine("Springfield"); pat.addIdentifier().setLabel("MRN: 12345"); // Create a new context and enable the narrative generator FhirContext ctx = new FhirContext(); ctx.setNarrativeGenerator(new DefaultThymeleafNarrativeGenerator()); String res = ctx.newJsonParser().setPrettyPrint(true).encodeResourceToString(pat); System.out.println(res); } https://github.com/jamesagnew/hapi-fhir/tree/master/hapi-fhir-tutorial/skeleton-project © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 55. Sample Generated Narrative  Generated narratives can be seen on our test server: http://fhirtest.uhn.ca/read?serverId=home&re source=DiagnosticReport&action=read&id=8 4&vid=1 55 © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 56. Extensions: The Easy Way  Every element has a collection of “undeclared” extensions 56 public class Example10_Extensions { public static void main(String[] args) { Patient pat = new Patient(); pat.addName().addFamily("Simpson").addGiven("Homer"); String url = "http://acme.org#eyeColour"; boolean isModifier = false; pat.addUndeclaredExtension(isModifier, url).setValue(new CodeDt(“blue")); IParser p = new FhirContext().newXmlParser().setPrettyPrint(true); String encoded = p.encodeResourceToString(pat); System.out.println(encoded); } © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office. }
  • 57. Extensions: The Easy Way  Every element has a collection of “undeclared” extensions 57 public class Example10_Extensions { public static void main(String[] args) { Patient pat = new Patient(); pat.addName().addFamily("Simpson").addGiven("Homer"); String url = "http://acme.org#eyeColour"; boolean isModifier = false; pat.addUndeclaredExtension(isModifier, url).setValue(new CodeDt(“blue")); IParser p = new FhirContext().newXmlParser().setPrettyPrint(true); String encoded = p.encodeResourceToString(pat); System.out.println(encoded); } © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office. } <Patient xmlns="http://hl7.org/fhir"> <extension url="http://acme.org#eyeColour"> <valueCode value="blue"/> </extension> <name> <family value="Simpson"/> <given value="Homer"/> </name> </Patient>
  • 58. Extensions: The “Hard” Way  HAPI also provides a set of annotations for creating statically typed extensions 58 @ResourceDef(name="Patient") public class Example11_ExtendedPatient extends Patient { @Child(name = "eyeColour") @Extension(url="http://acme.org/#extpt", definedLocally = false, isModifier = false) private CodeDt myEyeColour; public CodeDt getEyeColour() { if (myEyeColour == null) { myEyeColour = new CodeDt(); } return myEyeColour; } public void setEyeColour(CodeDt theEyeColour) { myEyeColour = theEyeColour; } } © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 59. Get Help!  See our website for documentation: http://jamesagnew.github.io/hapi-fhir/  We also have a Google Group / Mailing List https://groups.google.com/d/forum/hapi-fhir 59 © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 60. Get Involved!  HAPI is a large worldwide community of developers  Today most are working on HL7 v2, but this is changing fast  We are very grateful to the many people who have contributed so far, maybe you could be next? 60 © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 61. HAPI: Other Topics  Web Testing UI: The testing interface shown on our test server may be added to your own server  JPA: HAPI has a JPA module which stores and indexes resources in a relational database using Hibernate 61 © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.
  • 62. Thank You!  jamesagnew@gmail.com  jamesagnew214 on Skype 62 © 2014 HL7 ® International. Licensed under Creative Commons. HL7 & Health Level Seven are registered trademarks of Health Level Seven International. Reg. U.S. TM Office.