Updating GraphQL schema

Hey,

I’m having problems from time to time when updating a schema. Errors like:

Instance data is not valid.

With, I believe, small changes like adding:

type LoginRes @embedded {
  userToken: String!
  userId: String!
}

And changing:

type Mutation {
  ...
  - loginAUser(data: LoginAUserInput!): String! @resolver(name: "login_auser")
  + loginAUser(data: LoginAUserInput!): LoginRes! @resolver(name: "login_auser")
  ...
}

So, with this I’d just like to ask, what’s the best way to update a schema or how should I go about extending my schema, once it’s in production, without having to restart (create a new DB) from scratch each time?

If overriding the schema is a mandatory part of the workflow, how does this work in production if all the collections, functions are lost? How should I handle this in production?

Also, If creating a new DB is part of the workflow, how do I quickly recreate a DB with all the old data, as to have minimum downtime?

This worries me a bit. Any info is appreciated.

Thanks

Hi, @fillipvt!

The Instance data is not valid. error is being thrown in some identified scenarios. The most common case is when the schema update involves a change in an existing Index. Those errors should be fixed in upcoming releases.

According to your example, it seems that the error should also be thrown if you change the type for a custom Mutation field. I’ve tried reproducing it on my end, but I was not able to do it. Maybe the error is located in some other part of your schema? If you can share more of it, we might be able to track it down!

Regarding the second part of your question, the recommended way to evolve the schema, once in production, is at the moment to use the merge import mode as described here. The override mode was originally meant to use during the development phase. The reason why it deletes all of the database data is to allow a quick iteration on the schema definition while you are still on the early stages of the development process.

Now, we’ve learned from the feedback we’ve received that those two import modes are not enough for covering all of the use cases properly. Because of that, changes on the existing modes and new modes will be released in the future as well.

At the moment, overriding a schema might be necessary for certain cases (e.g., removing elements from your GraphQL schema). So, if you need to override your GraphQL schema, but you don’t want to loose the actual data stored in your database, you can try by manually removing the GraphQL metadata from all of the existing database objects (Database, Collections, Indexes, and Functions).

In order to do so, run the following FQL script from within the database you want to override the schema:

// Remove GraphQL metadata from Collections
Foreach(
  Paginate(Collections()),
    Lambda("ref",
      Update(Var("ref"), {
        "data": {
          "gql": null
        }
      }
    )
  )
);

// Remove GraphQL metadata from Indexes
Foreach(
  Paginate(Indexes()),
    Lambda("ref",
      Update(Var("ref"), {
        "data": {
          "gql": null
        }
      }
    )
  )
);

// Remove GraphQL metadata from Functions
Foreach(
  Paginate(Functions()),
    Lambda("ref",
      Update(Var("ref"), {
        "data": {
          "gql": null
        }
      }
    )
  )
);

NOTE: make sure to adjust the page size parameter as necessary.

Finally, you will need to remove the GraphQL metadata from the database itself. In order to do so, you will need to update the database from its parent database. Make sure to run the following command from the the parent database:

// Remove GraphQL metadata from Database
Update(Database("my-graphl-database"),
  {
    "data": {
      "gql": null
    }
  }
);

In case the database is at your account’s root level (i.e., it not’s contained under any parent database), you will need to run the above command from the shell. Let me know in case you need further instructions in order to do so!

After running all of the queries described above, your database should no longer have any GraphQL metadata associated to it. From then on, you should be able to import a new schema on top of it again as if it were a fresh database.

Hey @lregnier!

Thank you very much for your insights.

After I found the problem when making the post I solved it a bit later by erasing everything and starting from scratch. But, as it happens, I just tried deleting an element from the GraphQL schema and I got the same error: Instance data is not valid

The change I’m trying to do at the moment is deleting one element from a type definition:

type Budget {
    pockets: [Pocket] @relation
    owner: AUser!
    name: String!
    description: String
(-)totalAvailable: Float!
}

But after running all the commands to delete all the GraphQL metadata, as you mentioned, I get an error when trying to import the schema once again:

Instance data is not valid.

Would it be alright to share my schema here? Maybe it is indeed as you say, a problem with my schema, but I’ve been using the same schema when setting up a new DB from scratch, and no error happens there.

Thanks again

This is not an answer, but a commiseration:

I’ve gotten this error in the console for what I thought were very simple changes, only to upload the same schema file via a node script without issue. REALLY don’t know what happened there. I do not have any examples now, but if it happens in the future I will try to share!

2 Likes