Code Monkey home page Code Monkey logo

Comments (21)

icebob avatar icebob commented on March 29, 2024 20

@helfer Thanks, but unfortunately it's not solve my problem. My app is modularity, and in every module have queries in the Query. So I need to merge this queries to one before I gave it to the makeExecutableSchema.

For example:

post.module.js

const schema = `

type Query {
    posts(limit: Int, offset: Int, sort: String): [Post]
    post(id: Int, code: String): Post
}

type Post {
    id: Int!
    code: String!
    title: String
    content: String
    author: User!
}

type Mutation {
    upVote(postID: Int!): Post
    downVote(postID: Int!): Post
}

user.module.js


const schema = `
type Query {
    users(limit: Int, offset: Int, sort: String): [User]
    user(id: Int, code: String): User
}

type User {
    id: Int!
    code: String!
    fullName: String
    email: String
    username: String
    provider: String
    roles: [String]
    verified: Boolean
    gravatar: String
    lastLogin: Timestamp
    posts(limit: Int, offset: Int, sort: String): [Post]
}

type Mutation {
    createUser(userID Int!): User
    deleteUser(userID: Int!)
}
`

So I need to merge the Query definitions too. In schemaGenerator the concatenateTypeDefs functions concatenate the typeDefs only.

Are there any solution for this problem in the apollo-server or in the graphql-tools?

from apollo-server.

dbx834 avatar dbx834 commented on March 29, 2024 12

Here's a hacky inspiration,

File1.js,

// ----------------------------------------------------------------------- Schema & Resolvers

// ------------------------------------ Schema
const typeShard = `
type Planet {
  id: String
  name: String
  diameter: String
  gravity: String
  climate: String
  terrain: String
  rotationPeriod: String
  population: String
  orbitalPeriod: String
  surfaceWater: String
}
`;

const queryShard = `
planets: [Planet]
`;

// ------------------------------------ Resolvers
const resolvers = {
  Query: {
    planets() {
      return API.fetch();
    },
  },
};

// ----------------------------------------------------------------------- Exports

export { typeShard, queryShard, resolvers };

File2.js

// ----------------------------------------------------------------------- Schema & Resolvers

// ------------------------------------ Schema
const typeShard = `
type SomeOtherType {
  id: String
  ....
}
type RecordsAndMetaData {
  records: [SomeOtherType]
  totalRecords: String
  currentPage: String
}
`;

const queryShard = `
recordsAndMetaData(currentPage: String): RecordsAndMetaData
`;

// ------------------------------------ Resolvers
const resolvers = {
  Query: {
    recordsAndMetaData(root, { currentPage = '1' } = {}) {
      return API.configure({ currentPage });
    },
  },
  RecordsAndMetaData: {
    records() {
      return API.fetch();
    },
  },
};

// ----------------------------------------------------------------------- Exports

export { typeShard, queryShard, resolvers };

MergeAndCompileStuff.js

// ----------------------------------------------------------------------- Import stuff
import _ from 'lodash';

// ------------------------------------ Data Emulation
import { typeShard as ts1, queryShard as qs1, resolvers as rs1 } from './location/to/File1.js';
import { typeShard as ts2, queryShard as qs2, resolvers as rs2 } from './location/to/File2.js';

// ----------------------------------------------------------------------- Make stuff

// ------------------------------------ Compile schemas

const compiledSchema = [`
${ts1}
${ts2}
type Query {
  ${qs1}
  ${qs2}
}
schema {
  query: Query
}
`];

// ------------------------------------ Merge resolvers

const mergedResolvers = {};

_.map([rs1, rs2], function (resolverShard) {
  _.map(resolverShard, function (resolvers, outerKey) {

    if (mergedResolvers[outerKey] === undefined) {
      mergedResolvers[outerKey] = {};
    }

    _.map(resolvers, function (resolver, innerKey) {
      mergedResolvers[outerKey][innerKey] = resolver;
    });
  });
});

// ----------------------------------------------------------------------- Export stuff
export const thisPackage = 'sandbox:lib-transmit';
export { compiledSchema as schema, mergedResolvers as resolvers };

And in server/start.js,

// ----------------------------------------------------------------------- Imports

// ---------------------------------- Meteor & Apollo
import { Meteor } from 'meteor/meteor';
import { createApolloServer } from 'meteor/apollo';

// ---------------------------------- Fetch Schema & Resolvers for Apollo server
import { schema, resolvers } from 'meteor/sandbox:lib-transmit';

// ----------------------------------------------------------------------- Create Apollo Server
createApolloServer({
  graphiql: true,
  pretty: true,
  schema,
  resolvers,
});

// ----------------------------------------------------------------------- Startup code
Meteor.startup(() => {
  console.log('hello world!');
});

from apollo-server.

PierBover avatar PierBover commented on March 29, 2024 8

Has anyone worked out a more elegant solution to this problem other than joining everything by hand?

It's unrealistic to expect to have all types in the same file.

from apollo-server.

vmatekole avatar vmatekole commented on March 29, 2024 5

Thanks @helfer — I will join the conv. Incidentally, I came across this and currently giving it a spin — https://github.com/okgrow/merge-graphql-schemas. I haven't looked under the hood but on first use it appears to fulfil basic merging reqs.

from apollo-server.

helfer avatar helfer commented on March 29, 2024 2

Yes, this is not very well documented at the moment. A type definition can contain other imported type definitions. If they are circular, you can use a function that returns an array as type definition. You should use the makeExecutableSchema function from graphql-tools (not apollo-server) here: https://github.com/apollostack/graphql-tools/blob/88eadb99a11733fb11726df539d6fe1bb3be9a6f/src/schemaGenerator.js#L67

We're planning on making a big push for documentation and content starting next week, so this should be more well-documented soon!

from apollo-server.

helfer avatar helfer commented on March 29, 2024 1

Yes, I'll write some documentation today or tomorrow, including an example.

from apollo-server.

wuzhuzhu avatar wuzhuzhu commented on March 29, 2024

Thanks for answer.
When I trying to use makeExecutableSchema, I still got error when using concated typeDefs:
Am i miss something when doing this?
export const schema = [...rootSchema, ...userSchema, ...authorSchema];

/Users/walter/.meteor/packages/meteor-tool/.1.3.4_1.mi2rro++os.osx.x86_64+web.browser+web.cordova/mt-os.osx.x86_64/dev_bundle/server-lib/node_modules/fibers/future.js:280
W20160704-14:55:00.879(8)? (STDERR) throw(ex);
W20160704-14:55:00.879(8)? (STDERR) ^
W20160704-14:55:00.879(8)? (STDERR) Syntax Error GraphQL (27:21) Expected Name, found EOF
W20160704-14:55:00.880(8)? (STDERR)
W20160704-14:55:00.880(8)? (STDERR) 26: name: String
W20160704-14:55:00.880(8)? (STDERR) 27: author: [Author]

from apollo-server.

helfer avatar helfer commented on March 29, 2024

That should work just fine. Are you sure you don't have a syntax error in your file, like a missing } after [Author]?

from apollo-server.

wuzhuzhu avatar wuzhuzhu commented on March 29, 2024

Yes I fixed it by remove a comment line. Close.
thank you

from apollo-server.

icebob avatar icebob commented on March 29, 2024

@helfer could you show a sample, how to use the makeExecutableSchema function?

from apollo-server.

icebob avatar icebob commented on March 29, 2024

@helfer are you ready? Where can I find the docs & example?

from apollo-server.

icebob avatar icebob commented on March 29, 2024

up

from apollo-server.

dbx834 avatar dbx834 commented on March 29, 2024

+1 for docs on merging schemas and resolvers

from apollo-server.

helfer avatar helfer commented on March 29, 2024

Sorry for the delay, we're going to do a major rewrite of the documentation soon, so this might actually take even longer. In the meantime, here's the function signature:

function makeExecutableSchema({
  typeDefs, // shorthand type definitions
  resolvers, // resolve function definitions
  connectors,
  logger, // logging function to be called for every resolver
  allowUndefinedInResolve = false,
  resolverValidationOptions = {},
})

The resolver validation options (and defaults) are as follows.

{
    requireResolversForArgs = true,
    requireResolversForNonScalar = true,
}

from apollo-server.

helfer avatar helfer commented on March 29, 2024

@icebob Yeah, that's not going to work, because you need to have unique names for everything.

If you want, you could probably write a mergeSchemas function which merges different schemas and even namespaces them. It's not that difficult, all you'd have to do is look into the document and produce a new merged one.

from apollo-server.

icebob avatar icebob commented on March 29, 2024

@dbx834 thanks, your solution will be good.

from apollo-server.

icebob avatar icebob commented on March 29, 2024

If there would be namespaces in GraphQL, it solves my problem.

Meanwhile this is my solution to merge schemas & resolvers (similar to @dbx834 solution): https://gist.github.com/icebob/553c1f9f1a9478d828bcb7a08d06790a

from apollo-server.

veeramarni avatar veeramarni commented on March 29, 2024

I was wondering, whether solution posted by @icebob is still valid in latest Apollo version?

from apollo-server.

icebob avatar icebob commented on March 29, 2024

Yes, I'm using with new Apollo version.

from apollo-server.

vmatekole avatar vmatekole commented on March 29, 2024

same inquiry as @PierBover here ...

from apollo-server.

helfer avatar helfer commented on March 29, 2024

@PierBover @vmatekole we're having a conversation about schema merging/joining over on another repo, please come join us! https://github.com/apollographql/graphql-prism/issues/1

from apollo-server.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.