Giter VIP home page Giter VIP logo

Comments (27)

nikis05 avatar nikis05 commented on April 20, 2024 23

v2 is now stable, any advice on how to use it?

from graphql.

diego-d5000 avatar diego-d5000 commented on April 20, 2024 18

I'm using this nestjs module with Apollo 2 in the following way:

app.module.js

import { Module } from '@nestjs/common';
import { GraphQLFactory, GraphQLModule } from '@nestjs/graphql';
import { ApolloServer } from 'apollo-server-express';
import { LostPetsResolver } from 'lost-pets/lost-pets.resolvers';
import { LostPetsService } from './lost-pets/lost-pets.service';

@Module({
  imports: [GraphQLModule],
  providers: [LostPetsService, LostPetsResolver], // Provide services and resolvers
})
export class AppModule {
  // Inject graphQLFactory as in Nestjs Docs
  constructor(private readonly graphQLFactory: GraphQLFactory) { }

  configureGraphQL(app: any) {
    // Same as nestjs docs - graphql guide
    const typeDefs = this.graphQLFactory.mergeTypesByPaths('./**/*.graphql');
    const schema = this.graphQLFactory.createSchema({ typeDefs });

    // this changed. Apollo lib internally apply app.use(...)
    // and other middlewares to work
    // but it needs app object
    const server = new ApolloServer({ schema });
    server.applyMiddleware({ app });
  }
}

And then I give the app object to this method:

main.ts

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  // With Nestjs context get the app module to call our configure method
  const appModule = app.get(AppModule);
  appModule.configureGraphQL(app);

  await app.listen(3000);
}
bootstrap();

Thanks.

from graphql.

kamilmysliwiec avatar kamilmysliwiec commented on April 20, 2024 12

Apollo v2 integration is now available. Also, the docs + example have been updated as well https://docs.nestjs.com/graphql/quick-start

from graphql.

kamilmysliwiec avatar kamilmysliwiec commented on April 20, 2024 9

The [email protected] is not stable yet. We'll support it once it hits the final release.

from graphql.

mnlttt avatar mnlttt commented on April 20, 2024 8

@cschroeter there's how I've upgraded:

import * as jwt from 'jsonwebtoken';
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { GqlExecutionContext } from '@nestjs/graphql';

@Injectable()
export class AuthGuard implements CanActivate {
    constructor(private readonly authService: AuthService) {}

    canActivate(
        context: ExecutionContext,
    ): boolean | Promise<boolean> | Observable<boolean> {
        const ctx = GqlExecutionContext.create(context);
        const request = ctx.getContext().request;

        const token = request.headers.authorization
            ? (request.headers.authorization as string).split(' ')
            : null;

        if (process.env.NODE_ENV === 'development') {
            return true;
        }

        if (token && token[1]) {
            const decoded: any = jwt.verify(token[1], process.env.SECRET);

            return !!this.authService.findById(decoded.id);
        }
    }
}
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
@Module({
    imports: [
        GraphQLModule.forRoot({
            typePaths: ['./**/*.gql'],
            debug: true,
            playground: true,
            tracing: true,
            path: '/api/graphql',
            context: ({ req, res }) => ({
                request: req,
            }),
            rootValue: ({ req }) => ({ req }),
        }),
    ],
})
export class GQLModule {}

from graphql.

cschroeter avatar cschroeter commented on April 20, 2024 4

@arjitkhullar Here is an example including subscription handling:

import { Module } from '@nestjs/common';
import { GraphQLFactory, GraphQLModule } from '@nestjs/graphql';
import { ApolloServer } from 'apollo-server-express';
import { LostPetsResolver } from 'lost-pets/lost-pets.resolvers';
import { LostPetsService } from './lost-pets/lost-pets.service';

@Module({
  imports: [GraphQLModule],
  providers: [LostPetsService, LostPetsResolver], // Provide services and resolvers
})
export class AppModule {
  // Inject graphQLFactory as in Nestjs Docs
  constructor(private readonly graphQLFactory: GraphQLFactory) { }

  configureGraphQL(app: any, httpServer: any) {
    // Same as nestjs docs - graphql guide
    const typeDefs = this.graphQLFactory.mergeTypesByPaths('./**/*.graphql');
    const schema = this.graphQLFactory.createSchema({ typeDefs });

    // this changed. Apollo lib internally apply app.use(...)
    // and other middlewares to work
    // but it needs app object
    const server = new ApolloServer({ schema });
    server.applyMiddleware({ app });
    server.installSubscriptionHandlers(httpServer);
  }
}
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  // With Nestjs context get the app module to call our configure method
  const appModule = app.get(AppModule);
  const httpServer = app.getHttpServer();
  appModule.configureGraphQL(app, httpServer);

  await app.listen(3000);
}
bootstrap();

from graphql.

diego-d5000 avatar diego-d5000 commented on April 20, 2024 3

@viiiprock You can't apply this configureGraphQL method in that way because isn't a middleware, it doesn't receive req,res,next params. I'm navigating through Apollo 2 code, but I don't find any middleware like function/method yet to do that. Default Apollo 2 route is "/graphql", but you could change it in applyMiddleware method:

const server = new ApolloServer({ schema });
const path = '/api/graphql';
server.applyMiddleware({ app, path });

from graphql.

zuohuadong avatar zuohuadong commented on April 20, 2024 3

+1
v2 is now stable, any advice on how to use it?

from graphql.

cschroeter avatar cschroeter commented on April 20, 2024 2

Unfortunately if you use nestjs/passport it can no extract headers from the execution context. Ending up an internal error
TypeError: Cannot read property 'headers' of undefined", " at JwtStrategy._jwtFromRequest (/Users/cschroeter/Workspace/Edomo/edomo-middleware/node_modules/passport-jwt/lib/extract_jwt.js:58:21)

from graphql.

viiiprock avatar viiiprock commented on April 20, 2024 1

@kyle-mccarthy I do, seems it came from playground, but you could try

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  // With Nestjs context get the app module to call our configure method
  const appModule = app.get(AppModule);
  appModule.configureGraphQL(app);
  app.use('/graphql', () => {}); // Add route here
  await app.listen(3000);
}
bootstrap();

And it will do the trick.
I don't use Playground anyway, Insomnia is better ;)

from graphql.

diego-d5000 avatar diego-d5000 commented on April 20, 2024 1

Nice. Thanks @viiiprock, It seems that it's a graphql-playground issue:
graphql/graphql-playground#557

from graphql.

cschroeter avatar cschroeter commented on April 20, 2024 1

@viiiprock Sure you can access your context within the AuthGuard - no problem. But you can not access your request headers for example. You would need to extract them in the ApplicationModule from the req and then implement your authentication by urself instead of reusing the @nestjs/passport and @nestjs/jwtmodule.

from graphql.

viiiprock avatar viiiprock commented on April 20, 2024

Yeah, I'll move to nest js until it support Apollo 2

from graphql.

viiiprock avatar viiiprock commented on April 20, 2024

@diego-d5000 I haven't start with Nest yet but watching on it. So, based on your setup, how to expose graphql endpoint? Is it like:

  configure(consumer: MiddlewareConsumer) {
    consumer.apply(this.configureGraphQL).forRoutes('/graphql');
  }

from graphql.

viiiprock avatar viiiprock commented on April 20, 2024

great, I should make a try. Thanks @diego-d5000

from graphql.

kyle-mccarthy avatar kyle-mccarthy commented on April 20, 2024

@diego-d5000 do you have an issue with additional headers being sent when loading the graphql playground? I am seeing Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client in my app logs when visiting the URL the playground lives at.

from graphql.

agborkowski avatar agborkowski commented on April 20, 2024

@diego-d5000 wrote up how to do it, works like harm or just pull request to nest graphql module new version :)

from graphql.

arjitkhullar avatar arjitkhullar commented on April 20, 2024

How about graphql-subscriptions.

from graphql.

zuohuadong avatar zuohuadong commented on April 20, 2024

@kamilmysliwiec v2 is now stable.

from graphql.

krivochenko avatar krivochenko commented on April 20, 2024

@cschroeter I encountered with the same issue when I tried to use @nestjs/passport. Just for test I implemented simple guard:

import { CanActivate, Injectable } from '@nestjs/common';

@Injectable()
export class AuthGuard implements CanActivate {
  canActivate(context) {
    const httpContext = context.switchToHttp();
    console.log(httpContext.getRequest());
    return true;
  }
}

and console.log output is undefined. By the same reason passport can't get headers from request. Do you have any solution? Thanks for help.

from graphql.

sofyan-ahmad avatar sofyan-ahmad commented on April 20, 2024

@cschroeter I encountered with the same issue when I tried to use @nestjs/passport. Just for test I implemented simple guard:

import { CanActivate, Injectable } from '@nestjs/common';

@Injectable()
export class AuthGuard implements CanActivate {
  canActivate(context) {
    const httpContext = context.switchToHttp();
    console.log(httpContext.getRequest());
    return true;
  }
}

and console.log output is undefined. By the same reason passport can't get headers from request. Do you have any solution? Thanks for help.

I have the same issue, any solutions for this?

from graphql.

kamilmysliwiec avatar kamilmysliwiec commented on April 20, 2024

@sofyanhadia just look at the docs https://docs.nestjs.com/graphql/tooling "Execution Context"

from graphql.

w0wka91 avatar w0wka91 commented on April 20, 2024

@sofyanhadia #48

from graphql.

cschroeter avatar cschroeter commented on April 20, 2024

Using the AuthGuard within the GraphQL context is not possible. The context is not aware of any request object. So the JWT module tries to extract the Authorization header from the request object which is undefined. I'm not sure how to switch to original request object provided by the epxress instance, as already mentioned in #48. So right now I don't see any possibility to guard your GraphQL endpoints, which is kinda bad, i guess

from graphql.

viiiprock avatar viiiprock commented on April 20, 2024

@cschroeter
I don't get it, why need instance? Didn't the Apollo provide original request object by the context ? With Nest, it wrapped around GraphQLModule.forRoot({...context: async({req}) => ..... })
And the AuthGuard is really simple to implement.

@Injectable()
export class AuthGuard implements CanActivate {
  canActivate(
    context: ExecutionContext,
  ): boolean | Promise<boolean> | Observable<boolean> {
    const ctx = GqlExecutionContext.create(context);
    // you can get context by using `ctx.getContext()`
    return ctx && true;
  }
}

before update, I did something quite tricky, but it worked like a charm

@Injectable()
export class AuthGuard implements CanActivate {
  canActivate(
    context: ExecutionContext,
  ): boolean | Promise<boolean> | Observable<boolean> {

    // => get the context object with `context.getArgs()[2]`;

  }

from graphql.

viiiprock avatar viiiprock commented on April 20, 2024

got it , I don't use those stuff, I implemented jwt my self with jsowebtoken

from graphql.

lock avatar lock commented on April 20, 2024

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

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.