Getting started with the Kidney REST API
This page describes the basics of using the kidney exchange REST API
Table of Contents
Quick Start
In addition to the SOAP API the Kidney Exchange Allocator also exposes a
REST-like API - there is no strict sense of resources, it's just essentially an API over HTTP. The API makes
available two methods, find.json
and
find.xml
, both of which find an allocation of donors to patients with the
output data being formatted in JSON and XML respectively.
There are many libraries available in most programming languages to consume such a service; they vary from full blown REST resource kits to simple HTTP client libraries. Here we use the Apache Java HttpClient library to show how the service can be used and the output data processed.
First you will need to download the appropriate jar files
from the Apache website. On this page select 'binaries with dependencies' to get a superset of the jar files
required to run this example - of these files you only really need the httpclient, httpcore and the common-logging
jar files. The sample code below simply builds a URL to the service and sends this data using an HTTP POST
request. It's worth noting that this must be a POST request and an error will be returned should you try to access
this API with any other HTTP request type (e.g. GET or PUT). In the example below we are calling the
find.json
method and as such the output data (also shown below) is returned
in JSON format - more detailed information is available about the format on the
Output Formats page.
import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.utils.URLEncodedUtils; import org.apache.http.client.utils.URIUtils; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import java.io.IOException; import java.net.URISyntaxException; import java.io.InputStream; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.URI; import java.util.ArrayList; import java.util.List; public class Client { public static void main(String[] args) throws IOException, URISyntaxException { String data = "{ \"data\" :" + "{ \"1\" : { \"sources\" : [1]," + "\"dage\" : 65," + "\"matches\" : [ { \"recipient\" : 2, \"score\" : 3}," + "{ \"recipient\" : 3, \"score\" : 1}," + "{ \"recipient\" : 4, \"score\" : 2} ]}," + "\"2\" : { \"sources\" : [2]," + "\"dage\" : 45," + "\"matches\" : [ { \"recipient\" : 1, \"score\" : 2}," + "{ \"recipient\" : 5, \"score\" : 1} ]}," + "\"3\" : { \"sources\" : [3]," + "\"dage\" : 25," + "\"matches\" : [ { \"recipient\" : 1, \"score\" : 1} ]}," + "\"4\" : { \"sources\" : [4]," + "\"dage\" : 55," + "\"matches\" : [ { \"recipient\" : 2, \"score\" : 3}," + "{ \"recipient\" : 3, \"score\" : 2}," + "{ \"recipient\" : 5, \"score\" : 4} ]}," + "\"5\" : { \"sources\" : [5]," + "\"dage\" : 30," + "\"matches\" : [ { \"recipient\" : 2, \"score\" : 1}," + "{ \"recipient\" : 4, \"score\" : 2} ]} } }"; List<NameValuePair> qparams = new ArrayList<NameValuePair>(); qparams.add(new BasicNameValuePair("data", data)); qparams.add(new BasicNameValuePair("operation", "optimal")); qparams.add(new BasicNameValuePair("altruistic_chain_length", "1")); URI uri = URIUtils.createURI("https", "kidney.optimalmatching.com", -1, "/kidney/find.json", URLEncodedUtils.format(qparams, "UTF-8"), null); HttpPost httpost = new HttpPost(uri); DefaultHttpClient httpclient = new DefaultHttpClient(); HttpResponse response = httpclient.execute(httpost); HttpEntity entity = response.getEntity(); if (entity != null) { InputStream instream = entity.getContent(); BufferedReader reader = new BufferedReader(new InputStreamReader(instream)); String str; while ((str = reader.readLine()) != null) { System.out.println(str); } } httpclient.getConnectionManager().shutdown(); } }
{ "algorithm" : "Optimal set of exchanges with respect to the optimality criteria", "output" : { "all_cycles": { "0": {"cycle": [{"p": 1,"d": 1,"tb": 0.025,"dif": 3,"s": 3}, {"p": 2,"d": 2,"tb": 0.025,"dif": 3,"s": 2}], "backarcs": 0, "weight": 11.05, "alt": []}, "1": {"cycle": [{"p": 1,"d": 1,"tb": 0.009,"dif": 0,"s": 1}, {"p": 3,"d": 3,"tb": 0.009,"dif": 0,"s": 1}], "backarcs": 0, "weight": 2.018, "alt": []}, "2": {"cycle": [{"p": 2,"d": 2,"tb": 0.03025,"dif": 3,"s": 1}, {"p": 5,"d": 5,"tb": 0.03025,"dif": 3,"s": 1}], "backarcs": 0, "weight": 8.0605, "alt": []}, "3": {"cycle": [{"p": 4,"d": 4,"tb": 0.02025,"dif": 0,"s": 4}, {"p": 5,"d": 5,"tb": 0.02025,"dif": 0,"s": 2}], "backarcs": 0, "weight": 6.0405, "alt": []}, "4": {"cycle": [{"p": 1,"d": 1,"tb": 0.036,"dif": 3,"s": 2}, {"p": 4,"d": 4,"tb": 0.036,"dif": 3,"s": 3}, {"p": 2,"d": 2,"b": 0,"tb": 0.025,"dif": 3,"s": 2}], "backarcs": 1, "weight": 16.097, "alt": []}, "5": {"cycle": [{"p": 1,"d": 1,"tb": 0.036,"dif": 3,"s": 2}, {"p": 4,"d": 4,"tb": 0.016,"dif": 0,"s": 2}, {"p": 3,"d": 3,"b": 1,"tb": 0.009,"dif": 0,"s": 1}], "backarcs": 1, "weight": 8.061, "alt": []}, "6": {"cycle": [{"p": 2,"d": 2,"b": 2,"tb": 0.03025,"dif": 3,"s": 1}, {"p": 5,"d": 5,"b": 3,"tb": 0.02025,"dif": 0,"s": 2}, {"p": 4,"d": 4,"tb": 0.036,"dif": 3,"s": 3}], "backarcs": 2, "weight": 12.0865, "alt": []}}, "exchange_data": [ { "description": "(COIN) Optimal set of exchanges", "exchanges": [1,6], "weight": 14.1045, "two_way_exchanges": 1, "total_transplants": 5, "three_way_exchanges": 1 } ] } }
REST Requests
REST is the simplest request format to use - it's a simple HTTP POST action.
The REST Endpoint URL is http://kidney.optimalmatching.com/kidney
REST Response
REST is the simplest response format to use - it's a simple XML or JSON block depending on what format you have requested For XML the format will look something like this:
<?xml version="1.0" encoding="utf-8" ?> <data> <algorithm> [algorithm-name-here] </algorithm> <output> [xml-payload-here] </output> </data>And for JSON it's something like this:
{ "algorithm" : [algorithm-name-here], "output" : [json-payload-here] }If an error occurs, and XML format is being used, the following is returned:
<?xml version="1.0" encoding="utf-8" ?> <data> <algorithm> [algorithm-name-here] <algorithm> <error> [error-message-here] <error> </data>Similarly if an error occurs when using json we get:
{ "algorithm" : [algorithm-name-here], "output" : [error-message-here] }
API Guide
The REST API exposes two methods, namely find.xml
and
find.json
. As you may expect these methods carry out the same operation
and differ only in the format of the data they returned. Each method is discussed in detail below.
find.json(data, operation, altruistic_chain_length)
data
operation
- optimal
- returns a solution that is defined as optimal in the optimality criteria section.
- maxcard
- returns a solution that has maximum cardinality and subject to this maximum weight, i.e. is not constraint by maximising the effective number of pairwise exchanges. More details of this can be found in the maxcard sub-section of the optimality criteria section.
- pairs
- returns an optimal solution involving only pairwise exchanges.
altruistic_chain_length
1.0.0
and above of the kidney_server
(ruby) application and all version of the
kidney_service
application.max_cycle_size
output_format
nhsbtv1
or nhsbtv2
.
Default is nhsbtv1
.
find.xml(data, operation, altruistic_chain_length)
data
operation
- optimal
- returns a solution that is defined as optimal in the optimality criteria section.
- maxcard
- returns a solution that has maximum cardinality and subject to this maximum weight, i.e. is not constraint by maximising the effective number of pairwise exchanges. More details of this can be found in the maxcard sub-section of the optimality criteria section.
- pairs
- returns an optimal solution involving only pairwise exchanges.
altruistic_chain_length
1.0.0
and above of the kidney_server
(ruby) application and all version of the
kidney_service
application.max_cycle_size
output_format
nhsbtv1
or nhsbtv2
.
Default is nhsbtv1
.