A REST primer – FHIR style – part 1.
October 15, 2013 11 Comments
In this post I’m going to talk a little about REST – REpresentational State Transfer – in the context of FHIR. The FHIR specification goes into some detail about how REST and FHIR work together, so go there for more details.
As mentioned in a previous post, FHIR works across many different interoperability paradigms, but REST is the best established at this point in time – and by far the easiest to use (as you will see). It’s the one used by companies such as google, amazon and twitter to provide access to their services (as well as 37 signals – which was the original inspiration for FHIR).
Despite the complicated sounding name, it’s actually quite simple – in fact, it’s the way the web works. The term REST was first used by a chap called Roy Feilding – one of those uber-smart guys that defined many of the basic web protocols that we take for granted today. In a PhD dissertation, he took some of the basic web concepts, and described an ‘architectural style’ that took advantage of those concepts in an easy to use way. (sounds like the goals of FHIR – right)?
The basics are really quite simple.
- REST is built on top of the HTTP protocol – the same protocol you use when requesting a web page in your browser. HTTP (short for HyperText Transfer Protocol) is simply a set of rules that both server and client (in this case a browser) use to exchange data over the web. HTTP is a ‘request/response’ protocol – you make a request (which can contain data), the server responds and that’s it.
- REST thinks in terms of resources, each of which has an identity by which it can be manipulated. This is the URI (Uniform Resource Identifier), and uniquely specifies the location of a resource. It is specific to a particular server.
- When manipulating resources, there are a fixed number of methods that you can use. The ones that are of particular interest to FHIR include:
- GET – retrieve a particular resource based on its URI (server location + id). FHIR uses the GET method both to retrieve a single resource, and to perform a search which could potentially return multiple resources.
- POST – create a new resource at a specified endpoint. In REST the server will assign an id, and the combination of server location and id becomes the URI for that resource.
- PUT – update an existing resource. The client that is executing the PUT needs to know the URI of the resource (which, in FHIR, means that they know the id of the resource as well as the server where it is stored). In FHIR, this will create a new version of the resource.
- DELETE – remove a resource. Again the URI must be known. It is recommended (though not mandated) in FHIR that a copy of the resource is maintained, and potentially reachable using a version aware read, and the history by a history request, but a plain GET should not return the resource any more. (It will, however, return a status code telling the user that a resource was deleted – read on!)
- OPTIONS – this is a ‘special’ method in FHIR, that is directed to the root of the server, and returns a conformance resource that informs the client what the capabilities of the server are. I’ll write about this some other time – it’s actually quite useful, though not necessary to know for normal operation.
- When a server responds to an HTTP REST request, it processes the request according to the method and its internal business logic, and then returns a response to the client. The response has a number of parts to it:
- The body of the response is what the client is requesting from the server – generally in response to a GET request. Most of the other methods do not return a response. (Note: in the current version of the spec they actually do – but that will be removed soon).
- The server always returns a status code – which informs the client what the outcome of the request was – did it succeed, or did it fail – with some further details about the nature of the outcome. The status code is a number, which has a well defined meaning within the HTTP protocol. FHIR defines an operationOutcome resource, which the server can use to give the client detailed information about any failure.
- Both the request and the response can contain headers. These provide extra information about the request or response to assist the server or client to properly process the transaction. Examples include:
- Both request and response use the Content-type header to tell the other party whether a resource is in xml or json format.
- A client will use the Accept header to tell the server what format (xml/json) it would prefer to get back when making a GET (though the server is not obligated to honor this)
- The server will use the Location header to tell the client the URI of a newly created resource
- And so on.
Well, that’s enough background – lets actually do something in FHIR. Let’s get a patient resource from one of the on line FHIR test servers.
Paste the following command (which is actually a URI) into your browser:
What this does is to instruct your browser to make a GET request to the specified URI, and display the results in your browser. You should see an XML version of the Patient resource that has the id of 4165431. Simple – eh?
http://fhirtest.uhn.ca/baseDstu3/Patient/4165431
Dissecting the instruction a bit:
- HTTP:// – specified the HTTP protocol
- fhirtest.uhn.ca/baseDstu3/ – the endpoint on the Public HAPI server that responds to FHIR requests
- Patient/ – specified that the operation was to be on the Patient resource
- 4665431 – specified the patient with the id of 4665431.
A couple of notes:
- I needed to know what the Id was. It was fairly safe in this case because the public HAPI server is a test server with some fixed resources, and unless someone else deletes that resource it should be available (try another number if that happens). You could use this technique to retrieve any type of resource from any FHIR server – provided that you knew the Id – and passed any security mechanisms.
- The only thing you can do through the browser (at least this way) is to issue GET requests.
- For better results (and to use the other verbs) use a REST client like POSTMan
- I haven’t talked at all about security.
In the next post I’m going to delve into REST a bit further – how to search for resources if you don’t know the id, how to change existing ones or create new one. And, if there is time, how to do queries across resources – e.g. all the conditions associated with a specific patient.
BTW – if the link above doesn’t work, then try http://fhirtest.uhn.ca/baseDstu3/Patient. What you’ll get is a collection of Patients rather than a single one.
Do you have PUT and POST around the wrong way? PUT to create and then POST to update?
Nope. Check out this link from the spec (http://www.hl7.org/implement/standards/fhir/http.htm#update) – but it is a very common thing to mix up!
cheers…
Then is it not possible to create a resource with an id chosen by the client (because the server always assigns the id)?
It is certainly possible for the client to assign the ID – in FHIR, if a client PUT’s a resource to a URI (i.e. includes the ID) and there is no resource already there, then the server will create the resource using that ID (it returns a 201 status to indicate that this has happened). The issue with this of course is in potential ID collisions – what prevents 2 clients using the same ID for different resources?
However, FHIR takes the view that this is a deployment decision, and up to the implementers and trading partners using the server. They could insist on GUID’s as the IDs for example. I’m just finishing a post that goes into resource manipulation a bit more deeply – I’ll make sure to cover this off in a little more detail. Thanks for the question!
Pingback: Manipulating a single FHIR Patient Resource | Hay on FHIR
Pingback: FHIR: A question of identity | Hay on FHIR
David:
This is a nice intro in FHIR and REST! However, I tried connecting to the link you gave at http://hl7connect.healthintersections.com.au/svc/fhir/Patient/@100 to get a patient resource, but nothing came back. Is the link defunct?
Hi Mark, glad you found it helpful!
I do need to update that post (and likely others) as the FHIR URLs have changed – as has the address of Grahames server! The correct URL is http://fhir.healthintersections.com.au/open/Patient/100 (The spec at http://wiki.hl7.org/index.php?title=Publicly_Available_FHIR_Servers_for_testing has the complete list of servers.
The fun of getting involved in these things early on in the process!
David, nice intro but again the URL is out of date 😉
Unfortunately quite common with the speed that FHIR is developing!
Hi David the posted link no longer works and may need updating