-
Notifications
You must be signed in to change notification settings - Fork 7
Description
There’s a number of issues with the library in its current form:
- Reliance on schema directives means the library is incompatible with code-first libraries like
nexus,type-graphqlorgraphql-compose - Transforming the schema, whether done through schema directives or some other mechanism (like annotations), makes it hard to work with other tools like GraphQL Code Generator or IDE plugins.
- Exposing model details in the type definitions tightly couples the schema with the underlying data sources and the library itself. Migrating away from Sqlmancer would require not only changing the resolvers but changing all the type definitions as well.
- Exposing model details in the type definitions means we’re forced to utilize code generation -- the client’s type cannot just be inferred by TypeScript
- A schema-first approach means that if additional data models needed for internal use, they have to be exposed first as GraphQL types that are later removed from the schema using the
@privatedirective
What we could do differently:
- Remove all schema directives and use a single, standalone configuration object that includes all data model details.
- The data models defined inside the configuration object would resemble more traditional ORM data models and become the “source of truth” for the application. “Base” type definitions could be generated from the models as a convenience but type definitions could also be written by hand. Similarly, migration files could also be generated to keep the database in sync with the models.
- The data models could still include information specific to their respective GraphQL types, like “virtual” and paginated fields
The new workflow would look something like this:
- Write data models
- (Optionally) generate and run migrations based on the models
- (Optionally) generate type definitions from the models
- Write any remaining type definitions for the schema
- Instantiate client using only config object/data models and use it to write the resolvers
- Build the schema however you normally build your schema, with no extra steps
The API of the client itself would stay the same. When the data models change, the base type definitions can be regenerated and a new migration file can be created to sync the database.
In some ways, this workflow would be potentially more complicated than the existing one. Adding a where or orderBy argument to a field would require more steps than just sticking a directive on a field. On the other hand, utilizing a configuration object means we can leverage TypeScript for type checking and autocompletion, making it less error prone than stumbling through trying to add directives with the correct arguments.
Any "compliant" schema will work with the client, regardless of how it's created, opening up the possibility to use Sqlmancer with code-first schema libraries or even writing schemas using the core graphql module. The code generation feature could be expanded in the future to include generating code for these libraries without having to create additional, Sqlmancer-specific plugins for them.