Lesson 10
Code Page Here - DynamicSchema.htmlDynamic Quickbase Schema Creation
Create tables, fields, and relationships with the Quickbase REST API, capture the identifiers Quickbase returns, and observe the additional schema that Quickbase creates automatically.
Lesson Objective
Lesson 9 asked Quickbase to describe schema that already existed. Lesson 10 reverses that direction. JavaScript will now send schema instructions to Quickbase and progressively construct two new tables around the existing People training table.
Departments
Department Name
Location
People
Existing training table
Name
Age
Favorite Color
Tasks
Task Name
Due Date
Status
Part 1
Where Lesson 9 Left Us
The Schema Explorer from Lesson 9 taught us how to discover the application's structure instead of hard-coding it. The Code Page could discover the current App DBID, retrieve the application's tables, inspect fields, find Field IDs, and inspect child-side relationship metadata.
Lesson 9
↓
REST API
↓
JavaScript
↓
Inspect existing schema
Lesson 10
↓
REST API
↓
Quickbase
↓
Create new schema
Aha Moment
Metadata becomes an input
Schema metadata is not useful only for documenting an application. Once JavaScript discovers a Table DBID or Field ID, that identifier can become an input to the next API request.
Part 2
Start With the Schema, Not the API
We do not begin by throwing POST requests at Quickbase. First, define the structure that the requests must eventually create.
Departments
├── Department Name
└── Location
│
▼
People
├── Name
├── Age
└── Favorite Color
│
▼
Tasks
├── Task Name
├── Due Date
└── StatusThe important question in this lesson is not merely what a parent or child table is. The important question is what Quickbase physically creates when JavaScript asks Quickbase to construct those relationships.
Part 3
Our API Requests Do Not Create Everything
Creating a Quickbase table is a higher-level schema operation. Quickbase automatically supplies its normal system fields before our code creates a single custom field.
Quickbase Creates Automatically
Date Created
Date Modified
Record ID#
Record Owner
Last Modified By
Our REST Requests Create
Department Name
Location
Relationships add a third provenance category. A relationship operation can cause Quickbase to add a reference field and lookup fields even though our JavaScript never sends separatePOST /fieldsrequests for them.
{
parentTableId: departmentsTableDbid,
foreignKeyField: {
label: "Related Department"
},
lookupFieldIds: [
departmentNameFieldId,
departmentLocationFieldId
]
}We explicitly created earlier
Department Name
Location
Quickbase creates for the relationship
Related Department
Department Name lookup
Location lookup
Aha Moment
One API request can produce several pieces of schema
Quickbase schema is not necessarily a one-to-one representation of your REST calls. One relationship request can cause Quickbase to create supporting fields needed to implement that relationship.
Part 4
Construction Order Matters
A relationship cannot be constructed before the identifiers it depends on exist. Dynamic schema creation therefore becomes a dependency chain between API requests and API responses.
Create Departments
↓
Capture Departments Table DBID
↓
Create Department Name
↓
Capture Field ID
↓
Create Location
↓
Capture Field ID
↓
Discover People Table DBID
↓
Create Departments → PeopleCreate Tasks
↓
Capture Tasks Table DBID
↓
Create Task Name
↓
Create Due Date
↓
Create Status
↓
Capture all Field IDs
↓
Discover People Name Field ID
↓
Create People → TasksAha Moment
An API response becomes the next request's input
The important information from a successful request is often not simply "success." Quickbase returns identifiers that our next request requires.
Part 5
Never Guess an Identifier
During testing, a newly created table reported anextFieldIdvalue that let us predict what the next custom FIDs might be. The prediction happened to be correct.
That is useful for understanding Quickbase behavior. It is not how the application should obtain an identifier.
// Do not do this.
lessonState.departmentNameFieldId = 6;const data = await response.json();
lessonState.departmentNameFieldId = data.id;Aha Moment
Quickbase is authoritative
nextFieldId can help us understand what Quickbase may do next. It does not give JavaScript permission to manufacture the response before Quickbase returns it.
Part 6
Field IDs Are Local to Their Tables
One of the most useful discoveries in the finished schema was that different tables can legitimately contain the same Field ID.
| Table | Field | FID |
|---|---|---|
| Departments | Department Name | 6 |
| People | Name | 6 |
| Tasks | Task Name | 6 |
There is no collision because a Field ID is meaningful in the context of its table. That is why the Code Page retains both Table DBIDs and Field IDs.
Departments / FID 6
People / FID 6
Tasks / FID 6
// Three different fields.Part 7
The Lesson State Object
The Code Page keeps the identifiers it discovers and creates in a JavaScript object. This is more than convenient storage: it represents the dependencies between schema operations.
const lessonState = {
departmentsTableDbid: null,
peopleTableDbid: null,
tasksTableDbid: null,
departmentNameFieldId: null,
departmentLocationFieldId: null,
personNameFieldId: null,
taskNameFieldId: null,
taskDueDateFieldId: null,
taskStatusFieldId: null,
departmentsPeopleRelationshipId: null,
peopleTasksRelationshipId: null,
};Examples of dependencies
departmentsTableDbid is needed before Department fields can be created.
departmentNameFieldId and departmentLocationFieldId are needed before those fields can be requested as lookups.
peopleTableDbid identifies People as the child in the first relationship and as the parent in the second.
Part 8
Quickbase Is the Source of Truth
JavaScript memory disappears when the page reloads. The finished Code Page therefore does not assume that its in-memorylessonStateis authoritative.
PAGE LOAD
↓
Discover App DBID
↓
GET tables
↓
Find People / Departments / Tasks
↓
GET fields
↓
GET relationships
↓
Reconstruct lessonState
↓
Determine completed steps
↓
Enable the next valid actionIf a student closes the browser after completing four steps and returns tomorrow, every JavaScript value begins asnullagain. The page re-reads Quickbase, discovers what actually exists, and reconstructs its progress.
Aha Moment
The authoritative system can rebuild transient client state
Whenever possible, application state should be reconstructed from the authoritative system rather than trusted solely to temporary browser memory. Quickbase itself tells this lesson what has already been built.
Part 9
Status-Aware Construction
The finished Code Page contains six schema-changing actions, but not every action is available at the same time.
Create Departments Table
Create Department Fields
Create Departments → People Relationship
Create Tasks Table
Create Task Fields
Create People → Tasks Relationship
A disabled button means either the action has already been completed or a prerequisite has not yet been satisfied.
Refresh Lesson Status
Refresh is deliberately separate from the six construction steps. It does not mutate the schema. It re-reads Quickbase, reconstructslessonState, recalculates progress, and determines which action is valid next.
Part 10
Step 1 — Create Departments
/v1/tables?appId={APP_DBID}This is the first schema-changing request. The application DBID is discovered from the Quickbase Code Page context rather than hard-coded.
{
name: "Departments",
description: "Departments used in Lesson 10",
singleRecordName: "Department",
pluralRecordName: "Departments"
}The most consequential value returned is the new table'sid:
lessonState.departmentsTableDbid = data.id;Do not reduce the response to a Boolean success flag. Quickbase returns metadata describing the table it just constructed, including properties such as its alias, key field, default sorting, nextFieldId, nextRecordId, storage information, and timestamps.
Part 11
Inspect What Quickbase Already Created
Immediately after Departments is created, Quickbase already has its system fields even though our code has not yet created Department Name or Location.
| Field | Origin |
|---|---|
| Date Created | Quickbase automatic |
| Date Modified | Quickbase automatic |
| Record ID# | Quickbase automatic |
| Record Owner | Quickbase automatic |
| Last Modified By | Quickbase automatic |
| Department Name | Our REST request |
| Location | Our REST request |
Part 12
Step 2 — Create Department Fields
/v1/fields?tableId={TABLE_DBID}{
label: "Department Name",
fieldType: "text",
appearsByDefault: true,
addToForms: true
}{
label: "Location",
fieldType: "text",
appearsByDefault: true,
addToForms: true
}The lesson intentionally creates the two fields with separate requests so each Quickbase response can be inspected independently and each assigned Field ID can be captured.
Part 13
Step 3 — Create Departments → People
The relationship now consumes identifiers produced by the preceding steps. Departments is the parent. People is the child.
/v1/tables/{PEOPLE_CHILD_DBID}/relationship{
parentTableId: lessonState.departmentsTableDbid,
foreignKeyField: {
label: "Related Department"
},
lookupFieldIds: [
lessonState.departmentNameFieldId,
lessonState.departmentLocationFieldId
]
}Watch what happens physically
We request a relationship, a reference-field label, and two parent fields to use as lookups. We do not separately create the relationship helper fields with the field endpoint.
Our request says
Parent = Departments
Child = People
Reference label = Related Department
Look up Department Name + Location
Quickbase builds
Relationship
Related Department reference field
Department Name lookup
Location lookup
Part 14
Why the Relationship Appears From the Child Side
During development, inspecting Departments returned no relationship, even though Departments clearly participated in Departments → People. Inspecting People exposed the relationship.
Departments
│
│ parent
▼
People
│
└── Related Department
reference / foreign-key fieldQuickbase's relationship endpoint is oriented around the child table containing the reference field. Therefore People exposes the Departments → People relationship.
This does not mean Departments is unrelated to People. It means the API representation is centered on the child-side field that physically stores the reference.
Aha Moment
Relationship metadata is child-oriented
The relationship's reference/foreign-key field resides on the child. That is why querying the child table's relationship endpoint exposes the relationship.
Part 15
Steps 4 and 5 — Create Tasks
After Departments → People is verified, the same construction pattern is reused to create Tasks.
/v1/tables?appId={APP_DBID}{
name: "Tasks",
description: "Tasks used in Lesson 10",
singleRecordName: "Task",
pluralRecordName: "Tasks"
}/v1/fields?tableId={TASKS_DBID}| Field | Quickbase field type |
|---|---|
| Task Name | text |
| Due Date | date |
| Status | text-multiple-choice |
properties: {
choices: [
"Not Started",
"In Progress",
"Complete"
],
allowNewChoices: false
}Part 16
Step 6 — Create People → Tasks
The second relationship reverses People's role. People was the child of Departments; now People becomes the parent of Tasks.
/v1/tables/{TASKS_CHILD_DBID}/relationship{
parentTableId: lessonState.peopleTableDbid,
foreignKeyField: {
label: "Related Person"
},
lookupFieldIds: [
lessonState.personNameFieldId
]
}The Code Page discovers the People Name Field ID rather than assuming it is FID 6. Quickbase then creates the relationship support fields in Tasks.
Explicitly created earlier
Task Name
Due Date
Status
Relationship-derived schema
Related Person
People Name lookup
Part 17
JSON Is Part of the Teaching
The JSON output area in the Code Page is not merely debugging output. It deliberately separates what JavaScript requested, what Quickbase returned, and what identifiers JavaScript retained.
{
request: {
method,
endpoint,
payload
},
quickbaseResponse: {
...
},
capturedLessonState: {
...
}
}{
whatOurCodeExplicitlyRequested: {
...
},
whatQuickbaseCreatedForTheRelationship: {
...
},
quickbaseResponse: {
...
},
capturedLessonState: {
...
}
}Questions to ask while reading the output
- What did JavaScript explicitly ask Quickbase to create?
- What additional schema did Quickbase create automatically?
- What metadata did Quickbase return?
- Which identifiers did JavaScript capture for later requests?
Part 18
Final Schema Provenance
The completed schema contains fields from several different origins. Understanding that provenance is one of the central objectives of this lesson.
Departments
Quickbase system
Date Created
Date Modified
Record ID#
Record Owner
Last Modified By
Our API
Department Name
Location
People
Existing training fields
Name
Age
Favorite Color
Relationship-created
Related Department
Lookup fields
Department Name
Department Location
Tasks
Quickbase system
Date Created
Date Modified
Record ID#
Record Owner
Last Modified By
Our API
Task Name
Due Date
Status
Relationship-created
Related Person
Lookup
People Name — verify the exact label in Lesson 9
Part 19
When Is the Lesson Actually Complete?
The last POST returning HTTP 200 is not enough. The Code Page re-inspects Quickbase and declares the lesson complete only when the resulting schema can actually be discovered.
Completion Checklist
✓ People exists
✓ Departments exists
✓ Department fields exist
✓ Departments → People exists
✓ Tasks exists
✓ Task fields exist
✓ People → Tasks exists
Departments
↓
People
↓
TasksPart 20
Verify Everything With Lesson 9
Finish by returning to the Schema Explorer. Lesson 9 and Lesson 10 now form a closed loop: inspect, construct, then inspect again.
Departments
Verify its Table DBID, Department Name, Location, and standard system fields. Remember that the child-oriented relationship endpoint may show no relationship while inspecting Departments itself.
People
Verify Related Department, the Department lookup fields, and the Departments → People relationship. This is the child side of the first relationship.
Tasks
Verify Task Name, Due Date, Status, Related Person, the People lookup, and the People → Tasks relationship.
Lesson 10 Recap
What We Learned
During this lesson, our JavaScript explicitly created tables, ordinary fields, and relationships. Quickbase also created its own required system fields and relationship-derived fields.