O slideshow foi denunciado.
Utilizamos seu perfil e dados de atividades no LinkedIn para personalizar e exibir anúncios mais relevantes. Altere suas preferências de anúncios quando desejar.
HAPI-FHIR for 
Java Developers 
James Agnew 
FHIR Developer Days 
November 24, 2014 
© 2014 HL7 ® International. Licensed ...
Who am I? 
 Name: James Agnew 
 Company: University 
Health Network 
 Background: 
 Software development 
manager for ...
About this Presentation 
 All code samples are available on GitHub in 
fully working form 
 HAPI is too big a topic for ...
FHIR: A Quick Recap 
 There are two key parts of FHIR to consider: 
 The first is a data model for healthcare Resources ...
 The second is a RESTful API for interacting 
with that model 
© 2014 HL7 ® International. Licensed under Creative Common...
The HAPI Project 
 HAPI started in 2001 as an HL7 v2 Library 
 Built to support a simple web portal, now used 
in applic...
HAPI FHIR: What? 
 Not a client or a server, but a toolkit for 
building either 
7 
© 2014 HL7 ® International. Licensed ...
HAPI FHIR: Why? 
 HAPI FHIR was started to simplify access to our internal 
data sources 
© 2014 HL7 ® International. Lic...
Design Goals 
 Use Anywhere 
 Apache 2.0 License for all components 
 Minimal dependencies 
 Be Flexible 
 Loosely co...
HAPI: The Key 
Components 
 Structure Classes (represent FHIR model) 
 Parsers (convert model into XML/JSON) 
 Client (...
Structures Classes: 
The FHIR Model 
 HAPI Defines several sets 
of classes which form the 
data model 
 Resource defini...
Structures Classes: 
The FHIR Model (2) 
 HAPI also defines a class 
for each data type 
 Datatype classes are 
named [n...
Structures Classes: 
The FHIR Model (3) 
 JavaDocs for structures are available here: 
http://jamesagnew.github.io/hapi-f...
Taking the Structures for 
a spin 
 Patient Resource (http://hl7.org/implement/standards/fhir/patient.html) 
14 
 HumanN...
Taking the Structures for 
a spin (2) 
15 
public class Example01_CreateAPatient { 
public static void main(String[] theAr...
Taking the Structures for 
a spin (3) 
16 
public class Example01_CreateAPatient { 
public static void main(String[] theAr...
Taking the Structures for 
a spin (4) 
17 
public class Example02_CreateAPatient { 
public static void main(String[] theAr...
HAPI: The Key 
Components 
 Structure Classes (represent FHIR model) 
 Parsers (convert model into XML/JSON) 
 Client (...
Playing with Parsers 
19 
 The starting point for much of the HAPI-FHIR 
API is the FhirContext class 
 FhirContext acts...
Playing with Parsers: 
Encoding Resources 
20 
public class Example03_EncodeResource { 
public static void main(String[] t...
Playing with Parsers: 
Encoding Resources (2) 
21 
// Create a context 
FhirContext ctx = new FhirContext(); 
// Create a ...
Playing with Parsers: 
Parsing Resources 
22 
public class Example04_ParseResource { 
public static void main(String[] the...
HAPI: The Key 
Components 
 Structure Classes (represent FHIR model) 
 Parsers (convert model into XML/JSON) 
 Client (...
FHIR Clients: 
Recap on REST 
 FHIR defines basic CRUD operations that 
can be performed on a FHIR compliant 
server (*no...
FHIR Clients: 
Basic CRUD - Create 
25 
public class Example05_ClientCreate { 
public static void main(String[] theArgs) {...
FHIR Clients: 
Basic CRUD - Read/Update 
public class Example06_ClientReadAndUpdate { 
public static void main(String[] th...
FHIR Clients: 
Searching 
 FHIR defines a powerful search mechanism 
 Searches are specially crafted URLs to 
express qu...
FHIR Clients: 
Searching (2) 
 Searching is powerful, for lots more 
information please attend FHIR Search for 
Client De...
FHIR Clients: 
Searching (3) 
public class Example06_ClientReadAndUpdate { 
public static void main(String[] theArgs) { 
/...
FHIR Clients: 
Searching (4) 
public class Example06_ClientReadAndUpdate { 
public static void main(String[] theArgs) { 
/...
FHIR Clients: 
Lots More 
 You can follow a similar pattern to do many 
more operations: 
 Delete, Validate, History, Ta...
HAPI: The Key 
Components 
 Structure Classes (represent FHIR model) 
 Parsers (convert model into XML/JSON) 
 Client (...
FHIR Server: 
Architecture 
 HAPI provides a REST Server framework 
 Based on standard JEE/Servlet 2.5+ 
(Tomcat, Glassf...
FHIR Server: 
Architecture (2) 
 Architecture is 
based on 
“Resource 
Providers” which 
are custom classes 
you write to...
FHIR Server: 
Defining Resource Providers 
 Resource Providers are classes you create with specially 
annotated methods (...
FHIR Server: 
A Simple Example 
 The following slides show a simple example 
building a FHIR server using HAPI 
 Resourc...
FHIR Server: 
A simple resource provider 
37 
public class Example02_PatientResourceProvider implements IResourceProvider ...
FHIR Server: 
A simple server 
38 
 The servlet is very simple: it creates an instance of each 
resource provider and dec...
FHIR Server: 
Trying the server out 
 Console 1: Start Server 
39 
james$ mvn jetty:run 
[INFO] Scanning for projects... ...
FHIR Server: 
Trying the server out (2) 
 Console 1: Start Server 
40 
© 2014 HL7 ® International. Licensed under Creativ...
FHIR Server: 
Adding Create and Search 
41 
public class Example03_PatientResourceProvider implements IResourceProvider { ...
FHIR Server: 
Testing out Create 
 The following command executes a ‘create’ 
42 
curl -H "Content-Type: application/xml+...
http://acme.com/Patient?family=SMITH 
@Search 
public List<Patient> search(@RequiredParam(name="family") StringParam thePa...
FHIR Server: 
Much more is available 
 Combining multiple parameters 
 Parameters for sorting, limiting, paging, etc. 
4...
45 
FHIR Server: 
Learn More 
 Implementing a server which supports the full 
FHIR functionality is tricky! For some good...
HAPI: The Key 
Components 
 Structure Classes (represent FHIR model) 
 Parsers (convert model into XML/JSON) 
 Client (...
FHIR Validation 
 FHIR distributes a set of Schema (XSD) and 
Schematron (SCH) files containing FHIR 
validation rules 
...
FHIR Validation: 
A simple example 
48 
public class Example08_ValidateResource { 
public static void main(String[] args) ...
FHIR Validation: 
A simple example 
49 
<OperationOutcome xmlns="http://hl7.org/fhir"> 
<issue> 
public class Example08_Va...
FHIR Validation: 
Scope 
50 
 Validator currently validates against Schema 
and Schematron only 
 Still to come: 
 Valu...
The Narrative Generator 
 HAPI comes with a module for generating 
HTML narratives based on resources 
 Generator uses T...
Using the Narrative 
Generator 
public class Example09_NarrativeGenerator { 
} 
52 
public static void main(String[] args)...
Using the Narrative 
Generator 
public class Example09_NarrativeGenerator { 
} 
53 
public static void main(String[] args)...
Using the Narrative 
Generator 
[ … snip … ] 
<div><div class="hapiHeaderText"> Homer Jay <b>SIMPSON 
</b></div><table 
cl...
Sample Generated 
Narrative 
 Generated narratives can be seen on our test 
server: 
http://fhirtest.uhn.ca/read?serverId...
Extensions: The Easy 
Way 
 Every element has a collection of 
“undeclared” extensions 
56 
public class Example10_Extens...
Extensions: The Easy 
Way 
 Every element has a collection of 
“undeclared” extensions 
57 
public class Example10_Extens...
Extensions: The “Hard” 
Way 
 HAPI also provides a set of annotations for 
creating statically typed extensions 
58 
@Res...
Get Help! 
 See our website for documentation: 
http://jamesagnew.github.io/hapi-fhir/ 
 We also have a Google Group / M...
Get Involved! 
 HAPI is a large worldwide community of 
developers 
 Today most are working on HL7 v2, but this 
is chan...
HAPI: Other Topics 
 Web Testing UI: The testing interface shown 
on our test server may be added to your own 
server 
 ...
Thank You! 
 jamesagnew@gmail.com 
 jamesagnew214 on Skype 
62 
© 2014 HL7 ® International. Licensed under Creative Comm...
Próximos SlideShares
Carregando em…5
×

15

Compartilhar

Baixar para ler offline

FHIR API for Java programmers by James Agnew

Baixar para ler offline

FHIR API for Java programmers (James Agnew)

FHIR API for Java programmers by James Agnew

  1. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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.
  • MuhammadAbuJubbah

    Aug. 22, 2020
  • AneeshChackoV

    Jul. 11, 2020
  • SHIHCHIEHCHEN3

    Mar. 16, 2020
  • JuanCarlosSeguraSnch

    Oct. 31, 2018
  • samujjal

    Jun. 20, 2018
  • anjanmustafi

    Nov. 13, 2017
  • nininnt

    May. 8, 2017
  • KirbyKnight1

    Jan. 4, 2017
  • AnsumanRoy1

    Nov. 2, 2016
  • emreavs

    Oct. 11, 2016
  • FrankParth

    Apr. 29, 2016
  • BandeshKharnar

    Feb. 3, 2016
  • chavardz1

    Dec. 21, 2015
  • mruau

    Aug. 4, 2015
  • alexsleep

    Jun. 15, 2015

FHIR API for Java programmers (James Agnew)

Vistos

Vistos totais

15.764

No Slideshare

0

De incorporações

0

Número de incorporações

396

Ações

Baixados

643

Compartilhados

0

Comentários

0

Curtir

15

×