Open MichalLytek opened 6 years ago
@19majkel94 Why this is blocked? at face seems less complicated.
Go to the link in first post and read the discussion :wink: If you can implement this - feel free to make a PR π
This sadly prevents anybody from being able to use type-graphql
that is using graphcool/prisma as a backend. We would love to use it but sadly without being able to generate the schema necessary by the downstream tooling its a non starter :(
@ntziolis AFAIK, Prisma is the glue between your GraphQL server and your database. You define your model using SDL and you receive a generated client that acts as an ORM in your server app.
So there should be no problem to use Prisma along with your GraphQL API build with TypeGraphQL. Of course, the tighter integration (defining prisma model and your API GraphQL Object Type in one class with decorators) would help in reducing boilerplate, but I think it's not a deal breaker π
And to report an update about the status of the issue - now I think I understand where is the problem with directives in graphql-js
. They are purely the SDL thing, so tools written in different languages can parse the schema definition and apply certain behaviors in runtime.
So as with graphql-js
we define a runtime JS object, other tools (like Prisma or Apollo Engine) don't have an access to the directives. That's why we have to wait for a new GraphQL specification that will expose the directives info via an introspection query. For now the only workaround is to generate typeDefs
and resolversMap
instead of executable GraphQLSchema
and paste the "directives" from metadata storage into proper lines in SDL string π
@19majkel94 I understand the first instinct, but there are various reasons why we feel when solving this issue a lot of other goodness would come from it:
In order to clean this up and follow DRY here is how we wanted to use type-graphql
type-graphql
becomes our way of defining both public & prisma schema (including generating the actual SDL files)I understand this might have been the initial intention of type-graphql
but I can tell you after the 10th+ graphql project: The need for a framework that is the beginning and end where types originate is VERY high especially when using a graphql datasource underneath (we have tried various beyond prisma).
Hi @19majkel94
I was trying to undestand the problem for long hours π As far as I found apollo graphql-tools is doing simple job for schema directives. It just finds fields with directives and overrides their resolvers with enhanced version that applies that specific directive.
So as TypeGraphQL stores metadata for first part, the second part can be done the same way.
I don't know what you want to provide for prisma. The datamodel of the prisma is not a graphql thing. it's a customized version so I think it has nothing to do with TypeGraphQL that cares about server - client relation.
@Hossein-s So show me a proof of concept how to apply directive to a field using graphql-js
, not GraphQL SDL syntax.
@19majkel94 Great. I will work on it.
@Hossein-s I also took quite a long time to find a possible solution for programatically declare directives for a node, but no luck so far. So I am also keen to see your finding.
If I understand correctly, your statement here is not quite right:
As far as I found apollo graphql-tools is doing simple job for schema directives. It just finds fields with directives and overrides their resolvers with enhanced version that applies that specific directive.
A directive
is not a function, it is simply a piece of information that can be attached to a node (field, type, etc), which only contains name
and optional args
, and the directive itself has no logic at all, that said there is no way (and doesn't make sense) to "apply the directive".
In the case of apollo, you also need to implement SchemaDirectiveVisitor for specific directives.
@zhenwenc When you have SDL it's just piece of information. But when you want an executable schema, then executor applies the logic implemented for that piece of information to the resolver. As you can see in the SchemaDirectiveVisitor samples, every custom directive (and built in directives like deprecated directive) have an implementation, then you decorate fields and objects to call that implementation. (But I couldn't find cacheControl source to find how it works (even couldn't set it up to work with apollo πΆ )).
Do you know any case that astNode definitions needed by server? I'm new on this topic.
After investigating more, I found implementation of schema directives in apollo and graphql-yoga very similar to TypeGraphQL middlewares that are already available (But you can pass arguments to them).
@19majkel94 I don't know where schema directives sit in TypeGraphQL. π
@Hossein-s
When you have SDL it's just piece of information.
The problem (or difficulty) here is not about executing the directive, since apollo already provided a way to handle it (via SchemaDirectiveVisitor), but how to add the directive into the GraphQLSchema without using DSL.
If I understand it correctly, the reason why TypeGraphQL can use Middleware to implement cache control is because you can easily manipulate the cache control store since apollo injected it into the resolve info, which doesn't actually needs to involve directive at all.
If I understand it correctly, the reason why TypeGraphQL can use Middleware to implement cache control is because you can easily manipulate the cache control store since apollo injected it into the resolve info, which doesn't actually needs to involve directive at all.
@zhenwenc Thanks! Now I undestand where the astNode is used π.
So I think it's possible to patch the resulting schema and add the astNode if there is need π€ I will work on it...
I have updated PoC repository so that it adds astNode to GraphQLField. you can see it here.
So apollo cache control can read directives in this function. But other directives work without astNode.
It's very minimal just to show the posibility of feature.
@Hossein-s
Can you check in your PoC if you add directive to astNodes
, will it show up in printSchema
?
@19majkel94
Unfortunately no. printSchema
is not considering directives at all :-/
https://github.com/graphql/graphql-js/issues/869
@Hossein-s Yeah but we can use the custom one that prints astNodes π https://github.com/graphql/graphql-js/issues/869#issuecomment-374351118
@19majkel94
Yes, always there's a solutionπ
I tested that snippet but it didn't work (because of lacking astNodes for Query and other types). So modified the original printSchema
to print them. https://github.com/Hossein-s/type-graphql-schema-directives/commit/fb236bee9afcf6aafca446d75ce0a437a35c75ca
Hey @Hossein-s @19majkel94 , What's the currnet status of this? I was investigating this some time ago for https://github.com/prisma/nexus/issues/53#issuecomment-467169476 I have some time now and would like to help you solve and test this.
Yes please I would love to add field meta data from directives as well for use in the UI. My intent was to convert the schema in full server side and hang somewhere so the client can pull in all the meta data for UI auto generation.
Hey @Hossein-s, is your solution working ? I'm really interested to add directive to field
@Hossein-s Thanks for your idea, and I finally finished my workaroud repo.
@MichalLytek This is an in-doing, buggy work for schema directive. I'm wondering if this is the right approach?
@snys98 We already have a working implementation of directives support in a pending PR: https://github.com/MichalLytek/type-graphql/pull/369
This issue is partially solved by #369 but it doesn't support all the directives locations like scalars or arguments. So I will leave this issue open to track the work needs to be done in the future.
Are there plans to support Directives on Subscriptions?
@glentakahashi
This issue is partially solved by #369 but it doesn't support all the directives locations
Feel free to open a PR with added support for subscriptions.
Because of #546 and other issues, I've decided to rollback the support for JS-like syntax - now only the SDL string way is supported. Sorry for that, better now than after stable release π
@glentakahashi I've added a test case and subscriptions should also be supported from the beginning π
@MichalLytek thanks for the update! And to clarify, do you mean that directives on subscriptions should now work with the SDL method? Or that they will work in a future method.
@glentakahashi I've only added a test case that is passing: https://github.com/MichalLytek/type-graphql/commit/c6025069e6789cf6a414e0109e64adea50187650
So it was working in November - if it still doesn't work for you (with the SDL approach), please open an issue with and provide a repository with minimal reproducible code example.
Aha! Sorry my confusion was actually in how to implement the SchemaVisitor for the directive. For all other types (query, field, mutation) you override the field.resolve
method, but for specifically subscriptions you must override the field.subscribe
method instead.
So yes it has worked the whole time, I just didn't understand what I was doing
Partially solved by https://github.com/MichalLytek/type-graphql/pull/369
Currently blocked by https://github.com/graphql/graphql-js/issues/1343
Ability to define any arbitrary graphql directive to be passed to the compiled schema:
Which should be equivalent to:
It might be also implemented as a separate decorator that would make possible to create custom decorators like
@CacheControl({ maxAge: 240 })
: