Family REST proposal v2

Family REST proposal v2


New Pedigree JSON (with optional layout): 

"JSON_version": TEXT,

"proband": ID, // optional

"members": [ {"id":1, "properties": {...}}, {"id":2, "properties": {...}, "pedigreeProperties": {...}}, {"id":3, "properties" {...}, "notInPedigree": true}, ... ],  // required
                                  // each member may have an optional "properties" parameter (which has the same format as PT Patient JSON)
                                  // or/and "pedigreeProperties" parameter, which contains pedigree-specific data (which may change over time together with "JSON_version");
                                  // members with unknown position in the pedigree should have "notInPedigree" property set to "true"

"relationships": [      // is used to specify a relationship between two or more members (partners, parent(s)-child, siblings).
                        // current pedigree implementation will always create a []--*--() figure in the pedigree (even for two siblings, it will add new virtual parents - this should be improved in future versions)
       "id": RID,                 // needed for layout and long edges; only unique among relationships; not needed if there is no layout provided

       "members": [ ID1, ID2 ],   // at most 2 members are supported for now, these are the members which form the []--*--() part, children/siblings are specified in the "children" section
                                  // TODO: does it makes sense to rename this to "partners" or something like that, to not confuse this with "all members of the relationship including children"?
                                  // required: either 2 members (in a relationship) or one member + at least one child or no members and at least two children

       "properties": { "separated": true/false, "childlessStatus": "no"/"childless"/"infertile", "childlessReason": "text", "consanguinity": "yes"/"no"/"auto" (default) }, // optional

       "children": [                                                                                        // optional
             "id": ID,                   // a child can only be listed in one relationship (unless "adopted in" in one and "adopted out" in another - unsupported for now)
             "adopted": "no"/"in"/"out"  // default: "no"
                                         // (if one relationship has the child as "in" and another as "out" a path should be drawn from one family to the other, unsupported for now)
             "pregnancy": ID,            // (not implemented, supposedly specifies who carried the pregnancy - can be someone outside the relationship, or may need to clarify if both relationship members are female)
             "eggDonor": ID,             // (not implemented)
             "spermDonor": ID,           // (not implemented)
             "mitochondrial": ID,        // (not implemented)
      }, ...

"layout": {  // optional
   "members":       { ID1 : {"generation": W, "order": Z, "x": X}, ID2: {...} }, ... ],    // generation is mandatory, order is optional
   "relationships": { RID1: {"order": Z, "x": X}, RID2: {...}, ... },
   "longedges":     { RID_A: { "member": ID, "path": [ {"order": Z, "x": X}, {...}, ...] }, RID_B: {...}, ... ]   // top to bottom, from the person to the relationship

 // layout note: maybe "x" is not needed in layout, given generation and order can auto layout quickly and without changes? need to test
 // on the other hand: if someone else uses this, having X available lets them draw their own without complicated layout algorithms
 // also: maybe add "y" since given x and y it is easy to restore order and generation. generation/order make more sense, but x+y has all of that information + extra (actual x and y)
 // it is supported to only provide generations, or generations + orders, or generations + orders + positions (x)

 "settings": { "colors": { ... },   // optional, used to keep abnormality colors consistent, enables support for custom abnormality names; also currently used by pedigree legend
               "names": { ... }     //           may be discarded in one of the future versions

- note: "properties" should be in the same format as PhenoTips patient JSON except that nodes not linked to PhenoTips patients should not/will not have an "id" field defined there
- note: members for which "notInPedigree" is set to true are treated as node-less family members and are not included in pedigree layout
- implementation note: if at any point layout disagrees with pedigree, layout is scrapped and pedigree is re-laid-out; "notInPedigree" members are not considering when laying out the pedigree
- only "members" field is mandatory, however since pedigree should be a connected component if there is more than one member (with "notInPedigree" != true) there must be a corresponding link in the "relationships".


Families REST:

  • GET -> get family JSON, including pedigree JSON in format described above
    /families/{id} -> GET (by id)
    /families/eid/{id} -> GET (by external id)
    - optional: control if layout is included ?layout=false
    - optional: get PED (or other formats) using content-type (or URL parameters? easier to read/remember)

For all operations below pedigree image will not be updated (for now), pedigree will be OK once opened in pedigree editor

  • SET -> create a NEW family given pedigree using either JSON format described above OR other pedigree formats, e.g. PED
    /families -> POST
    input: either JSON or PED (auto-detect or/and use content-type?)
    note: for PED and other formats use whatever ID format supports as external_id for the pedigree node
    output body: a JSON with new family details (id) for HTTP OK, error details JSON for other HTTP codes
    for now: only new families, no overwriting existing families, no PUT for /families/{id} ?
  • For all operations below: refer to pedigree nodes by either external_id or Phenotips patient IDs (?eid=..., ?id=...)
  • REST endpoint: /families/{id}/OPERATION -> PUT + url parameters for IDs (no body for LINK/UNLINK)
  • UNLINK PATIENT: /families/{id}/link ?
      input: patientID or external_id
      result: phenotipsID link removed form pedigree & family, or error code if not linked or not enough rights etc.
  • LINK PATIENT: /families/{id}/unlink ?
      input: external_id, PhenotipsID
  • MODIFY pedigree: NOT supported for now. For the future:
    - CAN add parents (if does not have parents) or siblings or spouse* to a node (or, which is the same, add a node which is a child/parent of other node). Can be specified via patientID or pedigreeID
    - CAN merge pedigrees in simple cases (e.g. node X does not have spouses/children in existing pedigree and does not have parents in updated part)
    - cant merge in other cases. Should we then even bother?
    - removal is more tricky, what to do with "unlinked" patients/disconnected components, which one to keep?


PhenoTips® is freely available under the terms of the the GNU Affero General Public License, version 3.0.

 Download the latest release
 Play with our demo
 Get the source code


 Ask for free support (by volunteers):
 Inquire about commercial support:
 Follow us on twitter:

PhenoTips® is an exclusive trademark of Gene42 Inc.