graphql-faker
graphql-faker copied to clipboard
Due to how extend works we can't replace type fields
So I was given this project a first try since I'm building some sort of boilerplate. I already have a schema, with (most) resolvers in place and I wanted to extend this with mock data. I'm assuming this scenario is probably not the goal for this project, but certainly seems like it can be used for it, and yet it can't.
I can't replace fields within the existing types since extendSchema
from graphqljs seems to complain. In this case what I'd like is to leave the schema as is, but replace the resolver instead.
Example: Original schema:
type User {
id: ID!
firstName: String
lastName: String
}
Our fake schema in extend mode:
extend type User {
firstName: String @fake(type: firstName)
lastName: String @fake(type: lastName)
}
I would have expected the above syntax to work, and the resolver within it to return me the fake fields. I feel like I'm missing something obvious but if this isn't supported I think it should. I'd be able to help if you can point me in the right direction.
EDIT:
I've done something like this in the past with addMockFunctionsToSchema
from graphql-tools
but obviously, that one lacks the Faker integration, and it's also hard to do proper relay connections in there. Maybe we could find a way to use it here as a last resort, but I think custom resolvers after leaving the schema in place should be the way to go.
@blackxored I want this tool to be compliant with GraphQL spec and graphql-js
so I can't change how extendSchema
works. We also design extend mode to be used for applying non-breaking changes to existing GraphQL API and your use case is really different from that.
Hower, I have an idea how to accommodate your use case without introducing too much complexity into graphql-faker. In source code we have fakeSchema function that accepts schema and attaches resolvers to it. I can expose it as an NPM package so you would be able to write:
import { fakeSchema } from 'graphql-faker';
import { makeExecutableSchema } from 'graphql-tools';
const typeDefs = `
type User {
id: ID!
firstName: String @fake(type: firstName)
lastName: String @fake(type: firstName)
}
`;
const resolvers = {
User: {
id() {
// ...
}
}
};
const executableSchema = makeExecutableSchema({
typeDefs,
resolvers,
});
// Assing missing resolvers
fakeSchema(executableSchema);
// Pass executableSchema to your server
Will it solve your use case?
Seems we need to keep multiple version of schema in this case, maybe we could added a "patcher" function.
In fact, I've just defined another fake version of the exact same type and append it onto the end of the original schema, and it works...like:
type Post {
id: ID!
article: String!
}
type Post {
id: ID! @fake(type: uuid)
article: String! @fake(type: lorem, options: {loremSize: paragraphs})
}
by the way, I find this "fakeSchema" :+1: solves my issue: https://github.com/APIs-guru/graphql-faker/pull/32
Seems we need to keep multiple version of schema in this case, maybe we could added a "patcher" function.
@liuchong All GraphQL tools (including graphql-tools
) I'm aware of will silently ignore unknown directives, so you can safely use one schema.
by the way, I find this "fakeSchema" π solves my issue: #32
Implementing it requires me to switch from custom fork of graphql-js
to official version + a lot of refactoring. I plan to start working on v2.0.0
release next month.
I will ping you after initial refactoring is done so you could help with PR if you have time for it.
@IvanGoncharov Great, thanks!
This is unfortunately a deal-breaker for us, I would love to use this package but not being able to return mock data for existing fields is very annoying. Is there any workaround for this nowadays?
@mxstbr Do you want to mock the entire GraphQL API or just to use the proxy mode where some data are coming from actual API and some are mocked locally?
How about @override
directive, e.g.:
extend type Post {
acticle: String! @override @fake(type: lorem, options: {loremSize: paragraphs})
}
Will it work in your use case?
just to use the proxy mode where some data are coming from actual API and some are mocked locally
That's what I want!
# Remote schema
type User {
username: String!
}
# Local schema
extend type User {
# ...some more fields...
username: String! @fake(type: username)
}
Sounds like @override
would work for my use case but I am not sure why I even need to manually specify thatβif it's in the local schema, just override it instead of throwing an error?!
just override it instead of throwing an error?!
@mxstbr In this case, we are changing the behavior of extend
as defined in GraphQL specification and implemented in any other GraphQL tool/lib.
So I don't want to enable this functionality by default.
How about using --override
CLI Flag instead of individually marking fields?
That sounds great to me!
@IvanGoncharov Are @override
or --override
available ATM?
@ahmedlhanafy Not ATM, it's just a proposed solution. I will try to find time to implement it this month
Maybe I'm misunderstanding significantly π , but why would you want to define new fields via extend that don't exist in your original (remote) schema?
I would think that that main use case for this library is to mock existing schema field data?
π
@IvanGoncharov Any update?
@adaam2
I'd like to use graphql-faker to mock the api for new features so the front end can implement a feature without all backend work being done. Sometimes new features require adding fields to existing types. For example, after creating a new Course
type, I'd want to add a courses
field to Contact
:
type Course {
id: ID! @fake(type: uuid)
title: String @fake(type: word)
description: String @fake(type: lorem)
}
extend type Contact {
courses: [Course!] @listLength(min: 1, max: 1)
}
@steezeburger fair enough, but i think there's a place for both use cases here :)
Wouaou... this issue was open back in 2017 and there is still no solution? It's a pretty common use case, judging by the people who interacted on this thread.
I am also looking at the @override or { fakeSchema } solution -
Sincerely
@IvanGoncharov would like to check if you will have time to look at this any soon. Thx
This is exactly my use case as well. Have an existing GraphQL schema from a Hasura instance that I want to use to generate faked seed data to feed into mutations.
I made NPM module based on my PR which enables fields overriding. If you need this feature in main module, you can subscribe to my PR's notifications and use my fork-module until it gets merged.
https://www.npmjs.com/package/@proscom/graphql-faker