Mozaik

Content type schema migration

Learn how to use the schema migration tool to make the developer experience more streamlined

Written by Peter Balazs

Last updated: 12/09/2018

Content type schema migration is a powerful tool for allowing developers to treat a project's content type schema as code. As a developer, you can define your content type schema with the standard GraphQL schema definition language and keep this file in your source code repository. As your project evolves, you can change the schema definition file, and Mozaik handles the migration.

In this guide, we'll walk through how to set up a new project using the Mozaik CLI tool, import the initial schema, and how to apply changes later on.

First, if you haven't already, you need to sign up and create a new workspace in Mozaik. At the project type step, select the Create empty project. When it's done, you'll find yourself on your new project dashboard. Open the Access Tokens page from the left-hand menu, and create a new token. You can select different scopes for an access token, for this example let's add all four (for making schema changes you will need the project read and project write scopes at least).

After this, we can switch to the command line. You will need to create Node.js project. When you have your project set up, you need to install the Mozaik SDK and CLI tool from NPM. You can do this by running one of the following commands: npm install @mozaikio/sdk --save-dev or yarn add @mozaikio/sdk -D. (You can also install it as a global package but we think it's better to install every package locally.) Once it's installed, let's add the following line to the package.json scripts: "mozaikio": "mozaikio". After this, you will be able to run the CLI by npm run mozaikio or yarn mozaikio. (In the rest of the document we use only the yarn command for simplicity, but every command can be run by npm as well.)

There are two files that the CLI tool needs to be able to communicate with the API: a .mozaikrc file that contains the project API endpoint and the access token. You also need a mozaik-schema.graphql file that contains your content type schema definition.

Let's create these files by running yarn mozaikio init

Update the .mozaikrc file with your project API endpoint and the access token you've created previously. And update the mozaikio-schema.graphql file with the following code:

"""
Author content type
"""
type Author {
  name: SinglelineText
  avatar: Image
}

"""
Homepage content type
"""
type Homepage @singleton {
  title: SinglelineText @config(label: "Site title")
  tagline: MultilineText @config(label: "Site tagline")
  topPosts: [Post] @config(label: "Top 5 posts")
}

"""
Post content type
"""
type Post {
  title: SinglelineText @config(label: "Title")
  lead: MultilineText @config(label: "Lead")
  postContent: RichText @config(label: "Content")
  headerImage: Image @config(label: "Cover image" groupName: "Settings")
  postAuthor: Author @config(label: "Author" groupName: "Settings")
  tags: [SinglelineText] @config(label: "Tags" groupName: "Meta")
  socialMediaInfo: SocialMetaTags @config(label: "Tags" groupName: "Meta")
}

"""
Social media meta tags
"""
type SocialMetaTags @embeddable {
  twitterImage: Image @config(label: "Twitter card image")
  twitterAccount: SinglelineText @config(label: "Twitter account")
}

Now, everything is set up, so can start setting up our project. There are 4 commands for managing the schema. All commands starts with yarn mozaikio schema and you need to add one of the following subcommands:

  • import - Import a schema from the mozaikio-schema.graphql file. It only works when there is no content type in the project
  • export - Export the existing project schema to the mozaikio-schema.graphql file
  • diff - Compares the local and remote schemas
  • apply - Applies the local schema changes to the remote schema

Since your project is empty, let's run yarn mozaikio schema import

If you go to the Content types page in the Mozaik app, you can see all the content types are there. And you can start adding new documents. Let's create one of each document type. (You don't need to fill in all the fields, just create draft documents)

Now you have a project with a content type, some documents, everything is well. However, there is a new requirement that says that an email address must be added to the Author.

You can update the schema with the new email field:

"""
Author content type
"""
type Author {
  name: SinglelineText
  avatar: Image
  email: String
}

"""
Homepage content type
"""
type Homepage @singleton {
  title: SinglelineText @config(label: "Site title")
  tagline: MultilineText @config(label: "Site tagline")
  topPosts: [Post] @config(label: "Top 5 posts")
}

"""
Post content type
"""
type Post {
  title: SinglelineText @config(label: "Title")
  lead: MultilineText @config(label: "Lead")
  postContent: RichText @config(label: "Content")
  headerImage: Image @config(label: "Cover image" groupName: "Settings")
  postAuthor: Author @config(label: "Author" groupName: "Settings")
  tags: [SinglelineText] @config(label: "Tags" groupName: "Meta")
  socialMediaInfo: SocialMetaTags @config(label: "Tags" groupName: "Meta")
}

"""
Social media meta tags
"""
type SocialMetaTags @embeddable {
  twitterImage: Image @config(label: "Twitter card image")
  twitterAccount: SinglelineText @config(label: "Twitter account")
}

And you can verify the changes by running yarn mozaikio schema diff

If you want to apply the changes you can run yarn mozaikio schema apply

After confirming that you accept the changes, Mozaik will run the migration.

Breaking changes and warnings

One of the main concepts behind GraphQL is that you always evolve your schema without introducing breaking changes. A breaking change can be deleting a content type, removing a field from a content type, and so on. If you make a breaking change in your schema, Mozaik will refuse to apply those changes and will show some information on how you can resolve them.

Just for an example let's remove the socialMediaInfo field from the Post content type, and delete the whole SocialMetaTags content type:

"""
Author content type
"""
type Author {
  name: SinglelineText
  avatar: Image
  email: String
}

"""
Homepage content type
"""
type Homepage @singleton {
  title: SinglelineText @config(label: "Site title")
  tagline: MultilineText @config(label: "Site tagline")
  topPosts: [Post] @config(label: "Top 5 posts")
}

"""
Post content type
"""
type Post {
  title: SinglelineText @config(label: "Title")
  lead: MultilineText @config(label: "Lead")
  postContent: RichText @config(label: "Content")
  headerImage: Image @config(label: "Cover image" groupName: "Settings")
  postAuthor: Author @config(label: "Author" groupName: "Settings")
  tags: [SinglelineText] @config(label: "Tags" groupName: "Meta")
}

Now, if you run yarn mozaikio schema apply you will get the following error

And that's it. With a few simple steps, you can manage and track your content type schema changes painlessly.