Comments (12)
I made some PoC on how to use dependency injection in Directive classes, it requires one ugly hack but looks slick.
graphql.module.ts
@Module({
imports: [
GraphQLModule.forRootAsync({
useFactory(factory: DirectivesFactory) {
return {
typePaths: ['./**/*.graphql'],
debug: true,
playground: true,
installSubscriptionHandlers: true,
definitions: {
path: join(process.cwd(), 'src/graphql.schema.ts'),
outputAs: 'class',
},
transformSchema: (schema: GraphQLSchema) => {
return mergeSchemas({schemas: [schema], schemaDirectives: factory.register() });
}
};
},
imports: [DirectivesModule],
inject: [DirectivesFactory]
}),
directives.module.ts
import {HttpModule, Module} from '@nestjs/common';
import {DirectivesFactory} from "./directives.factory";
@Module({
imports: [HttpModule],
providers: [ DirectivesFactory],
exports: [ DirectivesFactory ]
})
export class DirectivesModule {}
directives.factory.ts
import {Inject, Injectable} from "@nestjs/common";
import {SchemaDirectiveVisitor} from "graphql-tools";
import {RestDirective} from "./rest-directive";
@Injectable()
export class DirectivesFactory {
@Inject()
restDirective: RestDirective;
register() {
return {
rest: this.restDirective.build()
}
}
}
And last one rest-directive.ts
import {HttpService, Inject, Injectable} from "@nestjs/common";
import {SchemaDirectiveVisitor} from "graphql-tools";
type DirectiveArguments = {
[name: string]: any;
}
@Injectable()
export class RestDirective {
@Inject()
private http: HttpService;
async visitFieldDefinition(args: DirectiveArguments){
const { url } = args;
const response = await this.http.get(url).toPromise();
return response.data;
}
build(): typeof SchemaDirectiveVisitor {
const rest = this;
class Directive extends SchemaDirectiveVisitor {
public visitFieldDefinition(field) {
field.resolve = async () => await rest.visitFieldDefinition(this.args);
}
}
return Directive
}
}
from graphql.
Then you use can use it like this from schema:
directive @rest(url: String) on FIELD_DEFINITION
# the schema allows the following query:
type Query {
getWeather: WeatherResponse @rest(url: "https://samples.openweathermap.org/data/2.5/weather?lat=35&lon=139&appid=b6907d289e10d714a6e88b30761fae22")
}
from graphql.
Any update on the intended way to do this? We would simply need the default @Skip and @include directives.
from graphql.
The more I read into graphql (I'm still a newbie), the more I think NestJs should embrace SchemaDirectives instead / also :-)
from graphql.
Any updates on this issue?
from graphql.
New 5.0.0
has been released.
Nevertheless, we didn't ship @DirectiveResolver()
decorator. GraphQLModule
is compatible with directives though. The reason for this is that Apollo forces us to pass types, instead of the concrete instances of the resolvers. Therefore, directive resolvers won't be able to access the injector and internal Nest module context because we can't register them as providers.
To register directive resolver, simply pass directiveResolvers
array to the GraphQLModule.forRoot()
method.
from graphql.
Thanks @kamilmysliwiec - can you provide a simplistic working example?
I think it will be useful for any future reference as well.
PS: I made it work as PoC back with NestJs 4.6 & @nestjs/graphql 2.0.0 with this hack:
configure() {
const self = this;
// @note: we need an unbound function here, not a () =>
this.graphQLFactory.createSchema = function(
schemaDefintion = { typeDefs: [] },
) {
return makeExecutableSchema({
...schemaDefintion,
directiveResolvers: self.directiveResolvers,
resolvers: {
...this.resolversExplorerService.explore(), // ignore private error, its a hack anyway!
...(schemaDefintion.resolvers || {}),
},
});
};
const schema = this.graphQLFactory.createSchema({ typeDefs });
....
}
from graphql.
@kamilmysliwiec I am also interested in an example how to add directive support "the intended way".
from graphql.
@sebastian-schlecht check out couple of comments above, I posted some workaround to this
from graphql.
Is there any workaround how I can use directives in a code-first approach? type-graphql
introduced a @Directive
decorator, but I cannot use it with NestJS :(
from graphql.
@lookapanda I have open a ticket for that problem. Hope anyone can add the new version from type-graphql:
from graphql.
@Ponjimon
The @directive() decorator is exported from the @nestjs/graphql package.
from graphql.
Related Issues (20)
- Enabling ts-morph v20.x HOT 1
- MappedType PartialType throws error when using option decorator factory input HOT 7
- definitions with option skipResolverArgs: true makes resolvers optional in d.ts HOT 5
- Using multiple `@ArgsType()` classes combines those arguments into one object and assigns it to all parameters which are an `@ArgsType` HOT 1
- Support for namespacing queries and mutations
- Always response Cannot return null for non-nullable field level2.level3 for nested resolver HOT 1
- GraphQL endpoints are not protected by the global Guards. HOT 2
- Nest can't resolve dependencies of the ApolloDriver. HOT 2
- TypeError: this.graphQlFactory.mergeWithSchema is not a function HOT 1
- If the sortSchema option is true, you want to sort the types, but not the fields. HOT 1
- CLI doesn't register object union with null HOT 1
- Add jsdoc for `debug` and `introspection` in `GraphQLModule` HOT 5
- TypeScript definitions generated with wrong case HOT 2
- `GraphQLModule` should throw an error if schema files are not found HOT 2
- Expose GraphQLModule options and gqlSchemaHost to support Serverless
- How to send partial data with error object using @Context
- CustomScalar parseLiteral doesn't allow null return type HOT 2
- Unable to Specify forRoutes Argument When Assigning Middleware to '/graphql' Endpoint
- ResolveField shouldn't be called when the field already has a value HOT 1
- Support for Custom Fields Decorators in Mapped types
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from graphql.