Many apps need to store persistent data, and most of the time, that data needs to be organized in a structured way. With Data Connect, you model your app data using schemas, and this blog post dives into what schemas are and how to use them.
We’ll use the movie review app example you might already know from the documentation and our previous deep-dive blog posts.
Declaring a Schema
Firebase Data Connect schemas are defined using GraphQL. The key components of GraphQL schema definitions are:
- Type definition
- Table name
@table
directive, which includes the optional arguments of naming convention and key(s)
Here is an example from the movie tracker app:
type Movie @table(name: "Movies", singular: "movie", plural: "movies", key: ["id"])
This line has:
- A
type
type definition, letting GraphQL know this is declaring a type (other examples of type definitions arequery
andmutation
) Movie
as the name of the schema- A directive
@table
which signifies creation of a schema
Within the @table
directive, there are a few optional fields:
name
: defines the table name; by default, the table name is the schema namesingular
: for implicit queries and mutations, this defines the name that gets used in the query / mutation that requires this tableplural
: for implicit mutations, this defines the name that gets used in the mutation that requires this tablekey
: an optional list for the name of the table’s key(s)
By default, the singular naming convention will be the name of the table with a lower case first letter, and the plural one will be the singular with a “s” at the end. You only need to use singular
or plural
to adjust the name if it is different than the default.
Similarly, the key by default will be named id
, and you do not need to declare this when you declare a schema.
Removing all of the defaults, the above declaration can be simplified to:
type Movie @table(name: "Movies")
Anatomy of a Schema
Now that you know how to declare a schema, how does a schema in its entirety look like? It is broken down into the following parts:
- Declaration to create a schema, as described in the previous section
- List of items in the schema
Here is an example schema for movies, written verbosely with all optional fields present except the schema declaration as covered above:
type Movie @table(name: "Movies") @index(fields: [releaseYear, rating], order: [ASC, DESC]) {
id: UUID! @col(name: "movie_id") @default(expr: "uuidV4()")
title: String! @col(name: "title")
releaseYear: Int @col(name: "release_year") @index
genre: String @col(name: "genre", dataType: "varchar(30)")
rating: Int @col(name: "rating")
description: String @col(name: "description")
}
Each line is the name of a column along with the data type of that column. Any data type followed by !
means this attribute is required. Data Connect supports a wide range of data types, some of which are in this code snippet like UUID
, String
, and Int
. UUID is a special data type that indicates that this is a unique ID, which is useful for keys.
We also see @col
, @default
, and @index
directives:
@col
explicitly sets column information, including names and data type. Thegenre
column is named “genre” with the String data type of at most 30 characters. By default, the first word of each line becomes the column name, so you only need@col(name: “...”
if you want a different name.@default
lets you set default values. In the example above, anid
defaults to a UUID generated byuuidV4()
.@index
defines a database index to optimize query performance. To create a single field SQL index, put@index
on a@col
field. You can specifyorder
, but this doesn’t matter much for single field indexes as they can be scanned in both directions. To define a composite index, You can put@index(fields: [...])
on@table
and define an order for each indexed column, defaulted to ASC. Above,releaseYear
would be ordered in ascending order whereasrating
would be ordered in descending order.
Removing all of the defaults, the above can be simplified to:
type Movie @table(name: "Movies") @index(fields: [releaseYear, rating], order: [ASC, DESC]) {
id: UUID! @default(expr: "uuidV4()")
title: String!
releaseYear: Int @index
genre: String @col(dataType: "varchar(30)")
rating: Int
description: String
}
Key Scalars
For databases optimized for speed, key scalars are an efficient way to identify objects. Data Connect automatically assembles these identifiers from key fields in your schemas, and the resulting scalars provide information about data identity and structure, accessible within a single cell. Key use cases include:
- sequential operations: key scalars serve as unique identifiers for new records, simplifying subsequent operations
- relational operations: key scalars provide access to relational keys, enabling more complex data manipulations
Server Values
Sometimes, your app might need server-computed values because the values need to be computed at the time of data creation. You can do this by using server values, where the server dynamically populates fields in your tables using stored or readily-computable values according to particular server-side expressions. For example, you can define a field with a timestamp applied when the field is accessed using the expression createdAt: Timestamp! @default(expr: "request.time")
. This might be used when a user creates their account, so the schema could look like this:
type User @table(key: "uid") {
// other fields
createdAt: Date! @default(expr: "request.time")
}
Relationships Between Tables
A big part of using relational databases is (surprise!): relationships between tables, and Data Connect lets you do that. Here is an in-depth blog post on how to define one-to-one, one-to-many, and many-to-many relationships in your schemas.
Try it out!
Data modeling is a crucial part of any app that requires data, and hopefully this blog post clarifies how to define and use schemas in Data Connect. If you need more information about Data Connect, check out the documentation, and you can also check out other deep-dive articles. As it’s a new product, we’d love to hear your opinion and any feature requests you have as we’re hard at work improving and adding more features to the product. If you haven’t already, give Data Connect a try today - we can’t wait to see what you build with it!