Fields
What is a field?
A field refers to a specific attribute or variable that is part of a model's structure. It is a characteristic or property that describes an aspect of the model's subject matter. Fields are used to define the structure and content of the model, and they can represent different types of information.
For example take a model for a Customer
entity in an e-commerce system. The Customer
model represents the information related to a customer, such as their name and date of birth. In this case, each of these attributes represents a field in the Customer model.
Here's an example representation of a Customer model with its fields:
Customer Model:
Field 1: Name (field type: string) - stores the customer's full name.
Field 2: Date of Birth (field type: date/time) - stores the customer's birth date.
Field defaults
In Gadget, you can set a default value for most field types in the Schema Editor. This default value will be used when creating a record if no specific value is provided. You can modify the default value anytime, but the change will only affect new records created afterward.
Types of fields
String field
A string field stores an arbitrary length string with UTF-8 encoding.
Number field
A number field stores a numerical value, optionally with a certain precision. Used to store both integers, floats, and arbitrary precision values.
Enum field
A enum field stores one string or a list of strings picked from a global list of allowed values. Can also be configured to accept any string as a valid input. Similar to an enum in traditional SQL databases.
Rich text field
A rich text field stores an enhanced-Markdown formatted string. Can produce formatted HTML for the markdown.
Boolean field
A boolean field stores a true or false value.
Date/time field
A date / time field stores a date or date and time value with a timezone. Accepts and serves data as an ISO-8601 string. Fields configured to not include time will ignore the time / timezone portion of input strings.
JSON field
A json field stores any JSON value. Any valid JSON is accepted.
Color field
A color field stores a hexadecimal representation of a color.
Email field
A email field stores an email as a string.
File field
A file field stores a file, like an image or a PDF, in cloud storage. See Storing files for more information.
URL field
A url field stores a URL as a string.
Vector field
The vector field can be used to store and retrieve vectors, as well as for sorting and filtering by distance between vectors. Vector similarity is most often used to implement semantic search in a database powering an AI application.
See the building AI apps guide for instructions on using the vector, and see the Vector Sorting and Vector Filtering sections of the API Reference for more information.
Password field
A password field is stored in your app's database using bcrypt, which is a widely adopted one-way password hashing algorithm. Once stored, password values cannot be retrieved. Instead, during login attempts, incoming passwords are compared against the stored hashed value to determine if the user entered the correct password. Password fields are commonly used for securely storing user authentication information such as passwords or tokens that should never be seen in cleartext again.
Encrypted string field
encrypted string fields in Gadget use two-way encryption with tweetnacl to store sensitive values in the database. These encrypted values can be stored and retrieved as long as the user has access to the record. They are particularly useful for storing access tokens or API keys that need to be retrievable but require additional security measures to protect their value.
Record state field
Some Gadget models include a record state field that stores a specific status for each record. While using record state for implementing business logic is optional, it can be a useful way to determine permissions and actions.
Rather than relying on generic operations like create, update, and delete, Gadget allows you to define specific and meaningful actions such as publish, fulfill, or complete. Each action can transition a record from one state to another. For example, publishing a record may move it from the Unpublished state to the Published state, while completing a task can move it from Not Started or Doing to Done.
The record state field holds the current state of each record. The field configuration panel defines the available states for this field.
System field
Each model in Gadget has three fields managed by the Gadget platform that is necessary for Gadget to function. These fields are:
ID
: This field captures a unique ID for each of your records within a table
Gadget will automatically handle ID assignments. To ensure performance and stability, Gadget auto-increments IDs on every new mutation regardless of the status of the mutation. As a result, your saved records will always have a unique ID, but the IDs are not guaranteed to be sequential. As an example, your IDs may increment from 11 to 13, as the mutation to create the 12th record failed.
Created At
: This field captures the timestamp at record creationUpdated At
: This field captures the timestamp of the last event which changed the record
System fields cannot be given a different name / API identifier.
Computed field
Produces a value according to a Gelly code snippet using other field values.
For more infromation, see our computed fields guide
Validations
In Gadget, a validation is an extension of field component of a model that helps prevent the entry of malformed or inconsistent data into your system. When modifying records, Gadget verifies that any new data satisfies the validations defined for each field. If an action attempts to write invalid data, it will be unsuccessful, and the invalid data will not be saved.
When making API calls to write data, Gadget provides structured error messages that clearly indicate what data was invalid. These error messages can be presented directly to users, helping guide them in correcting the problematic data.
Validations play a crucial role in maintaining data integrity and ensuring that only valid and coherent data is stored in your system. They serve as a safeguard against incorrect or incompatible data and facilitate a smooth user experience by providing clear feedback on data entry errors.
Applicable validations to field types
Gadget offers a selection of common validations for each field type. These vary from one field type to another:
Field type | Applicable Validations |
---|---|
string | Required , Uniqueness , String Length Range , Run Code Snippet , RegExp Pattern |
number | Required , Uniqueness , Number Min/Max Range , Run Code Snippet |
id | No applicable validations |
enum | Required , Uniqueness , Run Code Snippet |
rich text | Required , Uniqueness , String Length Range , Run Code Snippet , RegExp Pattern |
boolean | Required , Uniqueness , Run Code Snippet |
date / time | Required , Uniqueness , Run Code Snippet , RegExp Pattern , |
Required , Uniqueness , String Length Range , Run Code Snippet , RegExp Pattern | |
url | Required , Uniqueness , String Length Range , Run Code Snippet , RegExp Pattern |
file | Required , File Size Range , Image File , Run Code Snippet |
color | Required , Run Code Snippet , Color |
json | Required , Uniqueness , Run Code Snippet |
vector | Required , Uniqueness , Vector Dimensions , Run Code Snippet |
password | No applicable validations |
encrypted string | No applicable validations |
role list | No applicable validations |
computed | No applicable validations |
Required validation
A required validation refers to the process of ensuring that a particular input or data field is not empty or null when it is required to have a value. It is a form of data validation that checks whether a user has provided the necessary information before proceeding with a certain operation or action.
Uniqueness validation
The Uniqueness
validation in Gadget ensures that each value for a field occurs only once in the database. It is commonly used for fields like email or username to guarantee that each value is unique within the system.
Underlying database constraints are leveraged to enforce the uniqueness validation reliably, even in transactional contexts and under load.
If a Uniqueness
validation is added to a model that already contains data, the setup may fail if there are duplicate values for the field. In such cases, the uniqueness constraint is not enforced until the duplicate data is corrected by either deleting records or modifying the field values to ensure uniqueness. Once the data is made unique, the validation can be re-added and verified to succeed.
The Uniqueness
validation can be configured as case-sensitive or case-insensitive by toggling the Case Sensitive option. When the option is disabled, values are considered duplicates regardless of letter casing. This is useful for scenarios like URL slugs or emails, where users may enter values with different casing but uniqueness should be maintained regardless of casing.
Number Min/Max range validation
Number min/max range validation ensures whether a numeric value falls within a specified range of minimum and maximum values. It is commonly used to ensure that numeric input or data meets certain constraints or requirements.
String length range validation
String length range validation is a type of data validation that ensures whether a string has a specific length or falls within a certain range of lengths. It is commonly used to enforce length restrictions or requirements on user input or data fields
Image validation
The Image File
validation ensures that uploaded files meet three criteria:
- They have an
image
based MIME type or subtype — see MDN's reference. - They are in one of the following image file formats:
gif
,jpg
,png
,svg
, orwebp
(common web formats);apng
,bmp
,bpg
,cr2
,cur
,dcm
,flif
,heic
,ico
,jp2
,jpm
,jpx
,jxr
,psd
, ortif
(additional formats). - They do not contain an animation if the Allow animated images option is disabled.
File size range validation
File size range validation ensures the size of a file falls within a specified range of acceptable sizes. It is commonly used when handling file uploads or processing files in applications. By validating the file size, you can control resource consumption, prevent server overload, and maintain data integrity.
Color Validation
Color validation ensures whether a given value represents a valid color. It is typically used to ensure that color values provided by users or within a system adhere to a specific format or range of valid colors.
Vector dimension validation
The Vector dimensions validation in Gadget ensures that all vectors stored in a field have the same count of dimensions.
It's important to note that Gadget restricts sorting or filtering of vectors unless all the stored vectors and input vectors have the same dimension count. This is because many vector operations used in Gadget are not defined for vectors with different dimensions.
To enforce the consistency of vector dimensions, you can add a Vector dimensions validation to a field. This validation ensures that all vectors stored in the field have the same number of dimensions.
For more details about this validation and any related errors, you can refer to the GGT_DIFFERENT_VECTOR_DIMENSIONS error in the Gadget documentation.
RegEx pattern validation
RegExp also known as regular expression pattern validation, is used to validate strings or data against a specific pattern or format using regular expressions. Regular expressions (RegEx) are sequences of characters that define a search pattern, allowing for powerful and flexible pattern matching and validation.
Gadget uses the RegExp engine built into node.js to run RegExp Pattern validations. For information on how to write JavaScript regular expressions, please refer to MDN's reference.
Run code (custom) validation
In Gadget you can add your own custom validations written in JavaScript. The Run Code validation runs a JS function each time a record is created or updated to check if that change should succeed. If the function reports no errors, then the save will complete, and if the data is somehow invalid, the validation can add structured error messages to the different fields of the record being changed.
Each Run Code validation file must export a function as the default export function from the module. The function can be marked async
or return a Promise
. The function shouldn't return anything and, instead, should add errors to any fields determined to be invalid using the passed-in errors
object. The errors
object is an Errors
that holds a structured set of errors keyed by field.
By convention, Run Code validations are placed in a root-level folder named after the model and then in the validations
folder. For a model named Widget
, for example, the Gadget editor will suggest you add the first validation at widget/validations/some-useful-code.js
. You can move or rename these files however you wish.
Validation functions get passed one big context object and not individual arguments. This is because there are a lot of arguments
you may or may not need. Most Gadget users use JavaScript destructuring to pull out just the context keys that they need. The most common
keys used from the context are the record itself at the record
key, the api
object, which is an already set up instance of the
JavaScript client for the application at api
, and the Errors
object at the errors
key.
Here's a custom validation that tests if a record's full name is not null and its last name is also not null:
module.exports = async ({ record, errors }) => {if (record.firstName && !record.lastName) {errors.add("lastName", "must be set if the first name is set");}};
Here's a validation that tests if a record's phone number is valid:
1const PhoneNumber = require("awesome-phonenumber");2module.exports = async ({ record, errors }) => {3 const number = new PhoneNumber(record["customerPhoneNumber"]);4 if (!number.isValid()) {5 errors.add("customerPhoneNumber", "is not a valid phone number");6 }7};
If a validation function throws an error while executing, the action validating the current record will fail, and its effects wil roll back.