I am trying to convert from an introspection query to a GraphQL schema using the npm GraphQL library.
It keeps stating:
devAssert.mjs:7 Uncaught Error: Invalid or incomplete introspection result. Ensure that you are passing "data" property of introspection response and no "errors" was returned alongside: { ... }
Issue is I am getting it directly from GraphiQL Shopify and can't figure out how to validate my introspection return is correct.
Code:
var introspection = `
{
"data": {
"__schema": {
"types": [
{
"name": "Boolean"
},
{
"name": "String"
},
{
"name": "QueryRoot"
},
{
"name": "Job"
},
{
"name": "ID"
},
{
"name": "Node"
},
{
"name": "Order"
}
]
}
},
"extensions": {
"cost": {
"requestedQueryCost": 2,
"actualQueryCost": 2,
"throttleStatus": {
"maximumAvailable": 1000,
"currentlyAvailable": 980,
"restoreRate": 50
}
}
}
}`;
let schema = buildClientSchema(introspection);
//console.log(schema.printSchema());
I thought the introspection result could be a string? Or is there not enough info to build a schema? Do I need to expand the number of fields? What's the bare minimum needed to exchange an introspection result into a schema?
You should use getIntrospectionQuery to get the complete introspection query needed. If the response you're working with is a string, it should then be parsed to an object before being passed to buildClientSchema -- the function accepts an object, not a string.
Here's an example directly querying a schema using the graphql function -- you'll need to modify it based on how you're actually executing the query.
const { getIntrospectionQuery, buildClientSchema, graphql } = require('graphql')
const schema = new GraphQLSchema(...)
const source = getIntrospectionQuery()
const { data } = await graphql({ source, schema })
const clientSchema = buildClientSchema(data)
Make sure that you are only passing in the data portion of the response. The object you pass in should look like this:
{
__schema: {
// ...more properties
}
}
Related
I have a simple question today.
I retrieve data from my firebase database:
const response = await fetch('For pricacy purpose I replaced this link to my firebase database.');
const resData = await response.json();
console.log(resData);
Also I log the results in the console, the following text is what I retrieve:
Object {
"-MPOg49jvG-md0twgj-D": Object {
"id": 1,
},
"-MPTgHoTXzIcY_KpBHkc": Object {
"id": 2,
},
"-MPTgmANDZkMv7f_A9TG": Object {
"id": 4,
},
"-MPTgmc2fuu5XSUawuW7": Object {
"id": 3,
},
}
Now my question: I want to access not the id that is in the objects but rather the "name" of the object itself. If you look at the first element:
"-MPOg49jvG-md0twgj-D": Object {
"id": 1, }
i want to access this "-MPOg49jvG-md0twgj-D" and store it in a constant but I dont know how to do it. Any idea would be appriciated.
If I'm understanding correctly, you already fetched resData as a JavaScript object and want to get the keys? These are some ways that possibly could help you.
const resData = {
"-MPOg49jvG-md0twgj-D": {
id: 1
},
"-MPTgHoTXzIcY_KpBHkc": {
id: 2
},
"-MPTgmANDZkMv7f_A9TG": {
id: 4
},
"-MPTgmc2fuu5XSUawuW7": {
id: 3
}
};
// method 1
console.log(Object.keys(resData));
// method 2
for (const key in resData) {
console.log(key, resData[key]);
}
// method 3
console.log(Object.getOwnPropertyNames(resData));
Hope this can help, please correct me if I got it wrong.
I need to send the following example MongoDB query from a React.JS frontend app to a backend Node.js API via URL request params:
{
_id: ObjectId('507f1f77bcf86cd799439011'),
name: {
$in: ['foo', 'bar']
}
}
However, ObjectId is a function and cannot be serialized to JSON. So, I tried this BSON form as proposed in https://stackoverflow.com/a/34486720/6039697:
{
"_id": {
"$oid": "507f1f77bcf86cd799439011"
},
"name": {
"$in": ["foo", "bar"]
}
}
But MongoDB show this error
{
"message" : "unknown operator: $oid",
"ok" : 0,
"code" : NumberInt(2),
"codeName" : "BadValue",
"name" : "MongoError"
}
I Know I could check for _ids and parse in the API, but I would like to make this transparent and automatic. Does anyone have an idea on how can I get this working?
I found a solution to my question. This package solved my problem https://www.npmjs.com/package/bson
const { EJSON } = require('bson');
const mongoDBQuery = EJSON.parse(JSON.stringify({
"_id": {
"$oid": "507f1f77bcf86cd799439011"
},
"name": {
"$in": ["foo", "bar"]
}
}), { relaxed: true });
console.log(mongoDBQuery);
I am trying to create mock data by using the json-server in combination with the json-schema-faker.
I was trying to use the $ref property but I understood that this only references the type and not the exact value.
Is there a way to reuse the exact same value instead of just its type?
The schema I have in mockDataSchema.js file is:
var schema =
{
"title": "tests",
"type": "object",
"required": [
"test"
],
"properties": {
"test": {
"type": "object",
"required": [
"id",
"test2_ids",
"test3"
],
"properties": {
"id": {
"type": "string",
"faker": "random.uuid" // here
},
"test2_ids": {
"type": "array",
"items": {
"type": "string",
"faker": "random.uuid" // here
}
},
"test3": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"faker": "random.uuid" // here
}
}
}
}
}
}
}
};
module.exports = schema;
From this schema I want the id to be the same in all three locations which i have indicated with the comment // here.
Note that I can't use an enum or const as I want to have multiple tests occurrences.
test2_ids will be an array so i would like to include that specific id for the first id and other values of the same type as well..
In the id of test3 i just want the exact same value as the id of test.
Is it feasible what I am trying to achieve?
Or is there a way to change these data in the generateMockData.js file instead of the mockDataSchema.js which includes this schema ?
My generateMockData.js :
var jsf = require('json-schema-faker');
var mockDataSchema = require('./mockDataSchema');
var fs = require('fs');
var json = JSON.stringify(jsf(mockDataSchema));
fs.writeFile("./src/api/db.json", json, function (err) {
if (err) {
return console.log(err);
} else {
console.log("Mock data generated.");
}
});
I'd like to share here a solution that I found. In my case, I required to generate the same value for the fields password and password_confirmation using json-schema-faker, and something that worked for me was, assign a new property in the faker library and put the new property name inside the faker schema. Here the code:
import faker from 'faker';
import jsf from 'json-schema-faker';
// here we generate a random password using faker
const password = faker.internet.password();
// we assign the password generated to a non-existent property, basically here you create your own property inside faker to save the constant value that you want to use.
faker.internet.samePassword = () => password;
// now we specify that we want to use faker in jsf
jsf.extend('faker', () => faker);
// we create the schema specifying the property that we have created above
const fakerSchema = {
type: 'object',
properties: {
password: {
faker: 'internet.samePassword',
type: 'string'
},
password_confirmation: {
faker: 'internet.samePassword',
type: 'string'
}
}
};
// We use the schema defined and voilá!
let dataToSave = await jsf.resolve(fakerSchema);
/*
This is the data generated
{
password: 'zajkBxZcV0CwrFs',
password_confirmation: 'zajkBxZcV0CwrFs'
}
*/
I have a basic GraphQL query setup as follows:
Query.js:
const Query = {
dogs(parent, args, ctx, info) {
return [{ name: 'Snickers' }, { name: 'Sunny' }];
},
};
module.exports = Query;
schema.graphql:
type Dog {
name: String!
}
type Query {
dogs: [Dog]!
}
I created a function createServer() for starting the server as follows:
const { GraphQLServer } = require('graphql-yoga');
const Mutation = require('./resolvers/Mutation');
const Query = require('./resolvers/Query');
const db = require('./db');
function createServer() {
return new GraphQLServer({
typeDefs: 'src/schema.graphql',
resolvers: {
Mutation,
Query,
},
resolverValidationOptions: {
requireResolversForResolveType: false,
},
context: req => ({ ...req, db }),
});
}
module.exports = createServer;
I then tried querying dogs as follows:
query {
dogs {
name
}
}
But instead of getting the names from the array of dogs, I got the following error instead:
{
"data": null,
"errors": [
{
"message": "Cannot return null for non-nullable field Query.dogs.",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"dogs"
]
}
]
}
What seems to be causing this error?
This problem comes from AWS requiring certain standard values in the dynamoDB table, such as createdAt and updatedAd, just add these fields manually with a timestamp in dynamo db for further testing. A mutation always needs to be requested via id, this somehow was not clear to me when my schema was created by amplify codegen...
The above code works as you can see in codesandbox: https://codesandbox.io/s/olzj9vvpk5
But when I convert Query to something like {} it returns the same error so please check your paths and console.log Query to validate the path. Your export looks correct but you might have forgotten to save the file as I can see from the course starter files Query is an {}. Please double check.
Also if this code is in a public git repo please share the link.
I know this question has been answered, but for me the only thing that fixed this issue was to also pass the info argument.
In my case, I create a new Query.js file at the src folder but I import Query with Query = require('./resolvers/Query') and coding there. So, try to check the path, I think the problem is there.
i need to change the field dynamically
this.search = function(search, match) {
var deferred = $q.defer()
search({
size: 10000,
index: "products",
body: {
"query": {
"match": {
[search]: {
"query": match,
// "operator": "and",
type:"phrase"
}
}
}
}
but its showing the error 30:16 error Parsing error: Unexpected token [
You'll have to split it up so you can build the body object dynamically:
var body = {
"query": {
"match": { }
}
};
body.query.match[search] = {
"query": match,
"type": "phrase"
};
This isn't an AngularJS problem - the problem is you are trying to use a Computed Property Name for the object literal when the browser you are using doesn't support it.
Computed Property Name documentation link:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#Computed_property_names
To see the which browsers can & can't use Computed Property Names:
https://kangax.github.io/compat-table/es6/#test-object_literal_extensions_computed_properties