Table schema¶
A schema describes one table or collection : the type of every field, how a value is cleaned before it is saved, what makes it invalid, which fields point to other tables. It is a TypeScript file kept with the table in Git, and it is what the schema APIs enforce. The generated APIs never read it.
| Where | API Info → DB API : pick the instance, the database and the table, then the schema editor. Generate writes a first schema from the columns or from the documents of the table. |
| Shape | const schema: ISchemaType = { field: EType.string, other: { __type, validations, conversions, … } } and module.exports = { schema }. |
| Used by | The /api/schema/… APIs : save, master save, update, replace, get with deep, the is valid data for table check. |
| Gives | Validation, conversions, defaults, relations, the TypeScript interface db.<instance>.<database>.I<Table>, the sample payloads of the API testing page and of Swagger. |
1. A schema, field by field¶
- This is the
orderstable of the sample shop every new account gets : open it in the admin panel to see the whole thing with theproducts,customersandorderItemsschemas. - A field is a type alone (
name: EType.string) or an object with__typeand the rules below. A key the schema does not have is refused on save : the error names it. - The examples of the sections below are single fields : paste them inside
const schema: ISchemaType = { … }.
2. Types¶
__type |
Holds | Notes |
|---|---|---|
EType.string |
text | minLength, maxLength, email, enum, trims and case conversions |
EType.number |
numbers | min, max, auto increment |
EType.boolean |
true / false |
|
EType.date |
dates | min, max ; sent and received as ISO strings |
EType.objectId |
MongoDB ObjectId | strings in JSON |
EType.file, EType.files |
uploaded files | the request schema of a custom API, not a table |
- MongoDB documents nest :
address: { city: EType.string }is an embedded object,tags: [EType.string]an array of strings,lines: [{ sku: EType.string, qty: EType.number }]an array of objects. SQL tables are flat.
| Nested documents and arrays (MongoDB) | |
|---|---|
3. Conversions : clean the value first¶
Conversions run before the validations, on save and on update.
| Key | Does |
|---|---|
trim, trimStart, trimEnd |
Removes the spaces around a string. |
toLowerCase, toUpperCase |
Changes the case. |
conversionFun: (value, row) => … |
Your function ; its return value is stored. It runs even when the field is absent from the payload, which is how a updated_at: () => new Date() field is stamped on every save and update. |
defaults |
{ defaultValue } or { defaultFun: () => … } for a field absent from a save or a replace. defaultValue wins over defaultFun. shouldReplaceNullWithDefault and shouldReplaceEmptyStringWithDefault also replace null and "". |
encryption: true |
Stored encrypted with encryptionAlgorithm and secret of the secret, decrypted when read. An object { encryptionAlgorithm, secret, nonce } names other keys of the secret. |
hashing: true |
Stored as an HMAC SHA-256 hash with the nonce (or secret) of the secret : passwords, tax ids. Look a hashed value up with the hash data API. |
| Trim and case | |
|---|---|
| Encrypted and hashed fields | |
|---|---|
4. Validations : refuse a bad value¶
| Key | Refuses | Error type |
|---|---|---|
required: true |
A missing, null or empty value on save. On update, only a null or empty value sent. |
required |
min, max |
A number or a date outside the range. | min, max |
minLength, maxLength |
A string or an array outside the length range. | minLength, maxLength |
email: true |
A string which is not an email address. | emailNotValid |
enum: [ … ] |
A value outside the list. An empty list checks nothing. The sample data generator picks from the list. | enumValidation |
validatorFun: (value, row) => … |
Your function, run last : return true to accept ; return false or a message, or throw, to refuse. |
invalidValue |
unique: true |
A value another row already has, or which appears twice in the same batch. Checked with a query before the write, so prefer a unique index for busy tables (create indexes). | unique |
| required, min and max, minLength and maxLength | |
|---|---|
| email and enum | |
|---|---|
| validatorFun : your own rule, run last | |
|---|---|
| unique : checked with a query before the write | |
|---|---|
- The answer of a refused save is
400with one entry per problem inerrors:{ type, field, message, code, dataIndex },dataIndexbeing the position of the row in an array body. See Error codes.
5. Keys and generated values¶
| Key | Meaning |
|---|---|
isPrimaryKey: true |
The primary key of the table : the id of get by id, update by id, remove by id. |
isAutoIncrementByDB: true |
The database assigns the value (SQL identity columns). API Maker sends nothing for it. |
isAutoIncrementByAM: true or { start, step } |
API Maker assigns the next number, on every database, MongoDB included : see Auto increment. No effect with isAutoIncrementByDB. |
isAutoGenerateByAM: { valueGeneratorType } |
A random id when the payload has none : ObjectID, GUID_UUID, ULID or ShortUUID. Wins over isAutoIncrementByAM. |
isConcurrencyControlField: true |
The version field of optimistic concurrency control. |
6. Relations and virtual fields¶
| Key | Meaning |
|---|---|
collection or table, column |
The table and the column this field points to. database and instance when they differ from the ones of the schema. |
isVirtualField: true |
A field which is not in the table : it is filled from the other table, and can be saved through master save. s_columnVirtualLinker is the column of this table, t_columnVirtualLinker the column of the other table which holds it. |
- Relations feed deep populate (
deepon any get), master save (one call saves the order and its items) and the ER diagram. - A virtual field can not be used in
find: the errorvirtualFieldUsedInFindsays so.
7. Other keys¶
uim: settings of the deprecated UI Maker ; they change nothing at runtime.- A schema file can also export
validations, a list ofSUPER_KEYrules which refuse two rows with the same combination of fields. It is deprecated : create a unique index on the fields instead, it is faster and it holds for writes made outside API Maker too.