Giter VIP home page Giter VIP logo

Comments (12)

Tarjei400 avatar Tarjei400 commented on April 19, 2024 6

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.

Tarjei400 avatar Tarjei400 commented on April 19, 2024 1

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.

sebastian-schlecht avatar sebastian-schlecht commented on April 19, 2024 1

Any update on the intended way to do this? We would simply need the default @Skip and @include directives.

from graphql.

anodynos avatar anodynos commented on April 19, 2024

The more I read into graphql (I'm still a newbie), the more I think NestJs should embrace SchemaDirectives instead / also :-)

from graphql.

anodynos avatar anodynos commented on April 19, 2024

Any updates on this issue?

from graphql.

kamilmysliwiec avatar kamilmysliwiec commented on April 19, 2024

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.

anodynos avatar anodynos commented on April 19, 2024

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.

blissi avatar blissi commented on April 19, 2024

@kamilmysliwiec I am also interested in an example how to add directive support "the intended way".

from graphql.

Tarjei400 avatar Tarjei400 commented on April 19, 2024

@sebastian-schlecht check out couple of comments above, I posted some workaround to this

from graphql.

Ponjimon avatar Ponjimon commented on April 19, 2024

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.

volbrene avatar volbrene commented on April 19, 2024

@lookapanda I have open a ticket for that problem. Hope anyone can add the new version from type-graphql:

#618

from graphql.

leohxj avatar leohxj commented on April 19, 2024

@Ponjimon
The @directive() decorator is exported from the @nestjs/graphql package.

from graphql.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.