# Guide to schemas
No introduction to Apostrophe would be complete without a closer look at schemas! We've already seen some basic uses of schemas, but now it's time to introduce all of the available schema field types, as well as the options that allow you to build up the schema you want.
# Schemas save us time and trouble everywhere
Just to recap, a schema is simply an array of objects that define the fields that will exist for a particular kind of object. Each object in the array describes one field in the schema via type
, name
, label
and other properties.
Schemas don't just power the database on the back end. They also generate friendly user interfaces for creating and editing content in Apostrophe. This is why many projects that are time-consuming when coded from scratch only take half an hour with Apostrophe.
The apostrophe-schemas module provides powerful tools for working with schemas, but 99% of the time we use them automatically by extending apostrophe-pieces, apostrophe-widgets or apostrophe-custom-pages. They can also be used directly in custom projects.
# Building schemas with addFields
and friends
Modules like apostrophe-pieces pass on their addFields
, removeFields
, alterFields
and arrangeFields
options to the compose
method of apostrophe-schemas#compose. And the beautiful thing about compose
is how easy it becomes to create the schema you want, adding fields here, removing fields there and arranging them into tabs to suit your needs.
addFields
is simply an array of field definitions as seen below; if a field appears more than once, the later definition wins.
removeFields
is an array of fields to be removed. It is processed after addFields
.
alterFields
should be a function accepting a schema
array as its sole argument. alterFields
should modify the schema
array, rather than returning a value. It is rarely used.
# arrangeFields: grouping fields together in the interface as tabs
arrangeFields
groups fields together. The result is typically displayed as tabs. For example, here is the default arrangeFields
setting for all docs:
[
{
name: 'basics',
label: 'Basics',
fields: [ 'title', 'slug', 'published', 'tags' ]
},
{
name: 'permissions',
label: 'Permissions',
fields: [ 'loginRequired', '_viewUsers', '_viewGroups', '_editUsers', '_editGroups' ],
last: true
}
]
If the same group is defined more than once with arrangeFields
, the last definition wins.
If a group is defined twice, the last definition wins, and the group moves to the end.
However, if a group was defined with the last: true
flag, it remains below any other groups unless it appears again without the flag.
This makes it easy to arrange and then re-arrange the groups in subclasses without rearranging everything.
# Using beforeConstruct
to adjust schemas
When you create a new module that extends apostrophe-pieces at the project level, you will often use these options directly.
But when you're working on a module that other people will extend, you need a little more nuance. You want to configure the schema your way, then honor their settings so that everything is gracefully added to your work.
The beforeConstruct
function of your module is a great place to do this. For example:
// lib/modules/products/index.js
module.exports = {
extend: 'apostrophe-pieces',
name: 'product',
beforeConstruct: function(self, options) {
options.addFields = [
{
label: 'Price',
name: 'price',
type: 'float',
required: true
}
// If someone is extending or configuring this module,
// append their fields to ours
].concat(options.addFields || [])
}
};
The same technique works for the other options.
# Guide to schema field types
You can find a list of all Schema Field Types and a detailed reference for each of them in the Schema Field Type Reference, and a list of related properties in the Schema Property Reference. You can also learn how to create custom schema field types in How Do I Create a Custom Schema Field Type?.