Skip to content

Schema

Before learning about schemas, make sure you’ve read the previous section about The Graph to understand the core concepts like nodes and grefs.

Introduction

The types of nodes that a program exposes in its graph are defined in its schema.

A program’s schema consist of a set of node types with fields that define the available data.

Types can also declare actions which are functions that can be invoked on them, and events which other programs can be subscribed to.

To summarize, a type is made of

FieldsValues that can be queried
ActionsFunctions with side effects
EventsSubscribable notifications

Collectively these are called members.

Editing schemas

Schemas can be edited from the right sidebar and are stored in memconfig.json. You can also edit this file manually when convenient.

Root Type

All schemas must declare a type named Root which defines the type of its root node. The root node serves as the “entry point” into the program, so all grefs are relative to it.

The root node of each program can be referenced using the program’s name followed by a colon:

  • google-calendar:
  • github:
  • slack:

The trailing colon indicates that it’s a gref with no path.

Other nodes are referenced by appending a path. For example, if you had

membrane/github running, these would all be valid grefs:

grefRefers to
github:usersUserCollection
github:users.one(name:'membrane-io')User
github:users.one(name:'lodash').reposRepositoryCollection
github:users.one(name:'lodash').repos.one(name:'lodash')
Repository

Scalars (Primitive types)

Membrane provides a few built-in types for primitives (aka scalars):

  • String
  • Int (a 53-bit signed integer)
  • Float (a single-precision floating point number)
  • Boolean
  • Null
  • Void (used for actions that don’t return anything)

As well as a couple of “type wrappers”:

  • List<T> A list of T values
  • Gref<T> A gref to a node of type T

These two wrappers are essential for implementing pagination in a unified way across all programs and drivers.

Object types

As mentioned above, programs can define their own types with fields, actions and events.

To illustrate this section, we’ll use a simplified PullRequest type from

membrane/github with the following schema:

PullRequest
Fields
id: int
number: Int
title: String
body: String
owner: User
comments: CommentCollection
Actions
merge(message: String): Void
close(message: String): Void
Events
closed: ClosedEvent

Fields

Fields define the data that can be queried from a node.

Fields can be scalars, lists, grefs, or other object types.

Fields can have a corresponding “resolver” function that gets invoked during queries.

We’ll learn more about queries in the Queries section.

Actions

Actions are functions that can be invoked in the context of a graph node.

For example, the type PullRequest in membrane/github declares a merge action which can be invoked on a pull request.

For each action declared in the schema, you must define a corresponding function that gets called when the action is invoked.

We’ll learn more about actions in the Actions section.

Events

Any Membrane program can emit events on their nodes and subscribe to events on nodes of other programs.

For example, the type Issue in membrane/github declares a closed event, which is emitted when a specific issue is closed.

Events can optionally have a pair of corresponding functions called subscribe and unsubscribe that get invoked when the event is subscribed to or unsubscribed from.

We’ll learn more about events in the Events section.