Document toolboxDocument toolbox

Demographics API

Adds functionality to store demographic information on the server. See https://sagebionetworks.jira.com/wiki/spaces/MTB/pages/1934819724 and Demographic Survey Categories (somewhat outdated).

Type Checking

Currently, there is no type checking on demographic answer values, so all values are stored as strings. Type checking is a V2 goal.

App-Level vs. Study-Level

Routes are available for both app-level and study-level demographics. The idea is that some basic demographics might be collected during app onboarding which is not associated with a particular study, and then additional demographics data might be collected by a particular study within the app.

Routes

Saving

POST /v5/studies/{studyId}/participants/{userId}/demographics

Save/overwrite all demographics for a user

Study-level, posted on the user’s behalf (by researcher, study coordinator)

POST /v5/studies/{studyId}/participants/self/demographics

Save/overwrite all demographics for a user

Study-level, posted by the user

POST /v3/participants/{userId}/demographics

Save/overwrite all demographics for a user

App-level, posted on the user’s behalf (by app admin)

POST /v3/participants/self/demographics

Save/overwrite all demographics for a user

App-level, posted by the user

POST /v5/studies/{studyId}/participants/{userId}/demographics/assessment

Save/overwrite all demographics for a user

Study-level, posted on the user’s behalf (by researcher, study coordinator)

Uses the assessment JSON model

POST /v5/studies/{studyId}/participants/self/demographics/assessment

Save/overwrite all demographics for a user

Study-level, posted by the user

Uses the assessment JSON model

POST /v3/participants/{userId}/demographics/assessment

Save/overwrite all demographics for a user

App-level, posted on the user’s behalf (by app admin)

Uses the assessment JSON model

POST /v3/participants/self/demographics/assessment

Save/overwrite all demographics for a user

App-level, posted by the user

Uses the assessment JSON model

Deleting

DELETE /v5/studies/{studyId}/participants/{userId}/demographics/{demographicId}

Deletes a specific demographic (single category) for a particular user

Study-level, done by researcher or study coordinator

DELETE /v3/participants/{userId}/demographics/{demographicId}

Deletes a specific demographic (single category) for a particular user

App-level, done by app admin

DELETE /v5/studies/{studyId}/participants/{userId}/demographics

Deletes all of a user’s demographics

Study-level, done by researcher or study coordinator

DELETE /v3/participants/{userId}/demographics

Deletes all of a user’s demographics

App-level, done by app admin

Fetching

GET /v5/studies/{studyId}/participants/{userId}/demographics

Fetches all demographics for a user

Study-level, done by researcher/study-coordinator

GET /v3/participants/{userId}/demographics

Fetches all demographics for a user

App-level, done by app admin

GET /v5/studies/{studyId}/participants/demographics

Fetches all study-level demographics for all users within a study

Study-level, done by researcher/study-coordinator

GET /v3/participants/demographics

Fetches all app-level demographics for all users within an app

App-level, done by app admin

JSON Format

Unless otherwise stated, routes use the following schema (for a single user):

{ "userId": (read only) <string>, "demographics": { (category name): { "id": (guid) (read only) <string>, "multipleSelect": <bool>, "values": [ <any> ] "units": <string> }, ... } }

Example:

{ "userId": "userId1", "demographics": { "height": { "id": "guid1", "multipleSelect": false, "values": [ 72.0 ] "units": "m" }, "race": { "id": "guid2", "multipleSelect": true, "values": [ "Asian", "Native Hawaiian or Other Pacific Islander" ] } } }

Certain routes use an assessment response model for demographic input:

{ "stepHistory": [ { "children": [ { "identifier": <string> (category name), "answerType": { (optional) "unit": <string> }, "value": <single value, any type OR array of single value, any type OR object with fields of single value, any type> } ] } ] }

Although other fields may be included in the normal assessment model, all other fields are discarded for demographics use.

Example:

Internal model

SQL:

3 tables are used because each table has a one-to-many relationship with the table below it, both intuitively and in SQL, and this nested format is much simpler with multiple tables. It also allows convenient grouping by userId for a better JSON format.

  • DemographicsUsers: maps to Java class DemographicUser

    • Contains all demographics for a single user

    • One-to-many with Demographics

  • Demographics: maps to Java class Demographic

    • Contains all values for a single demographic category for a single user

    • One-to-many with DemographicsValues

  • DemographicsValues: maps to Java class DemographicValue

    • Contains a single value in a demographic category

App-level demographics are represented with a null studyId.