Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 5 years ago.
Improve this question
Is there a standalone tool to convert a modularized graphql schema to a json schema?
I have a graphql server using apollo-graphql and graphql-tools makeExecutableSchema. It follows the pattern described here
// schema.js
import { makeExecutableSchema } form 'graphql-tools';
const Author = `type Author { ... }`;
const Post = `type Post { ... }`;
const Query = `type Query { ... }`;
export const typeDefs = [Author, Post, Query];
export const schema = makeExecutableSchema({
typeDefs: typeDefs,
resolvers: { ... },
});
How can I create a schema.json form either typeDefs or schema?
I need a json schema to use relay-compiler or apollo-codegen. apollo-codegen includes this script to create a schema from a graphql server...
apollo-codegen introspect-schema http://localhost:8080/graphql --output schema.json
...but I want to create the schema, and run apollo-codegen, in an automated build. I don't want to create a server.
I would submit this as an answer, but the question has been marked off-topic ¯\_(ツ)_/¯
The answer from #daniel-rearden pointed me in the correct direction. makeExecutableSchema returns a GraphQLSchema so one can use graphql's printSchema and introspectionQuery to get json or graphql language representations of the schema.
// export.js
import { schema } from './schema.js'
import { graphql, introspectionQuery, printSchema } from 'graphql';
// Save json schema
graphql(schema, introspectionQuery).then(result => {
fs.writeFileSync(
`${yourSchemaPath}.json`,
JSON.stringify(result, null, 2)
);
});
// Save user readable type system shorthand of schema
fs.writeFileSync(
`${yourSchemaPath}.graphql`,
printSchema(schema)
);
There's graphql-to-json. I believe that has a CLI tool to do just that.
Alternatively, you could write your own script and just execute it with node. You don't have to spin up a server to run a query, you just need a schema and you can run a query directly against it. You can check out an example here.
Related
const { ApolloServer, gql } = require('apollo-server');
// A schema is a collection of type definitions (hence "typeDefs")
// that together define the "shape" of queries that are executed against
// your data.
const typeDefs = gql`
# Comments in GraphQL strings (such as this one) start with the hash (#) symbol.
# This "Book" type defines the queryable fields for every book in our data source.
type Book {
title: String
author: String
}
# The "Query" type is special: it lists all of the available queries that
# clients can execute, along with the return type for each. In this
# case, the "books" query returns an array of zero or more Books (defined above).
type Query {
books: [Book]
}
`;
const books = [
{
title: 'The Awakening',
author: 'Kate Chopin',
},
{
title: 'City of Glass',
author: 'Paul Auster',
},
];
// Resolvers define the technique for fetching the types defined in the
// schema. This resolver retrieves books from the "books" array above.
const resolvers = {
Query: {
books: () => books,
},
};
// The ApolloServer constructor requires two parameters: your schema
// definition and your set of resolvers.
const server = new ApolloServer({ typeDefs, resolvers });
// The `listen` method launches a web server.
server.listen().then(({ url }) => {
console.log(`🚀 Server ready at ${url}`);
});
So this is the code I copied from official Apollo GraphQL site. I use graphql 16.3 and apollo-server 2.25.3.
I don't know what the message told me what to fix. Help me please. Thank you guys so much!
From their documentation it seems that apollo-server 2 don't support graphql >15
https://www.apollographql.com/docs/apollo-server/migration/
I would either migrate to apollo-server 3 or downgrade graphql to version 15.
Ok, for 2 years I have been developing a GraphQL Node.js Apollo API in typescript, and there is one thing our team never managed to get up and running: How do we get "Go to Definition" in our .ts files, containing the Grahpql Schema?
Our schema is defined in multiple .ts files, and it's very frustrating having to look through many files when needing to lookup a type definition, input, etc.
We are all using VS Code, and I hoped I could obtain this with the Apollo Graphql extension. However this only seems to work for client projects?
Example of code structure
// file 1, inputs.ts
export const inputs = gql`
input: FancyInput {
fancyName: String!
}
`;
// file 2, mutations.ts
export const mutations = gql`
// HOW do we get "Go to Definition" when right clicking the 'FancyInput'?
fancyMutation(input: FancyInput): Boolean!
`;
// file 3, apollo-server-setup
const { inputs } = from './inputs';
const { mutations } = from './mutations';
const server = new ApolloServer({
typeDefs: [
inputs,
mutations
]
})
In the beginning, this was not a big problem, but now it's super frustrating because the project is rather big today with 30+ schema files.
So the reason I am asking this question is because I can get both of these to return a working result with just replacing one or the other. So which is the right one to use and why?
What are their purposes in regards to schemas?
import { mergeSchemas } from 'graphql-tools'
import bookSchema from './book/schema/book.gql'
import bookResolver from './book/resolvers/book'
export const schema = mergeSchemas({
schemas: [bookSchema],
resolvers: [bookResolver]
})
import { makeExecutableSchema } from 'graphql-tools'
import bookSchema from './book/schema/book.gql'
import bookResolver from './book/resolvers/book'
export const schema = makeExecutableSchema({
typeDefs: [bookSchema],
resolvers: [bookResolver]
})
Both of these examples work and return the desired outcome. I believe the correct one to use here is the makeExecutableSchema but not sure why the first one would work?
EDIT
Just incase it would be nice to have the types/resolvers:
typeDefs
type Query {
book(id: String!): Book
bookList: [Book]
}
type Book {
id: String
name: String
genre: String
}
Resolvers
export default {
Query: {
book: () => {
return {
id: `1`,
name: `name`,
genre: `scary`
}
},
bookList: () => {
return [
{ id: `1`, name: `name`, genre: `scary` },
{ id: `2`, name: `name`, genre: `scary` }
]
}
}
}
Query Ran
query {
bookList{
id
name
genre
}
}
Result
{
"data": {
"bookList": [
{
"id": "1",
"name": "name",
"genre": "scary"
},
{
"id": "2",
"name": "name",
"genre": "scary"
}
]
}
}
mergeSchemas is primarily intended to be used for schema stitching, not combing code for a single schema you've chosen to split up for organizational purposes.
Schema stitching is most commonly done when you have multiple microservices that each expose a GraphQL endpoint. You can extract schemas from each endpoint and then use mergeSchemas to create a single GraphQL service that delegates queries to each microservice as appropriate. Technically, schema stitching could also be used to extend some existing API or to create multiple services from a base schema, although I imagine those use cases are less common.
If you are architecting a single, contained GraphQL service you should stick with makeExecutableSchema. makeExecutableSchema is what actually lets you use Schema Definition Language to generate your schema. mergeSchemas is a relatively new API and has a number of open issues, especially with regards to how directives are handled. If you don't need the functionality provided by mergeSchemas -- namely, you're not actually merging separate schemas, don't use it.
Yes makeExecutableSchema creates a GraphQL.js GraphQLSchema instance from GraphQL schema language as per graphql-tools docs So if you are creating stand alone, contained GrpaphQL service is a way to go.
But if you are looking to consolidate multiple GraphQL services there are multiple different strategies you may consider such as schema-stitching, schema-merging from graphql-tools or federation from apollo (there are probably more).
Since I landed here while searching what is the difference between stitching and merging I wanted to point out that they are not one and the same thing. Here is the answer I got for this question on graphql-tools github.
Schema Stitching creates a proxy schema on top of different independent subschemas, so the parts of that schema are executed using GraphQLJS internally. This is useful to create an architecture like microservices.
Schema Merging creates a new schema by merging the extracted type definitions and resolvers from them, so there will be a single execution layer.
The first one keeps the individual schemas, but the second one won't. A use case for the first would be for combining multiple remote GraphQL APIs (microservices), while the second one would be good for combining local schemas.
I want to add introspection from a variable to my app.
I have this kind of introspection:
{"data":{"__schema":{"queryType":{"name":"PageContentQuery"}....
(that im getting from rest request)
I want this variable to be the schema provider, is it possible?
The full variable is here: https://stackblitz.com/edit/ts-graphql-demo-ypgi18?file=index.tsx
const fetcher = (params: any) => {
console.log(params);
return graphql(schema, params.query, params.variables);
}
const defaultQuery = `{
page{id,contents}
}`;
render(
<GraphiQL fetcher={fetcher} schema={schema} defaultQuery={defaultQuery}/>,
document.getElementById('root'),
);
thanks
Given the results of an introspection query, you can build a schema using buildClientSchema:
import { buildClientSchema } from 'graphql'
const schema = buildClientSchema(introspectionResult)
You can then pass that schema as prop to the GraphiQL component:
<GraphiQL fetcher={fetcher} schema={schema} />
Of course, that's generally not necessary -- if the schema is not passed in, then GraphiQL will just make an introspection query for you using the fetcher you provide.
How can I pass an existing GraphQLSchema object like graphql-iso-date to the makeExecutableSchema function, to use it along with my string-defined types and resolver functions? Say in following type definition I want the date property to be GraphQLDate from the mentioned package.
import { GraphQLDate, GraphQLTime, GraphQLDateTime } from 'graphql-iso-date';
let typeDefs = [];
typeDefs.push(`
type MyType {
date: Date
}
`);
let resolvers = {
Query: () => { /* ... */ },
};
makeExecutableSchema({ typeDefs, resolvers });
It turns out the resolvers map, which is passed to the makeExecutableSchema does accept the GraphQLScalarType and the Date type is scalar. We still have to add the types into the typeDefs manually though...
typeDefs.push('scalar Date');
and
resolvers.Date = GraphQLDate;
So I've created a module of external scalars in my project and am doing
import externalTypes from './externalTypes';
import printType from 'graphql';
// Define my typeDefs and resolvers here
for (let externalType of externalTypes) {
let { name } = externalType;
typeDefs.push(printType(externalType));
resolvers[name] = externalType;
}
makeExecutableSchema({ typeDefs, resolvers });
I figured it by trial/failure and only then found it in the docs, thus posting. Also I still don't know how would I add a non-scalar type this way (well other than manually writing it's type definition).
Also the printType function, which prints schema definition from type object passed, becomes handy here (see this question for more detail).