Management SDK
The GraphCMS Management SDK enables developers to make schema changes programmatically, using migration scripts. Combined with Environments, this allows an effective way to work on schema iterations. Use the SDK standalone in your development environment or integrate it into your CI/CD pipeline.
With the Management SDK, any schema change can now be automated with a dedicated migration script. This allows for quick schema syncs between environments and a better workflow for staging scenarios, from creating new models to adding new locales and editing existing fields. Whenever a feature-branch in your application gets merged, you are able to run the migrations scripts right in your CI/CD pipeline to ensure a fully automated release flow.
The created scripts can later be re-used on other environments and also give a revision history about performed schema changes.
Requirements
In order to use the SDK, there are a couple of things that are needed beforehand:
- A Permanent Auth Token with Management API access
- The Management SDK from NPM
Retrieving the PAT for Management API access
To set up a token, head into the Settings of your project and go to the section called "API Access". Scroll down to "Permanent Auth Tokens". Here you choose a name for your token, assign the Content API Permissions and then toggle the checkbox "Allow token to be used for the Management API and SDK".
Create the token and click "Copy" after it got created.
Installation
The Management SDK is currently available on NPM, as well as up to date documentation, and changelogs.
npm install @graphcms/management # yarn add @graphcms/management
Schema Migrations
Creating a Migration
To create a migration, the following parameters are required:
Authentication Token
authToken
.Can be retrieved from the project settings: Settings > API Access
Environment URL
endpoint
.Can be retrieved from the project settings: Settings > Environments
Migration Name
name
[optional].Every migration has a unique name. If unspecified, a name would be generated and will be part of the response of a successful migration.
Subsequent migrations with same name will fail.
const { newMigration } = require('@graphcms/management');const migration = newMigration({authToken: '...',endpoint: '...',name: '...', // optional});
Running a migration
The run
method runs the migration.
By default, migrations run in the background. Passing an optional boolean argument configures the migration to run in the foreground. Foreground behavior polls the GraphCMS migration status for a success or error message. The default background behavior simply initiates the migration but doesn’t wait for a response.
const foreground = true;const { errors, name } = await migration.run(foreground);if (errors) {console.log(errors);}if (name) {console.log(name);}
Dry Run a Migration
A migration can be dry run to preview what changes would be applied.
const changes = migration.dryRun();console.log(changes);
Running a dry run won't apply changes to your schema.
Up and Down Migrations
In software driven migrations, it is common to write “up” migrations where you mutate your data, and a “down” migration where you roll those changes back. This is most commonly used for feature development / testing where removing having to touch the interface would improve the developer workflow and the down migration cleans up after yourself, reducing the chances of naming collisions in the database.
This is typically done by creating two functions called “up” and “down”, where creation/mutation statements reside in the up function and deletion methods reside in the down function.
const { newMigration, FieldType } = require('@graphcms/management');// Create a function that would remove all created models & fields in upconst down = () => {const migration = newMigration({authToken: '...',endpoint: '...',});migration.deleteModel('Author');return migration;};// The actual migration that should be performedconst up = () => {const migration = newMigration({authToken: '...',endpoint: '...',});// Create the Author modelmigration.createModel({apiId: 'Author',apiIdPlural: 'Authors',displayName: 'Author',})// Add a required name field.addSimpleField({apiId: 'name',displayName: 'Name',isRequired: true,type: FieldType.String,});return migration;};
Available Schema Migrations
The SDK supports schema migrations on the following entities:
- Models
- Fields
- Enumerations
- Locales
- Content Stages
- Remote Fields
All operations are documented in details on npm.
Example Migration
An example migration script might look like the following. The authToken
needs to be replaced with the token we just created, and the endpoint
of you environment can be retrieved from "Settings" -> "Environments".
const { newMigration, FieldType } = require('@graphcms/management');// create a new migration for an environment// using auth token and environment endpoint url.const migration = newMigration({ authToken: '...', endpoint: '...' });// create modelconst author = migration.createModel({apiId: 'Author',apiIdPlural: 'Authors',displayName: 'Author',});// add fieldsauthor.addSimpleField({apiId: 'firstName',displayName: 'First Name',type: FieldType.String,});author.addSimpleField({apiId: 'lastName',displayName: 'Last Name',type: FieldType.String,});// run migrationmigration.run();
Creating Remote Fields
Remote fields are custom resolver entry points for your schema. They allow external data sourcing from third party web services and accept field values from other GraphCMS fields as arguments.
Remote fields are composed of two parts. First you need to define the returning type that will come from the remote resolve and then you need to define the resolver parameters.
Remote fields are available to Enterprise plans. Upgrade your plan.
The following conditions apply when using remote fields:
- Remote Fields cannot be Required.
- Remote Fields cannot be Unique.
- Any query with at least one remote field will not be cached.
- Remote Fields are currently hidden by default in the content editor form.
- Remote Fields cannot currently be queried as part of a Union Type relation.
Remote Field Resolver
Remote resolvers execute a HTTP request given the provided parameters. Remote resolvers have a default timeout of 500ms and can return a limit of 8kb of data. If the data errors or returns empty, the fields will return null which is consistent for type safe systems.
const { newMigration } = require('@graphcms/management');const migration = newMigration({ authToken: '...', endpoint: '...' });const modelApiId = 'Product';migration.model(modelApiId).addRemoteField({apiId: '…',displayName: '…',remoteConfig: {method: 'GET',payloadFieldApiIds: [...payloadIds],returnType: '…',url: '…',},});
Root Level Configuration
Key | Type | Description |
---|---|---|
apiId | String! | Name of the API ID to be exposed. |
displayName | String! | Display name for the Content Editor. |
remoteConfig | Object! | Config for the remote field, for example url to request. |
Remote Config
Key | Type | Description |
---|---|---|
method | String | One of GET , PUT , or POST . |
payloadFieldApiIds | [String] | Field apiId 's to be automatically appended to GET requests as query params. |
returnType | String | The return type from the resolver. |
url | String | The url to make the request. Supports string interpolation |
headers | Object | Object of any valid header value written in key, array syntax. For example: Accept: ["application/json"] |
Both headers and urls accept a replacer syntax for string interpolation. The url value of https://shop.com/product/{sku}
would pass the corresponding value for the apiId
of sku
into the url string.
Return Types
Key | Type | Description |
---|---|---|
Valid GraphQL Scalar | String | ID, String, Boolean, Int, Float. |
Custom GraphCMS Scalar | String | Long, Json, DateTime, Date, Location. |
GraphCMS Type | String | Color, Location, RichText. |
Custom Type | String | A custom type defined by you. |
Custom Type Definition
Custom types are defined as a string that evaluates to valid GraphQL SDL Syntax.
const { newMigration } = require('@graphcms/management');const migration = newMigration({ authToken: '...', endpoint: '...' });migration.createRemoteTypeDefinition({definition: 'type ExampleType { name: String, age: Int }',displayName: 'Example Type Name',description: 'An example type for use with examples.',});migration.run();
These can be combined to reference multiple levels of data depth.
const { newMigration } = require('@graphcms/management');const migration = newMigration({ authToken: '...', endpoint: '...' });migration.createRemoteTypeDefinition({definition: 'type ComplexExampleType { name: String, example: ExampleType }',displayName: 'Complex Example Type Name',description: 'A complex example type referencing another custom type.',});migration.run();