For AI agents: the documentation index is at /docs/aidbox/llms.txt. A Markdown version of this page is available at /docs/aidbox/notebooks.md or by requesting it with the Accept: text/markdown header.
Aidbox Docs
All notebooks

Getting Started: Custom Resources

Guide on work with custom resources

34 cells · updated Jul 17, 2023

This is a read-only view. Responses shown were saved when the notebook was published — open it in your own Aidbox to run the cells against live data.

Defining a Custom Resource

Sometimes your data does not fit any existing FHIR resources. It is not always obvious that your data cannot be translated to FHIR because of some FHIR generalizations. The right first step is to go to FHIR comunity chat and ask your specific question about mapping to FHIR, or contact Health Samurai modeling team about your concern. If you are still sure that there is no appropriate resource in FHIR or it takes too much time to wait for it, you can define your own Custom Resources in Aidbox.

Custom resources in Aidbox

This Notebook explains Custom Resources using Entity, but since 2303 we recommend to use Aidbox Projects way.

Unfortunatelly, Aidbox Project configuration is not available in Aidbox Sandbox.

Custom resources using Entity

Custom Resources are defined exactly the same way as core FHIR resources. They can refer to existing resources, have uniform REST API for CRUD and Search,and participate in transactions.

Let's imagine that in our application we want to store user preferences such as UI configuration or personalized Patient List filters. It is expected that you have already created a box in Aidbox Sandbox. First of all, we have to define a new resource type by creating an Entity resource.

REST Send Cells run only inside Aidbox. Use Run in Aidbox above to open this notebook in your own instance.
POST /Entity
content-type: text/yaml

id: UserSetting
type: resource
isOpen: true
Response: Body
Status: 201
type: resource
isOpen: true
id: UserSetting
resourceType: Entity
meta: {lastUpdated: '2021-09-24T11:20:10.327424Z', createdAt: '2021-09-24T11:20:10.327424Z', versionId: '3218'}
REST Send Cells run only inside Aidbox. Use Run in Aidbox above to open this notebook in your own instance.
GET /UserSetting
accept: text/yaml
Response: Body
Status: 200
query-time: 4
meta: {versionId: '3234'}
type: searchset
resourceType: Bundle
total: 0
link:
- {relation: first, url: '/UserSetting?page=1'}
- {relation: self, url: '/UserSetting?page=1'}
query-timeout: 60000
entry: []
query-sql: ['SELECT "usersetting".* FROM "usersetting" LIMIT ? OFFSET ? ', 100, 0]
SQL Send Cells run only inside Aidbox. Use Run in Aidbox above to open this notebook in your own instance.
SELECT * FROM "usersetting";
REST Send Cells run only inside Aidbox. Use Run in Aidbox above to open this notebook in your own instance.
POST /UserSetting
content-type: text/yaml

id: user-1
theme: dark
Response: Body
Status: 201
theme: dark
id: user-1
resourceType: UserSetting
meta: {lastUpdated: '2021-09-24T11:25:38.184205Z', createdAt: '2021-09-24T11:25:38.184205Z', versionId: '3243'}
REST Send Cells run only inside Aidbox. Use Run in Aidbox above to open this notebook in your own instance.
GET /UserSetting
accept: text/yaml
Response: Body
Status: 200
query-time: 1
meta: {versionId: '3246'}
type: searchset
resourceType: Bundle
total: 1
link:
- {relation: first, url: '/UserSetting?page=1'}
- {relation: self, url: '/UserSetting?page=1'}
query-timeout: 60000
entry:
- resource:
    theme: dark
    id: user-1
    resourceType: UserSetting
    meta: {lastUpdated: '2021-09-24T11:25:38.184205Z', createdAt: '2021-09-24T11:25:38.184205Z', versionId: '3243'}
  fullUrl: http://localhost:8765/UserSetting/user-1
  link:
  - {relation: self, url: 'http://localhost:8765/UserSetting/user-1'}
query-sql: ['SELECT "usersetting".* FROM "usersetting" LIMIT ? OFFSET ? ', 100, 0]
SQL Send Cells run only inside Aidbox. Use Run in Aidbox above to open this notebook in your own instance.
SELECT id, resource->>'theme' as theme FROM "usersetting";
REST Send Cells run only inside Aidbox. Use Run in Aidbox above to open this notebook in your own instance.
GET /UserSetting/user-1
accept: text/yaml
Response: Body
Status: 200
theme: dark
id: user-1
resourceType: UserSetting
meta: {lastUpdated: '2021-09-24T11:25:38.184205Z', createdAt: '2021-09-24T11:25:38.184205Z', versionId: '3243'}
REST Send Cells run only inside Aidbox. Use Run in Aidbox above to open this notebook in your own instance.
PUT /UserSetting/user-1
content-type: text/yaml

theme: white
patientsFilters:
  - location: ICU
Response: Body
Status: 200
theme: white
patientsFilters:
- {location: ICU}
id: user-1
resourceType: UserSetting
meta: {lastUpdated: '2021-09-24T11:28:19.313003Z', createdAt: '2021-09-24T11:25:38.184205Z', versionId: '3256'}
REST Send Cells run only inside Aidbox. Use Run in Aidbox above to open this notebook in your own instance.
GET /UserSetting/user-1/_history
accept: text/yaml
Response: Body
Status: 200
resourceType: Bundle
type: history
total: 2
entry:
- resource:
    theme: white
    patientsFilters:
    - {location: ICU}
    id: user-1
    resourceType: UserSetting
    meta: {lastUpdated: '2021-09-24T11:28:19.313003Z', createdAt: '2021-09-24T11:25:38.184205Z', versionId: '3256'}
  request: {method: PUT, url: UserSetting}
- resource:
    theme: dark
    id: user-1
    resourceType: UserSetting
    meta: {lastUpdated: '2021-09-24T11:25:38.184205Z', createdAt: '2021-09-24T11:25:38.184205Z', versionId: '3243'}
  request: {method: POST, url: UserSetting}
id: '3256'
query-sql: ['WITH history AS ((SELECT id, txid, ts, resource_type, status::text AS status, resource, cts FROM "usersetting" WHERE id = ?) UNION (SELECT id, txid, ts, resource_type, status::text AS status, resource, cts FROM "usersetting_history" WHERE id = ?)) SELECT * FROM history ORDER BY txid DESC LIMIT ?', user-1, user-1, 100]
REST Send Cells run only inside Aidbox. Use Run in Aidbox above to open this notebook in your own instance.
DELETE /UserSetting/user-1
accept: text/yaml
Response: Body
Status: 200
theme: white
patientsFilters:
- {location: ICU}
id: user-1
resourceType: UserSetting
meta: {lastUpdated: '2021-09-24T11:29:04.192158Z', createdAt: '2021-09-24T11:29:04.192158Z', versionId: '3260'}
REST Send Cells run only inside Aidbox. Use Run in Aidbox above to open this notebook in your own instance.
POST /UserSetting
content-type: text/yaml

id: user-2
theme:
  - name: white
  - name: black
Response: Body
Status: 201
theme:
- {name: white}
- {name: black}
id: user-2
resourceType: UserSetting
meta: {lastUpdated: '2021-09-24T11:31:04.161350Z', createdAt: '2021-09-24T11:31:04.161350Z', versionId: '3268'}
REST Send Cells run only inside Aidbox. Use Run in Aidbox above to open this notebook in your own instance.
POST /Attribute
content-type: text/yaml

id: UserSetting.theme
path: ['theme']
type: {id: string, resourceType: Entity}
enum: ['dark', 'white']
resource: {id: UserSetting, resourceType: Entity}
Response: Body
Status: 201
enum: [dark, white]
path: [theme]
type: {id: string, resourceType: Entity}
resource: {id: UserSetting, resourceType: Entity}
id: UserSetting.theme
resourceType: Attribute
meta: {lastUpdated: '2021-09-24T11:34:39.693486Z', createdAt: '2021-09-24T11:34:39.693486Z', versionId: '3277'}
REST Send Cells run only inside Aidbox. Use Run in Aidbox above to open this notebook in your own instance.
GET /$json-schema?path=definitions.UserSetting
accept: text/yaml
Response: Body
Status: 200
path: [definitions, UserSetting]
schema:
  type: object
  patternProperties:
    ^(_.*|fhir_.*): {}
  properties:
    id: {type: string}
    extension:
      type: array
      items: {$ref: '#/definitions/Extension'}
    modifierExtension:
      type: array
      items: {$ref: '#/definitions/Extension'}
    meta: {$ref: '#/definitions/Meta'}
    resourceType: {type: string, constant: UserSetting}
    theme:
      type: string
      enum: [dark, white]
REST Send Cells run only inside Aidbox. Use Run in Aidbox above to open this notebook in your own instance.
POST /UserSetting
content-type: text/yaml

id: user-3
theme: 2
Response: Body
Status: 422
resourceType: OperationOutcome
text: {status: generated, div: Invalid resource}
issue:
- severity: fatal
  code: invalid
  expression: [UserSetting.theme]
  diagnostics: expected type of string
- severity: fatal
  code: invalid
  expression: [UserSetting.theme]
  diagnostics: expected one of dark, white
REST Send Cells run only inside Aidbox. Use Run in Aidbox above to open this notebook in your own instance.
PATCH /Entity/UserSetting?_type=json-merge-patch
content-type: text/yaml

isOpen: false
Response: Body
Status: 200
type: resource
isOpen: false
id: UserSetting
resourceType: Entity
meta: {lastUpdated: '2021-09-24T11:43:46.904897Z', createdAt: '2021-09-24T11:20:10.327424Z', versionId: '3307'}
REST Send Cells run only inside Aidbox. Use Run in Aidbox above to open this notebook in your own instance.
GET /$json-schema?path=definitions.UserSetting
accept: text/yaml
Response: Body
Status: 200
path: [definitions, UserSetting]
schema:
  type: object
  patternProperties:
    ^(_.*|fhir_.*): {}
  properties:
    id: {type: string}
    extension:
      type: array
      items: {$ref: '#/definitions/Extension'}
    modifierExtension:
      type: array
      items: {$ref: '#/definitions/Extension'}
    meta: {$ref: '#/definitions/Meta'}
    resourceType: {type: string, constant: UserSetting}
    theme:
      type: string
      enum: [dark, white]
  additionalProperties: false

And we see the schema keyword additionalProperties: false (last line in the response above) which means that now our schema is closed. Let's test it by the request with additional property menu:

REST Send Cells run only inside Aidbox. Use Run in Aidbox above to open this notebook in your own instance.
POST /UserSetting
content-type: text/yaml

theme: dark
menu: collapsed
Response: Body
Status: 422
resourceType: OperationOutcome
text: {status: generated, div: Invalid resource}
issue:
- severity: fatal
  code: invalid
  expression: [UserSetting.menu]
  diagnostics: extra property