Graphql-tools: mockServer overrides pre-defined resolvers

Created on 18 Jan 2017  Â·  7Comments  Â·  Source: ardatan/graphql-tools

In order for the front team I'm working with to go on with their development I decided to expose a mock version of the server under a different route so they could go on implementing everything needed even if I'm not fully ready yet.

They are using angular2/typescript so I decided to go that way to keep the code in one place and not deal with ts' typings.

It's all great on paper, but when I tried the following implementation

Server.route({
    method : 'POST',
    path : '/mockql',
    handler : (request, reply) => {
        const _mockServer = mockServer(Schema)

        reply(_mockServer.query(request.payload.query))
    }
})

// Register plugins
Server.register([{
    register : GraphQLServer.graphqlHapi,
    options : {
        path : '/graphql',
        graphqlOptions : {
            schema : Schema,
            graphiql : true,
            debug : Process.env.NODE_ENV === 'development'
        },
        route : {
            cors : true
        }
    }
}])
Server.start()

I realised that once I made a query to the /mockql route, the other queries were impacted as well and started responding with random data (as should be on the /mockql route).

Why would using the mockServer factory override all the things like that?
Is this wanted, and if so, why?

Am I missing something?

enhancement

Most helpful comment

I will try to find some time and do that.
😨

All 7 comments

The underlying API is addMockFunctionsToSchema: http://dev.apollodata.com/tools/graphql-tools/mocking.html#addMockFunctionsToSchema

As the name implies, it mutates the passed-in schema to add mocks to it.

If you don't want any of the original resolvers, I'd suggest printing and then parsing the schema as a way of cloning it. On the other hand if you want to keep some of the resolvers then we would need to come up with some other approach.

In our use case we have the entire server run either in mock mode or in production mode, so we didn't run into this before, but I'd be happy to work together to find a solution!

Thanks for your input.

May I suggest that the naming is misleading then?

mockServer(Schema).query(...) 

Suggests that mockServer it will return a server with the given schema. I do not understand, from reading this code, that it will modify any schema pre-given to the graphql-tools and also that it will use the addMockFunctionsToSchema function.

By the way, is there somewhere I can find documentation about the mockServer method directly? I can't seem to find it.

From my point of view, mockServer should be a factory that returns a server (an object in which you could use the query method, or whatever is necessary for it to be a proper server :)) and should be totally independant from everything that has been defined previously.

Either that, or make it explicit that you want to just use addMockFunctionsToSchema really.

[edit] : Just to elaborate on this : Being able to do this would allow for devs to work on a totally offline mode that would still respond with the proper type of data even if a route is defined with real resolvers. And it would be simple to do, without any weird tricks.

@Shahor You're right. MockServer was never intended to do very much, and its name is indeed misleading. I think we should either remove it or modify it so it makes a copy of the schema before mocking it. I'd definitely appreciate a PR in that direction, if you have time to make one!

As for overwriting existing resolve functions, there's an option on addMockFunctionsToSchema that prevents it from happening, but it's not exposed through mockServer.

I will try to find some time and do that.
😨

Hello again o/
Can someone give me some indications as to how I can make this happen?
I've been poking around but I'm not sure exactly how I could implement this the proper way and since I don't have a good knowledge of the graphql internals I might miss some stuff.

I guess I could add a cloneSchema param to the mockServer factory, and then clone the schema but I have no clue as to how I could clone that schema properly and ensure that I would be modifying a new schema and not mutate any other pre-created schema.

edit: I finally have some time to take care of this. I'll happily do it but need a bit of guidance.

In the meantime I'm just passing a clone of my initial schema to mockServer.

@Shahor You'll want to do a deep clone on the schema. The only thing that mocking touches are the resolvers (I think), so you just have to make sure that the resolvers in the original schema don't get changed.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

alfaproject picture alfaproject  Â·  4Comments

Adherentman picture Adherentman  Â·  4Comments

proehlen picture proehlen  Â·  4Comments

stubailo picture stubailo  Â·  3Comments

ghost picture ghost  Â·  3Comments