Apollo-server에서 context는 무엇인가
apollo-server에서 contructor에 지정해주는 context란 다음과 같습니다. 일종의 전역 변수 같은 개념이죠.
An object (or a function that creates an object) that's passed to every resolver that executes for a particular operation. This enables resolvers to share helpful context, such as a database connection.
Certain fields are added to this object automatically, depending on which Node.js middleware your server uses.
For more details, see The context argument.
출처 - www.apollographql.com/docs/apollo-server/api/apollo-server/#constructor
한가지 더 중요한 사실은 첫번째 인자로 Request 객체를 자동으로 가져온다는 겁니다.
미들웨어
=> gql context
=> context를 @Context를 통해 resolver에서 사용하거나 ExecutionContext를 통해CustomDecorator, Guard 등에서 활용합니다.
미들웨어를 통해 req 객체에 원하는 정보를 달아서 전달하면 gql context에서 적당히 정제한 후에 넘겨주는 방식으로 자주 사용합니다.
A request context is available for each request. When context is defined as a function, it will be called on each request and will receive an object containing a req property, which represents the request itself.
By returning an object from the context function, it will be available as the third positional parameter of the resolvers:
new ApolloServer({
typeDefs,
resolvers: {
Query: {
books: (parent, args, context, info) => {
console.log(context.myProperty); // Will be `true`!
return books;
},
}
},
context: async ({ req }) => {
return {
myProperty: true
};
},
})
출처 - github.com/apollographql/apollo-server#context
Nest에서 context를 통해 resolver에서 사용하자
우선 미들웨어를 통해 req 객체에 사용할 정보를 추가해줘야 합니다. 이 부분은 Middleware를 다룬 제 포스트를 참고하시면 됩니다.
어쨋거나 JwtMiddleware를 달아주었고, req.user에 정보를 추가해줬습니다. 이 request 객체는 context의 첫번째 인자로 들어가니 여기서 빼내 사용하면 되겠죠
@Injectable()
export class JwtMiddleWare implements NestMiddleware {
constructor(private readonly jwtService: JwtService, private readonly usersService: UsersService) {}
... 생략
req['user'] = user;
next();
}
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer.apply(JwtMiddleWare).forRoutes({
path: '/graphql',
method: RequestMethod.ALL,
});
}
}
context를 사용할 수 있게 GraphQLModule을 구성해봅시다.
GraphQLModule은 apollo-server-core를 연장한 겁니다. 내부 정의 부분을 참고해보면 ApolloServerBase를 받아 사용한 부분이 보입니다. 이 말은, Apollo에서 제공하는 내용을 통해 gql 서버를 구성할 수 있다는 것입니다.
import { ApolloServerBase } from 'apollo-server-core';
줄 수 있는 속성이 많네요. 각 속성이 무엇을 의미하는지는 공식문서를 참고합시다.
export interface Config extends BaseConfig {
modules?: GraphQLSchemaModule[];
typeDefs?: DocumentNode | Array<DocumentNode> | string | Array<string>;
parseOptions?: GraphQLParseOptions;
resolvers?: IResolvers | Array<IResolvers>;
schema?: GraphQLSchema;
schemaDirectives?: Record<string, typeof SchemaDirectiveVisitor>;
context?: Context | ContextFunction;
... 중략
}
다음과 같이 구성해봅시다.
GraphQLModule.forRoot({
autoSchemaFile: join(process.cwd(), 'src/schema.gql'), // set true if you want to use in memory gql
debug: true,
playground: true,
context: ({ req }) => ({ user: req['user'] }),
}),
일반적으로 resolver에서 (root, args, context, info) => ... 상태로 들어가서 여기에서 사용했습니다만 nest에서는 조금 다릅니다. @nest/graphql에서 @Context를 이용해야 합니다.
@Query(() => User)
getMyProfile(@Context() context) {
if (!context.user) {
return;
} else {
return context.user;
}
}
'Node, Nest, Deno > 🦁 Nest - Series' 카테고리의 다른 글
Nest + Jest unit test (1) Jest configuring (1) | 2020.11.27 |
---|---|
Nest + gql + typeORM(@nestjs/typeorm) (7) typeORM relationsihp (0) | 2020.11.26 |
Nest + gql + typeORM(@nestjs/typeorm) (5)Enum (0) | 2020.11.23 |
Nest + gql + typeORM(@nestjs/typeorm) (4) Mapped Types, @InputType으로 DTO 쉽게 만들기 (2) | 2020.11.22 |
Nest + gql + typeORM(@nestjs/typeorm) (3) Repository pattern, @InjectRepository (0) | 2020.11.21 |