PhenoTips » Developer Guide » API » PhenoTips RESTful API

PhenoTips RESTful API

This page is a draft.

Starting with version 1.2, PhenoTips provides a RESTful API for reading and modifying patient data. In summary, the REST services allow to list existing patient records, add a new patient record, retrieve, modify or delete an existing patient record with the given identifier. Data is exchanged in JSON format. The JSON representation of a patient record that is produced or that can be consumed by the PhenoTips RESTful API is specified in the JSON import/export section of the developer guide.

Accessing the service

The PhenoTips RESTful endpoint is rooted at the following URI:

http[s]://host[:port]/[applicationName/]rest/

For example, the list of patients in a PhenoTips instance running locally at port 8080 can be accessed via:

http://localhost:8080/rest/patients

Authentication

The PhenoTips RESTful API supports two types of authentication:

  • HTTP BASIC Auth: You provide your credentials using the Authorization HTTP header
  • PhenoTips session: If you are logged in and you use the cookies provided by the authentication mechanism, you will also be authenticated to the RESTful API. This is useful, for example, when you are interacting with the API using the XMLHttpRequest object of a browser using JavaScript.

If you don't provide any credentials, the RESTful API will return an Unauthorized (401) empty response for any attempt to access resources that require authentication.

Resources

Resource URIs are specified using URI templates. Bracketed elements are formal parameters and should be instantiated to actual values in order to retrieve the associated resource.

Root resources

/patients[?[start={integer}][&number={integer}][&orderFiled={id,eid}][&order={asc,desc}]]

  • HTTP method: GET

    Media types (must request one with the “Accept” HTTP request header):
    application/json
    application/xml
    Result:
    Lists patient records
    Parameters:
    start: for large result set paging, the index of the first patient to display in the returned page; defaults to 0
    number: for large result set paging, how many patients to display in the returned page; defaults to 30
    orderField: field used for ordering the patients, can be one of id (default) or eid
    order the sorting order, can be one of asc (default) or desc
    Status codes:
    200 if the request was successful
    401 if the user was not authenticated
    403 if the user was authenticated but not authorized 

/patients

  • HTTP method: POST

    Accepted media type:
    application/json
    Media type:
    application/json
    Result:
    If successful, creates a new patient record and returns its location, otherwise provides an error report
    Status codes:
    201 if the patient was created
    401 if the user was not authenticated
    403 if the user was authenticated but not authorized 
    500 if creating the patient failed

/vocabularies

  • HTTP method: GET

    Media types (must request one with the “Accept” HTTP request header):
    application/json
    application/xml
    Result:
    List the available vocabularies in this PhenoTips instance
    Status codes:
    200 if request was successful
    500 if an unknown error occured

Patient resources

/patients/fetch?[id={internalIdentifierN}]*[&eid=externalIdentifierN}]*

  • HTTP method: GET

    Accepted media type:
    application/x-www-form-urlencoded (optional)
    Media type:
    application/json
    Result:
    Retrieves one or more patient records, identified either by their internal or external PhenoTips identifiers, as an array of JSON representations. If any of the indicated patient records don't exist, or if the user sending the request doesn't have the right to view any of the target patient records, then they are simply skipped from the result. The target identifiers can be specified either in the query string, or in the request body.
    Status codes:
    200 if request was successful
    500 if generating the response failed

/patients/{id}

  • HTTP method: GET

    Media type:
    application/json
    Result:
    Retrieves a patient record, identified by its internal PhenoTips identifier, in its JSON representation. If the indicated patient record doesn't exist, or if the user sending the request doesn't have the right to view the target patient record, an error is returned.
    Status codes:
    200 if request was successful
    401 if the user was not authenticated
    403 if the user was authenticated but not authorized 
    404 if the resource was not found
  • HTTP Method: PUT

    Accepted Media type:
    application/json
    Media type:
    application/json
    Result:
    Updates a patient record, identified by its internal PhenoTips identifier, from its JSON representation. If the  indicated patient record doesn't exist, or if the user sending the request doesn't have the right to modify it, no change is performed and an error is returned. If a field is set in the patient record, but missing in the provided JSON, then that field is not changed.
    Status codes:
    204 if the patient was updated.
    304 if the patient was not modified.
    401 if the user was not authenticated
    403 if the user was authenticated but not authorized 
    404 if the resource was not found
  • HTTP Method: DELETE

    Media type:
    application/json
    Result:
    Deletes a patient record, identified by its internal PhenoTips identifier. If the indicated patient record doesn't exist, or if the user sending the request doesn't have the right to delete the target patient record, no change is performed and an error is returned.
    Status codes:
    200 if request was successful
    401 if the user was not authenticated
    403 if the user was authenticated but not authorized 
    404 if the resource was not found

/patients/eid/{eid}

  • HTTP method: GET

    Media type:
    application/json
    Result:
    Retrieves a patient record, identified by its given “external” identifier, in its JSON representation. If the indicated patient record doesn't exist, or if the user sending the request doesn't have the right to view the target patient record, an error is returned. If multiple records exist with the same given identifier, a list of links to each such record is returned.
    Status codes:
    200 if request was successful
    300 if multiple patient records with the same given identifier exist
    401 if the user was not authenticated
    403 if the user was authenticated but not authorized 
    404 if the resource was not found
  • HTTP Method: PUT

    Accepted Media type:
    application/json
    Media type:
    application/json
    Result:
    Updates a patient record, identified by its given “external”  identifier, from its JSON representation. If the  indicated patient record doesn't exist, or if the user sending the request doesn't have the right to modify it, no change is performed and an error is returned. If a field is set in the patient record, but missing in the provided JSON, then that field is not changed.
    Status codes:
    202 if the patient was updated.
    300 if multiple patient records with the same given identifier exist
    304 if the patient was not modified.
    401 if the user was not authenticated
    403 if the user was authenticated but not authorized 
    404 if the resource was not found
  • HTTP Method: DELETE

    Media type:
    application/json
    Result:
    Deletes a patient record, identified by its given “external” identifier. If the indicated patient record doesn't exist, or if the user sending the request doesn't have the right to delete the target patient record, no change is performed and an error is returned.
    Status codes:
    200 if request was successful
    401 if the user was not authorized
    404 if the resource was not found

Vocabulary Resources

 will be available in PhenoTips version 1.3 Milestone 1

/vocabularies/{vocabulary}

  • HTTP Method: GET

    Media types (must request one with the “Accept” HTTP request header):
    application/json
    application/xml
    Result: 
    Retrieves a representation of the specified vocabulary. The vocabulary can be specified by any of its known aliases. i.e /vocabularies/hpo and /vocabularies/HP will retrieve the same resource.

    Status codes:
    200 if request was successful
    404 if no vocabulary was found with the specified id
  • HTTP Method: PUT

    Result: 
    Reindex the whole vocabulary, fetching the source from the specified location. Reindexing may take some time to complete. This request must come from an adminstrator.
    Parameters:
    url: The URL to be indexed
    Status codes:
    200 if request was successful
    400 if the request was malformed or the specified url is invalid
    403 if the user does not have administrating rights on PhenoTips
    404 if no vocabulary was found with the specified ID
    500 if the reindexing failed
    503 if the specified vocabulary does not support reindexing
  • HTTP Method: GET

    Result: 
    Provides term suggestions based on an input for the specified Vocabulary. Request can optionally specify additional filters. If no suggestions are found an empty response is returned.
    Parameters:
    input: The string upon which suggestions will be based
    maxResults: The maximum number of results to be returned
    sort: an optional sort parameter, in a format that depends on the actual engine that stores the vocabulary. Usually a property name followed by code asc or desc; Usually empty.
    customFilter:  custom filter query to further restrict which terms may be returned, in a format that depends on the actual engine that stores the vocabulary; some vocabularies may not support a filter query; may be empty
    Status codes:
    200 if request was successful
    400 if vocabulary or input are empty or malformed
    404 if the vocabulary was not found

/vocabularies/terms/{vocabulary}/{id}

  • HTTP Method: GET

    Result: 
    Retrieves a JSON representation of the vocabulary term by searching the specified vocabulary. The vocabulary may be specified by any of its known aliases. The id must be in the form PREFIX:XXXX where the prefix is the vocabulary identifier and the XXXX are replaced by digits.
    Status codes:
    200 if request was successful

/vocabularies/terms/{id}

  • HTTP Method: GET

    Result: 
    Retrieves a JSON representation of the vocabulary term by resolving the vocabulary based on the ID's prefix. The id must be in the form PREFIX:XXXX where the prefix is the vocabulary identifier and the XXXX are replaced by digits.
    Status codes:
    200 if request was successful

Testing resource URIs

Using a REST client to test API endpoints

There are a number of REST clients that can be used to interact with the PhenoTips API. Typically, one can use a command-line tool or a browser addon to test API endpoints.

Command-line tools

While cURL is the most commonly used command-line tool for transferring data with URL syntax, httpie offers highly intuitive syntax designed to be a human-friendly alternative to cURL. The basic examples below are displayed using both httpie and cURL.

Browser extensions

Browser extensions offer the ease of a simple user-interface for interacting with an API. To name a few, this includes selecting HTTP methods from a simple dropdown list, simple editing of request parameters, capability to add test cases, and pretty-print of output responses.

Recommendations

General steps

Basic examples using a REST client

The examples use a root URI running a PhenoTips instance locally on port 8080:

http://localhost:8080/rest/patients
 

Authenticating with a REST client

Via a browser extension:

Authentication parameters are inputted through the UI and are passed with each request. Authentication values can be saved and persisted between sessions as per user settings. 

Via httpie:

Send requests without having to specify login information each time by creating a session to have custom headers, authorization, and cookies persist with each request to your local PhenoTips instance.

http --session=JohnDoe -a JohnDoe:johndoespassword http://localhost:8080

Via curl:

curl -u JohnDoe:johndoespassword http://localhost:8080

Example response:

HTTP/1.1 200 OK
Cache-Control: no-cache
Content-Language: en
Content-Length: 22118
Content-Type: text/html;charset=UTF-8
Expires: Wed, 31 Dec 1969 23:59:59 GMT
Pragma: no-cache
Set-Cookie: JSESSIONID=1f7pvahulv2n7e2kp768r1kty;Path=/

View all patient records

HTTP method: GET
URL: http://localhost:8080/rest/patients

With a REST client browser extension, select the HTTP method and fill in the appropriate URL for the request. In this case, we would select GET and input the URL above. 

Example httpie request:

http --session=JohnDoe GET http://localhost:8080/rest/patients

Example curl request:

curl http://localhost:8080/rest/patients/P0000001

Example response body:
Note: The default response type for a GET method is application/xml, however application/json can be returned if specified as a value for the Accept parameter.

<patients xmlns="https://phenotips.org/">
<link href="http://localhost:8080/rest/patients" rel="self"/>
<patientSummary>
<link href="http://localhost:8080/rest/patients/P0000001" rel="https://phenotips.org/rel/patientRecord"/>
<id>P0000001</id>
<eid/>
<created_by>XWiki.JohnDoe</created_by>
<created_on>2016-08-03T14:10:07.000Z</created_on>
<version>3.7</version>
<last_modified_by>XWiki.JohnDoe</last_modified_by>
<last_modified_on>2016-08-16T14:55:48.000Z</last_modified_on>
</patientSummary>
<patientSummary>
<link href="http://localhost:8080/rest/patients/P0000002" rel="https://phenotips.org/rel/patientRecord"/>
<id>P0000002</id>
<eid/>
<created_by>XWiki.Admin</created_by>
<created_on>2016-08-03T14:10:10.000Z</created_on>
<version>2.28</version>
<last_modified_by>XWiki.JohnDoe</last_modified_by>
<last_modified_on>2016-08-03T20:52:21.000Z</last_modified_on>
</patientSummary>
</patients>

View a single patient record

HTTP method: GET
URL: http://localhost:8080/rest/patients/{id}

For an existing patient record with an id value of P0000001, replace {id} in the url with P0000001.

Example httpie request:

http --session=JohnDoe GET http://localhost:8080/rest/patients/P0000001

Example curl request:

curl http://localhost:8080/rest/patients/P0000001

Example response body:

{
   "clinicalStatus": "affected",
   "date": "2016-08-03T14:10:07.000Z",
   "ethnicity": {
       "maternal_ethnicity": [],
       "paternal_ethnicity": []
    },
   "exam_date": "2016-08-03",
   "family_history": {},
   "features": [],
   "genes": [
        {
           "gene": "SP3",
           "status": "candidate",
           "strategy": [
               "sequencing"
            ]
        }
    ],
   "id": "P0000001",
   "last_modification_date": "2016-08-16T14:55:48.000Z",
   "last_modified_by": "JohnDoe",
   "life_status": "alive",
   "links": [
        {
           "href": "http://localhost:8080/rest/patients/P0000001",
           "rel": "self"
        }
    ],
   "meta": {
       "hgnc_version": "2016-03-30T19:53:05.302Z",
       "hpo_version": "releases/2016-01-13",
       "omim_version": "2015-10-07T16:48:25.859Z",
       "phenotips_version": "1.3-SNAPSHOT"
    },
   "nonstandard_features": [],
   "patient_name": {
       "last_name": "Smith"
    },
   "prenatal_perinatal_history": {},
   "report_id": "P0000001",
   "reporter": "JohnDoe",
   "sex": "U",
   "solved": {
       "status": "unsolved"
    },
   "specificity": {
       "date": "2016-08-22T16:38:34.688Z",
       "score": 0,
       "server": "monarchinitiative.org"
    }
}

Creating a patient record

HTTP method: POST
URL: http://localhost:8080/rest/patients

Example JSON data for a simple request:

{
   "clinicalStatus": "affected",
   "patient_name": {
       "last_name": "Smith",
       "first_name": "Samantha"
    },
   "sex": "F",
   "solved": {
       "status": "unsolved"
    }
}

Fields in the patient record that are not specified in the request will either take a default value (which may be an empty placeholder) or will not be set unless explicitly specified in the request body. Please refer to JSONExport for additional patient resource JSON parameters.

Example httpie request:

http --session=JohnDoe POST http://localhost:8080/rest/patients \
clinicalStatus=affected \
patient_name:='{"last_name": "Smith", "first_name": "Samantha"}' \
sex=F \
solved:='{"status": "unsolved"}'

Example curl request:

curl -H "Content-Type: application/json" -X POST -d \
'{"clinicalStatus": "affected", \
"patient_name": {"last_name": "Smith", "first_name": "Samantha"}, \
"sex": "F", \
"solved": {"status": "unsolved"} \
}' \
http://localhost:8080/rest/patients \

Example response:

HTTP/1.1 201 Created
Accept-Ranges: bytes
Content-Language: en
Content-Length: 0
Content-Script-Type: text/javascript
Date: Mon, 22 Aug 2016 17:43:32 GMT
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Location: http://localhost:8080/rest/patients/P0000005
Set-Cookie: JSESSIONID=c3e9ggmsx2yy8mn6mzgy3fcu;Path=/
XWiki-User: XWiki.XWikiGuest
XWiki-Version: 7.1.4

Updating a patient record

HTTP method: PUT
URL: http://localhost:8080/rest/patients/{id}

In the last example, a patient record with id P0000005 was created using POST. Updating the patient record would require one to specify only the data field(s) and the associated value of the data field to be updated. For instance, if we'd like to change the clinicalStatus (see the full list of JSON attributes in a patient object) value in the patient record from "affected" to "unaffected", we simply only need to specify this single key-value pair (below), while all other fields in the patient record will remain unchanged.

Simple example (see More on overwriting data with PUT for complex examples):

{
   "clinicalStatus": "unaffected"
}

Please refer to JSONExport for additional patient resource JSON parameters.

Example httpie request:

http --session=JohnDoe PUT http://localhost:8080/rest/patients/P0000005 \
clinicalStatus=unaffected

Example curl request:

curl -H "Content-Type: application/json" -X PUT -d \
'{"clinicalStatus": "unaffected"}' \
http://localhost:8080/rest/patients/P0000005

Example response:

HTTP/1.1 204 No Content
Accept-Ranges: bytes
Content-Language: en
Content-Length: 0
Content-Script-Type: text/javascript
Date: Mon, 22 Aug 2016 17:43:32 GMT
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Location: http://localhost:8080/rest/patients/P0000005
Set-Cookie: JSESSIONID=c3e9ggmsx2yy8mn6mzgy3fcu;Path=/
XWiki-User: XWiki.XWikiGuest
XWiki-Version: 7.1.4

More on overwriting data with PUT

Here is an example for a more complex case, such as when the JSON attribute (see the full list of JSON attributes in a patient object) to be updated in the patient record is a list, object, or list of objects. 

In this case (assume the response from a GET request for patient record P0000003), for the variants JSON attribute, the value is a list of objects representing gene variants:

{
   "patient_name": {
       "last_name": "Smith",
       "first_name": "Samantha"
    },
   "report_id": "P0000003",
   "variants": [
   {
     "genesymbol": "AES",
     "cdna": "c.1094C>T",
     "transcript": "NM_0000028",
     "sanger": "negative",
     "zygosity": "homozygous",
     "evidence": [
       "rare",
       "predicted",
       "reported"
     ],
     "interpretation": "variant_u_s"
   },
   {
     "genesymbol": "SP3",
     "cdna": "c.78_81del",
     "transcript": "NM_0000879",
     "sanger": "positive",
     "zygosity": "homozygous",
     "interpretation": "variant_u_s",
     "segregation": "not_segregates"
   }
    ],
   "reporter": "JohnDoe",
   "sex": "F",
   "solved": {
       "status": "unsolved"
    },
    ...
}

In the case that one wishes to update a single value (i.e. the transcript accession number for the variant inside gene AES) inside one of the objects from the variants list. One must provide the variant object with the updated field as well as all other existing objects in the current variants list inside the request body as the PUT method operates by overwriting any data mapped to the JSON attributes specified in the request with the data provided (see the full list of JSON attributes in a patient object). 

Hence, the JSON request body for updating the transcript accession number value from NM_0000028 to NM_0000123 would be:

{
   "variants": [
   {
     "genesymbol": "AES",
     "cdna": "c.1094C>T",
     "transcript": "NM_0000123",
     "sanger": "negative",
     "zygosity": "homozygous",
     "evidence": [
       "rare",
       "predicted",
       "reported"
     ],
     "interpretation": "variant_u_s"
   },
   {
     "genesymbol": "SP3",
     "cdna": "c.78_81del",
     "transcript": "NM_0000879",
     "sanger": "positive",
     "zygosity": "homozygous",
     "interpretation": "variant_u_s",
     "segregation": "not_segregates"
   }
    ]
}

Similarly, to delete one of the variant objects from the current variants list, remove one of the variant objects from the current list and send the remaining list in the body of a PUT request:

{
 "variants": [
   {
     "genesymbol": "AES",
     "cdna": "c.1094C>T",
     "transcript": "NM_0000123",
     "sanger": "negative",
     "zygosity": "homozygous",
     "evidence": [
       "rare",
       "predicted",
       "reported"
     ],
     "interpretation": "variant_u_s"
   }
    ]
}

Deleting a patient record

HTTP method: DELETE
URL: http://localhost:8080/rest/patients/{id}

Example httpie request:

http --session=JohnDoe DELETE http://localhost:8080/rest/patients/P0000005

Example curl request:

curl -X DELETE http://localhost:8080/rest/patients/P0000005

Example response:

HTTP/1.1 204 No Content
Accept-Ranges: bytes
Content-Language: en
Content-Length: 0
Content-Script-Type: text/javascript
Date: Mon, 22 Aug 2016 19:19:34 GMT
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Set-Cookie: JSESSIONID=r8kytfz1vk3n14tp6npkgvx4v;Path=/
XWiki-User: XWiki.XWikiGuest
XWiki-Version: 7.1.4