Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make resolvers optional to enable a schema-first approach #222

Closed
soneymathew opened this issue Jan 5, 2019 · 7 comments
Closed

make resolvers optional to enable a schema-first approach #222

soneymathew opened this issue Jan 5, 2019 · 7 comments
Labels
Discussion 💬 Brainstorm about the idea Question ❔ Not future request, proposal or bug issue

Comments

@soneymathew
Copy link

Thank you for sharing this good work openly. I have the following feature request for your consideration, please let me know your thoughts.

Is your feature request related to a problem? Please describe.
I am exploring the possibility to use this fantastic library to spar on type definitions, before investing on resolvers/services
My goal is to stay focussed fully on the type definition without being distracted by the complexities of having to implement the resolvers. Assume that my backend services are not ready.
I chanced upon this recipe while trying to integrate a mocking strategy with type-graphql
https://www.apollographql.com/docs/graphql-tools/mocking.html#Default-mock-example

Describe the solution you'd like
Proposal

  1. buildSchema() should allow a provision to make resolvers optional
  2. enable us to add mocked resolvers with
// Add mocks, modifies schema in place
addMockFunctionsToSchema({ schema });

Describe alternatives you've considered
Alternative 1:
Implement minimal resolvers
use addMockFunctionsToSchema( { schema, preserveResolvers: false });
This is what I do currently

Alternative 2:

  1. emit schema using type-graphql to a file
  2. deserilaize and feed it to
import { makeExecutableSchema, addMockFunctionsToSchema } from 'graphql-tools';

const schemaString = getSchemaFromFileThatIsEmittedFromTypeGraphQL()

// Make a GraphQL schema with no resolvers
const schema = makeExecutableSchema({ typeDefs: schemaString });

// Add mocks, modifies schema in place
addMockFunctionsToSchema({ schema });
@soneymathew soneymathew changed the title make resolvers optional to allow integrating with addMockFunctionsToSchema({ schema }); make resolvers optional to enable a schema-first approach Jan 5, 2019
@MichalLytek MichalLytek added Question ❔ Not future request, proposal or bug issue Discussion 💬 Brainstorm about the idea labels Jan 5, 2019
@MichalLytek
Copy link
Owner

@soneymathew

buildSchema() should allow a provision to make resolvers optional

To be able to mock anything, you need to define your queries/mutations. And in TypeGraphQL we define the signature of the queries/mutations by writing resolver's class methods.

But this doesn't mean that your resolvers has to work. They can just throw error as the're not implemented yet:

@Resolver()
class SampleResolver {

  @Query(returns => [User])
  getUsers(@Arg("name") name: string) {
    throw new Error("Not implemented yet!");
  }
}

So you can build your schema and then just use the type defs without actual resolvers functions:

import { buildSchema} from "type-graphql";
import { printSchema } from "graphql";
import { makeExecutableSchema, addMockFunctionsToSchema } from 'graphql-tools';

// Generate a base schema from classes and decorators
const baseSchema = await buildSchema({ resolvers: [SampleResolver] });
// Extract only types definitions
const schemaString = printSchema(baseSchema);
// Make a GraphQL schema with no resolvers
const schema = makeExecutableSchema({ typeDefs: schemaString });
// Add mocks, modifies schema in place
addMockFunctionsToSchema({ schema });

Does this solution fill your needs? 😉

@lukejagodzinski
Copy link

lukejagodzinski commented Jan 5, 2019

@soneymathew @19majkel94 I was actually talking about the same thing with the creators of this tool https://github.com/dotansimha/graphql-code-generator. It should be fairly easy to add such module/template to this tool so it would generate TypeGraphQL base/abstract type and resolver classes from the schema. Later you could just extend them and provide resolvers logic. I'm actually interested with this feature, so there are both of us. I think with their help we could create something. We had interesting discussion about schema first approach and I'm leaning towards it even more as we're already using this approach on the client and used to use it on the server in previous application. And TypeGraphQL is so nice that I wouldn't like to sacrifice neither TypeGraphQL and schema first approach.

@soneymathew
Copy link
Author

in TypeGraphQL we define the signature of the queries/mutations by writing resolver's class methods.

this helps, I think I missed to notice that key point. I was trying to avoid the construct of resolvers altogether for the sake of introducing that construct later in the cycle to the reviewers.

@MichalLytek
Copy link
Owner

@soneymathew

I was trying to avoid the construct of resolvers

So you want to create object/input types with TypeGraphQL but the Query/Mutation are defined in SDL? What are the benefits of this hybrid approach? 😕

@lukejagodzinski
Copy link

@19majkel94 I've talked with one of the authors of the Apollo on the schema first approach and he said that sometimes it's easier to think GraphQL first when designing application. GraphQL is intended to be understandable not only by developers but also by non technical person that can design schema according to the client requirements. The other reason is that SDL is very easy to understand and reason about from. Of course, you can always generate schema after defining your resolvers but sometimes you might want to design your entire schema first, when talking for example with the mobile application developers and discussing what shape data should come in. There are many reason to follow schema first principle. But I think it could be done with third party libraries like https://graphql-code-generator.com

@MichalLytek
Copy link
Owner

@soneymathew @lukejagodzinski
#233 should match your requirements - you can generate typeDefs from TypeGraphQL, mix them with your SDL, add resolvers mocks and build the schema.

The only inconvenience is that you have to create at least one resolver with one query (might be e.g. currentDate) and import (and use) all the spare types that you want in the schema (typeDefs) 😉

@soneymathew
Copy link
Author

Thanks for #233 I will give it a try.

So you want to create object/input types with TypeGraphQL but the Query/Mutation are defined in SDL? What are the benefits of this hybrid approach?

@lukejagodzinski have covered some of the aspects. The benefit of the hybrid approach IMO is to reduce the friction to the minimum and allow the complexity to increase in stages.

I wanted to leverage type-graphql for the common constructs that lays the foundation of the system schema. I wanted the discussion to be strictly focussed on type definitions

  • What interfaces should be made available,
  • what is the pagination strategy,
  • what are the general mutations,
  • what should be queryable in the mutations etc

having to think about resolver implementations needs a shift of mindset that goes to waste if the schema drastically evolves in a review. The balance of skills required to do a schema definition combined with authoring resolvers distracts each other, at least for me.

  • Step 1: Define schema
  • Step 2: Mock it, it's a one liner at first.
  • Step 3: Spar with team, let them query the endpoint and test the mocks for their needs
  • Step 4: Goto step 1 and incorporate review comments if any.
  • Step 5 implement resolvers stage by stage.

By the time I reach step 5 I have reasonable confidence on the type definition and have some certainty that my work on resolvers will not go to waste.
I believe that authoring the resolvers needs much more attention to detail, like service design, avoid n+1 problem etc which deserves a lot more mind space and effort, while I am at it, the UI devs can start consuming the mock schema as a contract and start on their implementation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Discussion 💬 Brainstorm about the idea Question ❔ Not future request, proposal or bug issue
Projects
None yet
Development

No branches or pull requests

3 participants