Storage and API configuration
Aidbox keeps resource persistence and resource APIs in two layers you can configure independently:
- A storage defines how a resource type's data is stored in PostgreSQL and lets you configure it: the table name, whether history is kept, and the name of the history table. The
defaultstorage type uses the table layout described in Database schema. - An API connects a storage to a FHIR REST endpoint. It exposes the resource type at
/fhir/{resourceType}and governs which FHIR interactions (read, create, update, search, history) are available.
A resource type can have several storages, but only one is active at a time: the storage an API points to. /fhir/metadata lists only the resource types and interactions that have an active API.
You manage both layers through FHIR operations that accept and return a Parameters resource.
API auto-mount
The enable-api-auto-mount setting controls whether Aidbox exposes resource types for you.
true(default): Aidbox generates a storage and an API for every resource type that has aStructureDefinition, together with itsSearchParameters./fhir/Patientand/fhir/Patient?active=truework without any configuration. This matches how Aidbox behaved before storages and APIs became configurable.false: Aidbox mounts only its essential system resources (such asUser,Client,AccessPolicy). To expose any other resource type, create a storage and an API for it with the operations below.
Turn auto-mount off when you want to:
- expose a selected set of resource types and nothing else,
- keep a newly uploaded
StructureDefinitionfrom becoming available until you opt in, - serve a resource type under an endpoint name you choose, such as
/fhir/MyResource.
Storages
A storage record carries these parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
structureDefinition | canonical | yes | Canonical URL (url|version) of the StructureDefinition the storage conforms to. |
storageType | string | yes | Only default is supported today. Future releases add other types, such as partitioned. |
tableName | string | yes | Name of the main PostgreSQL table. At most 63 bytes (the PostgreSQL identifier limit). |
history | boolean | no | Keep prior versions in a history table. Defaults to false. |
historyTableName | string | conditional | Name of the history table. Required when history is true, and must be omitted when history is false. |
storageId | string | output | Server-generated identifier. Pass it to $configure-storage and $delete-storage. |
$create-storage
Creates a storage and its PostgreSQL table. If the table already exists, Aidbox reuses it. With history set to true, Aidbox also creates the history table. The response echoes the storage with its generated storageId.
POST /fhir/$create-storage
Content-Type: application/json
{
"resourceType": "Parameters",
"parameter": [
{ "name": "structureDefinition", "valueCanonical": "http://hl7.org/fhir/StructureDefinition/Observation|4.0.1" },
{ "name": "storageType", "valueString": "default" },
{ "name": "tableName", "valueString": "observation_main" },
{ "name": "history", "valueBoolean": false }
]
}
{
"resourceType": "Parameters",
"parameter": [
{ "name": "structureDefinition", "valueCanonical": "http://hl7.org/fhir/StructureDefinition/Observation|4.0.1" },
{ "name": "storageType", "valueString": "default" },
{ "name": "tableName", "valueString": "observation_main" },
{ "name": "history", "valueBoolean": false },
{ "name": "storageId", "valueString": "2791c25a-c28d-47ea-ab96-3e13162a5b58" }
]
}
$configure-storage
Updates an existing storage. The operation validates the parameters you send, so pass the full storage definition (storageType, tableName, structureDefinition, history, and historyTableName when history is true) along with the storageId.
POST /fhir/$configure-storage
Content-Type: application/json
{
"resourceType": "Parameters",
"parameter": [
{ "name": "structureDefinition", "valueCanonical": "http://hl7.org/fhir/StructureDefinition/Observation|4.0.1" },
{ "name": "storageType", "valueString": "default" },
{ "name": "tableName", "valueString": "observation_main" },
{ "name": "history", "valueBoolean": true },
{ "name": "historyTableName", "valueString": "observation_main_history" },
{ "name": "storageId", "valueString": "2791c25a-c28d-47ea-ab96-3e13162a5b58" }
]
}
{
"resourceType": "Parameters",
"parameter": [
{ "name": "structureDefinition", "valueCanonical": "http://hl7.org/fhir/StructureDefinition/Observation|4.0.1" },
{ "name": "storageType", "valueString": "default" },
{ "name": "tableName", "valueString": "observation_main" },
{ "name": "history", "valueBoolean": true },
{ "name": "historyTableName", "valueString": "observation_main_history" },
{ "name": "storageId", "valueString": "2791c25a-c28d-47ea-ab96-3e13162a5b58" }
]
}
$list-storage
Returns every storage as a collection Bundle of Parameters.
POST /fhir/$list-storage
Content-Type: application/json
{ "resourceType": "Parameters" }
{
"resourceType": "Bundle",
"type": "collection",
"entry": [
{
"resource": {
"resourceType": "Parameters",
"parameter": [
{ "name": "structureDefinition", "valueCanonical": "http://hl7.org/fhir/StructureDefinition/Observation|4.0.1" },
{ "name": "storageType", "valueString": "default" },
{ "name": "tableName", "valueString": "observation_main" },
{ "name": "history", "valueBoolean": true },
{ "name": "historyTableName", "valueString": "observation_main_history" },
{ "name": "storageId", "valueString": "2791c25a-c28d-47ea-ab96-3e13162a5b58" }
]
}
}
]
}
$delete-storage
Removes the storage record. The PostgreSQL table and its data stay in place.
POST /fhir/$delete-storage
Content-Type: application/json
{
"resourceType": "Parameters",
"parameter": [
{ "name": "storageId", "valueString": "2791c25a-c28d-47ea-ab96-3e13162a5b58" }
]
}
{
"resourceType": "Parameters",
"parameter": [
{ "name": "status", "valueString": "success" }
]
}
Deleting a storage does not drop its table. The data remains, and you can reattach it by creating a storage on the same tableName.
APIs
An API record carries these parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
resourceType | string | yes | FHIR resource type exposed at /fhir/{resourceType}. One active API per resource type. |
storageId | string | yes | Storage the API reads from and writes to. |
apiTemplate | string | yes | pre-2604. |
apiId | string | output | Server-generated identifier. Pass it to $configure-api and $delete-api. |
pre-2604 is the only template available, and it is required. It enables the full FHIR REST interaction set (read, vread, create, update, patch, delete, history, search), reproducing the default behavior of Aidbox APIs before this feature. Future releases add more templates. They also let an API turn individual interactions on and off without a template.
$create-api
Connects a resource type to a storage. The resource type starts serving requests at /fhir/{resourceType} and appears in /fhir/metadata.
POST /fhir/$create-api
Content-Type: application/json
{
"resourceType": "Parameters",
"parameter": [
{ "name": "resourceType", "valueString": "Observation" },
{ "name": "storageId", "valueString": "2791c25a-c28d-47ea-ab96-3e13162a5b58" },
{ "name": "apiTemplate", "valueString": "pre-2604" }
]
}
{
"resourceType": "Parameters",
"parameter": [
{ "name": "apiId", "valueString": "39473529-a37e-4b98-afc2-bea014bbe68e" },
{ "name": "apiTemplate", "valueString": "pre-2604" },
{ "name": "resourceType", "valueString": "Observation" },
{ "name": "storageId", "valueString": "2791c25a-c28d-47ea-ab96-3e13162a5b58" }
]
}
$configure-api
Updates an existing API, for example to point a resource type at a different storage. Pass the apiId with the full API definition.
POST /fhir/$configure-api
Content-Type: application/json
{
"resourceType": "Parameters",
"parameter": [
{ "name": "apiId", "valueString": "39473529-a37e-4b98-afc2-bea014bbe68e" },
{ "name": "resourceType", "valueString": "Observation" },
{ "name": "apiTemplate", "valueString": "pre-2604" },
{ "name": "storageId", "valueString": "ac2e94f7-e543-4ea4-a739-a8159a06e939" }
]
}
{
"resourceType": "Parameters",
"parameter": [
{ "name": "apiId", "valueString": "39473529-a37e-4b98-afc2-bea014bbe68e" },
{ "name": "apiTemplate", "valueString": "pre-2604" },
{ "name": "resourceType", "valueString": "Observation" },
{ "name": "storageId", "valueString": "ac2e94f7-e543-4ea4-a739-a8159a06e939" }
]
}
$list-api
Returns every API as a collection Bundle of Parameters.
POST /fhir/$list-api
Content-Type: application/json
{ "resourceType": "Parameters" }
{
"resourceType": "Bundle",
"type": "collection",
"entry": [
{
"resource": {
"resourceType": "Parameters",
"parameter": [
{ "name": "apiId", "valueString": "39473529-a37e-4b98-afc2-bea014bbe68e" },
{ "name": "apiTemplate", "valueString": "pre-2604" },
{ "name": "resourceType", "valueString": "Observation" },
{ "name": "storageId", "valueString": "2791c25a-c28d-47ea-ab96-3e13162a5b58" }
]
}
}
]
}
$delete-api
Removes the API. The resource type stops being served, unless auto-mount regenerates it. The storage and its data stay in place.
POST /fhir/$delete-api
Content-Type: application/json
{
"resourceType": "Parameters",
"parameter": [
{ "name": "apiId", "valueString": "39473529-a37e-4b98-afc2-bea014bbe68e" }
]
}
{
"resourceType": "Parameters",
"parameter": [
{ "name": "status", "valueString": "success" }
]
}
Example: disable history for a resource type
With auto-mount on, Aidbox serves every resource type with history enabled. To turn history off for one resource type, point its API at a default storage that uses the resource type's existing table with history set to false. The new storage overrides the auto-mounted one, and since $create-storage reuses an existing table, the data stays in place.
This example disables history for Observation, whose data lives in the observation table.
Create a storage on that table with history off:
POST /fhir/$create-storage
Content-Type: application/json
{
"resourceType": "Parameters",
"parameter": [
{ "name": "structureDefinition", "valueCanonical": "http://hl7.org/fhir/StructureDefinition/Observation|4.0.1" },
{ "name": "storageType", "valueString": "default" },
{ "name": "tableName", "valueString": "observation" },
{ "name": "history", "valueBoolean": false }
]
}
Point the Observation API at the storage $create-storage returned:
POST /fhir/$create-api
Content-Type: application/json
{
"resourceType": "Parameters",
"parameter": [
{ "name": "resourceType", "valueString": "Observation" },
{ "name": "storageId", "valueString": "0ff1baab-411d-4682-8e42-0325caf760c5" },
{ "name": "apiTemplate", "valueString": "pre-2604" }
]
}
Reads, creates, updates, and searches keep working, and updates no longer write history rows. The _history interactions, at both the instance and type level, respond with 422 and an OperationOutcome:
GET /fhir/Observation/{id}/_history
{
"resourceType": "OperationOutcome",
"id": "not-supported",
"issue": [
{
"severity": "fatal",
"code": "not-supported",
"diagnostics": "History is disabled for resource type Observation"
}
]
}
To bring history back, delete the API and storage so the resource type reverts to the auto-mounted storage, or configure the storage with history set to true and a historyTableName.