Is there an example of uploading a graphql schema with POST using node request or axios instead of Curl?

I am looking to do something similar to the curl schema upload in the docs:
curl -X POST localhost:8080/admin/schema --data-binary '@schema.graphql'

but Instead doing it within a Node program. I would much prefer to use something like Request or Axios as opposed to running a exec for curl within the node program. I know you can update the schema using graphql but I would prefer not to instantiate a graphql client just for this. I am currently trying using axios, which does not produce an error but does not update the schema correctly. The typeArray is created through graphql-tools schema loading and is an array of graphql schema strings and if I just write the result to a .graphql file and then curl it to dgraph it works fine.

axios.post('http://localhost:8080/admin/schema', {
      data: typesArray.join(),
    })

I’m not 100% sure, cuz I’m not using GraphQL everyday. But I think it should be something like

axios({
   url: 'http://localhost:8080/admin',
   method: 'post',
   data: {
    query: `mutation{
     createGQLSchema(schema: "${someString}"){
      schema
     }
    }`
   }
  })
   .then(res => {
    console.log(res.data);
   })
   .catch(err => {
    console.log(err.message);
   });

As the injection of the Schema is a mutation you should follow that logic. The curl method is different.

Admin Schema

	type GQLSchema @dgraph(type: "dgraph.graphql") {
		id: ID!

		"""
		Input schema (GraphQL types) that was used in the latest schema update.
		"""
		schema: String!  @dgraph(pred: "dgraph.graphql.schema")

		"""
		The GraphQL schema that was generated from the 'schema' field.
		This is the schema that is being served by Dgraph at /graphql.
		"""
		generatedSchema: String!
	}

Makes sense thank you. I am trying to determine what error I am getting back from this method but the details are sparse.

{
  errors: [ { message: 'Unexpected <Invalid>', locations: [Array] } ],
  extensions: {
    tracing: {
      version: 1,
      startTime: '2021-06-01T20:52:27.3192885Z',
      endTime: '2021-06-01T20:52:27.3193752Z',
      duration: 86900
    }
  }
}

No logs on the dgraph side

I attempted to update based upon the example found here:
https://dgraph.io/docs/graphql/admin/

which looks like this:

axios({
      url: 'http://localhost:8080/admin',
      method: 'post',
      data: {
        query: `mutation {
          updateGQLSchema(
            input: { set: { schema: "type Person { name: String }"}})
          {
            gqlSchema {
              schema
              generatedSchema
            }
          }
        }`,
      },
    })

This seemed to work

However, adding the @key or @id directive to allow apollo federation like so:

axios({
      url: 'http://localhost:8080/admin',
      method: 'post',
      data: {
        query: `mutation {
          updateGQLSchema(
            input: { set: { schema: "type Person @key(fields: 'name') { name: String }"}})
          {
            gqlSchema {
              schema
              generatedSchema
            }
          }
        }`,
      },
    })

results in an error:

{
  errors: [
    {
      message: 'resolving updateGQLSchema failed because input:1: Unexpected <Invalid>\n',
      locations: [Array]
    }
  ],
  data: { updateGQLSchema: null },
  extensions: {
    tracing: {
      version: 1,
      startTime: '2021-06-01T21:03:03.7351175Z',
      endTime: '2021-06-01T21:03:03.7358707Z',
      duration: 753100
    }
  }
}

Here is what is currently working for us using fetch. There would be less need to convert to/from json with axios in general, but we also had to convert the schema.toString() before pushing it. We don’t have any @key fields, but we do have other directives and this is working for us. Maybe this will help get you going.


const updateSchemaQuery = `mutation($schema: String!) {
  updateGQLSchema(input: { set: { schema: $schema } }) {
    gqlSchema {
      schema
    }
  }
}
`
async function pushSchema() {
  // try {
  const data = await fs.promises.readFile('./src/schema.graphql', 'utf8')
  const schema = data.toString()

  const response = await fetch(`https://YOUR-ENDPOINT.us-west-2.aws.cloud.dgraph.io/admin`, {
    headers: {
      'Content-Type': 'application/json',
      'X-Auth-Token': 'XXXXX',
    },
    method: 'POST',
    body: JSON.stringify({
      query: updateSchemaQuery,
      variables: {
        schema: schema,
      },
    }),
  })
  console.log(response.statusText)
  
  const json = await response.json()
  
  if (json.errors) {
    json.errors.forEach((error) => console.log(error.message, error.locations))
    console.error(json.errors)
    throw JSON.stringify(json.errors)
  }
  //console.log(json)
  return json
}

2 Likes

I altered this for my needs and this worked for me I think, thank you!

Adding what the final code looks like for anyone else with the same ?

axios({
      url: 'http://localhost:8080/admin',
      method: 'post',
      data: {
        query: `mutation($schema: String!) {
          updateGQLSchema(input: { set: { schema: $schema } }) {
            gqlSchema {
              schema
            }
          }
        }
        `,
        variables: {
          schema: typesArray.join(),
        },
      },
    })
    .then((res: any) => {
      console.log(res.data)
    })
    .catch((error: any) => {
      console.log(JSON.stringify(error))
    })
3 Likes