Overview

wsidb reads and writes the WSi database over HTTP. Each request names the WSi version to serve it.

Endpoints
Endpoint Purpose

GET /v0/versions

The supported WSi versions.

GET /v0/<wsi-version>/table/<table-type>

One table as JSON.

GET /v0/<wsi-version>/tables/schema

The columns every table holds.

GET /v0/<wsi-version>/tables/dat

All tables in WSi’s binary .dat format.

PUT /v0/<wsi-version>/tables

Write a set of tables.

POST /v0/<wsi-version>/tables/check

Check a set of tables without writing.

GET /v0/versions is open; every other endpoint requires the headers described under Requests.

Requests

A request body larger than 8 MiB is rejected with 413.

WSi version

The first path segment after /v0/ names the WSi version to serve the request:

/v0/wsi-<major>-<minor>/...
/v0/wsi-<major>/...

Omitting the minor version uses the newest one supported for that major version.

wsi4- is accepted in place of wsi-.

License key

Authorization: Bearer <license-key>

The license key is a UUID. A key that is not valid is answered with 401; a database the key does not reach, or may not write to, with 403.

Database

The database must be linked to the license key, and is named either by its UUID or by its name:

X-Database-Uuid: <database-uuid>
X-Database-Name: <database-name>

The UUID is the preferred handle: a request carrying both headers is served by the UUID, and the name is ignored. Selecting by UUID requires WSi 2.3 or newer. A database whose name contains whitespace can be reached only by its UUID.

GET versions

The WSi versions this service supports.

GET /v0/versions
curl 'https://wsidb.wsoptics.de/v0/versions'
[
    {"major": 1, "minor": 31},
    {"major": 2, "minor": 3}
]

The versions come in no particular order.

GET table

One table as JSON.

GET /v0/<wsi-version>/table/<table-type>

<table-type> is a value of WSi’s TableType enumeration, matched case-sensitively. The values, and the columns each table’s rows hold, are documented under Table Documentation.

curl -H 'Authorization: Bearer <license-key>' \
     -H 'X-Database-Uuid: <database-uuid>' \
     'https://wsidb.wsoptics.de/v0/wsi-2/table/sheetMaterial'

The response body is an array of rows. Their columns follow the table type; the example below is sheetMaterial.

[
    {
        "identifier": "1.0038",
        "name": "1.0038",
        "description": ""
    }
]

GET tables schema

The columns every table holds.

GET /v0/<wsi-version>/tables/schema
curl -H 'Authorization: Bearer <license-key>' \
     -H 'X-Database-Uuid: <database-uuid>' \
     'https://wsidb.wsoptics.de/v0/wsi-2/tables/schema'

One entry per table type, columns in column order. key names the column in the rows GET table serves, unique marks the columns identifying a row, refers is present where a column points at another table, and unit holds the factors of the unit the values are served in.

[
    {
        "type": "sheetMaterialDensity",
        "translations": [
            {"language": "en", "text": "Sheets - Material density"},
            {"language": "de", "text": "Bleche - Materialdichte"}
        ],
        "columns": [
            {
                "key": "sheetMaterialId",
                "translations": [
                    {"language": "en", "text": "Sheet - Material"},
                    {"language": "de", "text": "Blech - Material"}
                ],
                "valueType": "string",
                "nullable": false,
                "unique": true,
                "refers": {
                    "type": "sheetMaterial",
                    "columnIndex": 0,
                    "columnKey": "identifier"
                },
                "enumValues": [],
                "unit": []
            },
            {
                "key": "density",
                "translations": [
                    {"language": "en", "text": "Density"},
                    {"language": "de", "text": "Dichte"}
                ],
                "valueType": "number",
                "nullable": false,
                "unique": false,
                "enumValues": [],
                "unit": [
                    {"unit": "kg", "exponent": 1},
                    {"unit": "m", "exponent": -3}
                ]
            }
        ]
    }
]

valueType is one of string, number, integer, boolean or enumeration. enumValues is filled only for enumeration, and translations carries the languages the WSi version holds a name in.

Requires WSi 2.6 or newer; an older version is answered with 400.

GET tables (dat)

All tables at once, in WSi’s binary .dat format.

GET /v0/<wsi-version>/tables/dat
curl -H 'Authorization: Bearer <license-key>' \
     -H 'X-Database-Uuid: <database-uuid>' \
     -o tables.dat \
     'https://wsidb.wsoptics.de/v0/wsi-2/tables/dat'

The response body is the raw .dat payload, to be handed to WSi as-is rather than parsed.

PUT tables

Write a set of tables. The update is applied only if the database stays consistent; on any inconsistency the whole update is aborted and the database is left unchanged.

PUT /v0/<wsi-version>/tables

The body is a JSON object holding the tables to write and how they meet what is already stored. Each table has a type naming a value of the TableType enumeration and a content holding rows in the shape that type defines, both documented under Table Documentation. type is matched case-sensitively.

importMode selects how the submitted rows meet the stored ones; omitting it selects update:

update

Update only existing rows.

upsert

Update existing rows and add new ones.

replace

Replace the stored table with the submitted one.

payload.json
{
    "tables": [
        {
            "type": "sheetMaterial",
            "content": [
                {
                    "identifier": "1.0038",
                    "name": "1.0038",
                    "description": ""
                }
            ]
        }
    ],
    "importMode": "update"
}
curl -X PUT \
     -H 'Authorization: Bearer <license-key>' \
     -H 'X-Database-Uuid: <database-uuid>' \
     --data-binary '@payload.json' \
     'https://wsidb.wsoptics.de/v0/wsi-2/tables'

A successful write is answered with 200 OK and an empty body.

An update the database rejects is answered with the status describing the rejection and a JSON body. message describes the rejection; details is present only for rejections that carry one, in the form POST tables check shows. An error raised before the update reaches the database — a missing or invalid header, an unsupported WSi version, an oversized body — answers plain text, and both shapes are sent as text/plain.

{
    "message": "...",
    "details": {}
}

POST tables check

Check a set of tables without writing them.

POST /v0/<wsi-version>/tables/check

The body is the one PUT tables takes, so the same payload can be checked and then written.

curl -X POST \
     -H 'Authorization: Bearer <license-key>' \
     -H 'X-Database-Uuid: <database-uuid>' \
     --data-binary '@payload.json' \
     'https://wsidb.wsoptics.de/v0/wsi-2/tables/check'

A check that ran is answered 200, whether or not the tables would be accepted. A license that may not write is answered 403, as it is for a write.

{
    "valid": true
}

Where the tables would be rejected, status and message are what the write would have been answered with, and issues is present where the rejection locates one.

{
    "valid": false,
    "status": 400,
    "message": "Database inconsistent",
    "issues": [
        {
            "type": "referredEntryMissing",
            "content": {
                "affectedRowType": "sheetMaterialDensity",
                "affectedRowIndex": 2,
                "affectedColumnIndex": 0,
                "relatedRowType": "sheetMaterial",
                "relatedColumnIndex": 0,
                "referredId": "no-such-material"
            }
        }
    ]
}

Which members content holds follows the type. Rows and columns are given as indices, columns into the columns GET tables schema reports; with replace a row index is the position the row was sent at.

Requires WSi 2.6 or newer; an older version is answered with 400.