Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
151 lines (119 sloc) 4.53 KB
title
Schemas & Collections

The role of the schema is to serve as a central source of truth that will be used to generate or populate many of Vulcan's other components.

/images/vulcan-schemas.svg

Based on your schema, Vulcan can:

Example

Here is a schema example, taken from the Movies tutorial:

const schema = {
  // default properties

  _id: {
    type: String,
    optional: true,
    viewableBy: ["guests"]
  },
  createdAt: {
    type: Date,
    optional: true,
    viewableBy: ["guests"],
    onInsert: (document, currentUser) => {
      return new Date();
    }
  },
  userId: {
    type: String,
    optional: true,
    viewableBy: ["guests"],
    resolveAs: {
      fieldName: "user",
      type: "User",
      resolver: (movie, args, context) => {
        return context.Users.findOne(
          { _id: movie.userId },
          {
            fields: context.Users.getViewableFields(
              context.currentUser,
              context.Users
            )
          }
        );
      },
      addOriginalField: true
    }
  },

  // custom properties

  name: {
    label: "Name",
    type: String,
    optional: true,
    viewableBy: ["guests"],
    insertableBy: ["members"],
    editableBy: ["members"]
  },
  year: {
    label: "Year",
    type: String,
    optional: true,
    viewableBy: ["guests"],
    insertableBy: ["members"],
    editableBy: ["members"]
  },
  review: {
    label: "Review",
    type: String,
    optional: true,
    control: "textarea",
    viewableBy: ["guests"],
    insertableBy: ["members"],
    editableBy: ["members"]
  }
};

As you can see, a schema is a JavaScript object containing a list of fields, each of which is defined using a range of special properties.

Creating Collections

Vulcan features a number of helpers to make setting up your layer faster, most of which are initialized through the createCollection function:

const Movies = createCollection({
  collectionName: "movies",

  typeName: "Movie",

  schema,

  resolvers,

  mutations
});

The function takes the following arguments:

  • collectionName: the name of the collection throughout your app (will be lowercased in your MongoDB database).
  • dbCollectionName: if you want to use a different name in your database you can specify it here.
  • typeName: the name of the GraphQL type that will be generated for the collection.
  • schema, resolvers, mutations: see below.
  • generateGraphQLSchema: whether to use the objects passed above to automatically generate the GraphQL schema or not (defaults to true).

Alternative Approach

Passing a schema, a resolver, and a mutation to createCollection enables a lot of Vulcan's internal synergy. That being said, you can also set generateGraphQLSchema to false and use the custom schemas, custom resolvers, and custom mutations utilities documented below to bypass this if you prefer.

Extending Schemas

Sometimes, you'll want to extend an existing schema. For example Vulcan's Forum example has three main collections: Posts, Users, and Comments. Each of them has a pre-set schema, but that schema can also be extended with custom fields.

This is how the vulcan:newsletter package extends the Posts schema with a scheduledAt property that keeps track of when a post was sent out as part of an email newsletter:

Posts.addField({
  fieldName: "scheduledAt",
  fieldSchema: {
    type: Date,
    optional: true
  }
});

The collection.addField() function takes either a field object, or an array of fields. Each field has a fieldName property, and a fieldSchema property.

Each field schema supports all of the SimpleSchema properties, such as type, optional, etc.

A few special properties (viewableBy, insertableBy, editableBy, control, and order) are also supported by the Forms package.

You can also remove a field by calling collection.removeField(fieldName). For example:

Posts.removeField("scheduledAt");