Nest 포함 GraphQL 구독: 실행 중인 여러 서버에서 게시하는 방법
본문의 선결 조건:
Docker이 당신의 기계에 설치되어 있습니다.
그럼 상황을 봐야지.서버에 인스턴스가 하나만 있을 경우 Redis가 필요하지 않습니다.
단, 응용 프로그램을 확장하고 추가 서버 실례를 생성할 때, 한 실례에 발표된 이벤트가 다른 실례의 구독자에게 수신될 수 있도록 확보해야 한다.이것은 기본 구독이 당신을 위해 할 수 없는 일입니다.
따라서 기본 구독을 사용하여 기본적인 GQL 응용 프로그램을 구축하는 것부터 시작합니다.
먼저
@nestjs/cli
을 설치합니다.npm i -g @nestjs/cli
그런 다음 새 NestJS 프로젝트를 만듭니다.nest new nestjs-gql-redis-subscriptions
이제
nestjs-gql-redis-subscriptions/src/main.ts
을 열고 변경합니다.await app.listen(3000);
받는 사람:await app.listen(process.env.PORT || 3000);
이것은 우리가 필요할 때 envvar를 통해 포트를 지정할 수 있도록 합니다.NestJS는 매우 신뢰할 수 있는 GQL 지원을 가지고 있지만, 이를 이용하기 위해 추가 의존 항목을 설치해야 합니다.
cd nestjs-gql-redis-subscriptions
npm i @nestjs/graphql apollo-server-express graphql-tools graphql graphql-subscriptions
우리는 또한 graphql-subscriptions
을 설치했는데, 이것은 우리의 응용 프로그램에 구독을 가져왔다.구독의 실제 상황을 보기 위해 우리는 "탁구"응용 프로그램을 구축할 것입니다. 그 중에서
ping
은 GQL mutation
을 통해, pong
은 GQL subscription
을 통해 발송됩니다.src
디렉터리에서 types.graphql
파일을 만들고 우리의 모드를 거기에 두십시오.type Query {
noop: Boolean
}
type Mutation {
ping: Ping
}
type Subscription {
pong: Pong
}
type Ping {
id: ID
}
type Pong {
pingId: ID
}
그런 다음 app.module.ts
으로 이동하여 GraphQLModule
을 다음과 같이 가져옵니다.// ... other imports
import { GraphQLModule } from '@nestjs/graphql';
import { PubSub } from 'graphql-subscriptions';
@Module({
imports: [
GraphQLModule.forRoot({
playground: true,
typePaths: ['./**/*.graphql'],
installSubscriptionHandlers: true,
}),
],
providers: [
{
provide: 'PUB_SUB',
useValue: new PubSub(),
},
],
})
export class AppModule {}
GraphQLModule.forRoot
에 전달되는 옵션을 살펴보겠습니다.playground
-http:localhost:${PORT}/graphql
에 GQL Playground을 노출한다.우리는 이 도구를 사용하여'탁구'사건을 구독하고'탁구'돌변을 보낼 것이다.installSubscriptionHandlers
- 구독 지원 활성화 typePaths
-GQL 유형에 정의된 경로입니다.{
provide: 'PUB_SUB',
useValue: new PubSub(),
}
이것은 게시/구독 엔진의 기본 (메모리) 구현입니다. 이벤트를 발표하고 구독을 만들 수 있습니다.이제 GQL 서버를 구성한 후에 해상도를 만들 때가 되었습니다.
src
폴더에서 ping-pong.resolvers.ts
파일을 만들고 다음 내용을 입력합니다.import { Resolver, Mutation, Subscription } from '@nestjs/graphql';
import { Inject } from '@nestjs/common';
import { PubSubEngine } from 'graphql-subscriptions';
const PONG_EVENT_NAME = 'pong';
@Resolver('Ping')
export class PingPongResolvers {
constructor(@Inject('PUB_SUB') private pubSub: PubSubEngine) {}
@Mutation('ping')
async ping() {
const pingId = Date.now();
this.pubSub.publish(PONG_EVENT_NAME, { [PONG_EVENT_NAME]: { pingId } });
return { id: pingId };
}
@Subscription(PONG_EVENT_NAME)
pong() {
return this.pubSub.asyncIterator(PONG_EVENT_NAME);
}
}
우선, 우리는 PingPongResolvers
으로 @Resolver('Ping')
류를 장식해야 한다.NestJS 공식 문서는 그 목적을 잘 설명합니다.너는 새둥지에 문의해도 된다.js 공식 문서 Working with GraphQL
The
@Resolver()
decorator does not affect queries or mutations (neither@Query()
nor@Mutation()
decorators). It only informs Nest that each@ResolveProperty()
inside this particular class has a parent, which is aPing
type in this case.
그리고
ping
의 돌연변이를 정의했습니다.그 주요 직책은 pong
사건을 발표하는 것이다.마지막으로 구독 정의가 생겼습니다. 구독한 클라이언트에게 적당한 이벤트를 보내는 것을 책임집니다.
PingPongResolvers
을 AppModule
에 추가해야 합니다.// ...
@Module({
// ...
providers: [
PingPongResolvers,
{
provide: 'PUB_SUB',
useValue: new PubSub(),
},
],
})
export class AppModule {}
현재, 우리는 이미 응용 프로그램을 시작하고, 우리의 실제 실현을 볼 준비가 되어 있다.실제로 메모리 구독 문제를 이해하기 위해 두 개의 응용 프로그램을 실행합니다. 하나는 포트 3000에 있고, 다른 하나는 포트 3001에 있습니다.
터미널 창에서 다음을 실행합니다.
# port 3000 is the default port for our app
npm start
다음 예제에서는PORT=3001 npm start
다음 프레젠테이션은 다음과 같습니다.보시다시피: 3001에서 실행된 실례는: 3000 실례에서 발표된 어떤 이벤트도 얻지 못했습니다.
다음 그림은 다양한 각도에서 볼 수 있습니다.
분명히: 3001: 3000에 게시된 이벤트를 볼 수 없습니다.
이제 우리 응용 프로그램을 좀 조정해서 이 문제를 해결합시다.우선, Redis 구독 종속성을 설치해야 합니다.
npm i graphql-redis-subscriptions ioredis
graphql-redis-subscriptions
은 PubSubEngine
인터페이스의 Redis 감지 실현을 제공합니다: RedisPubSub
.이전에 이 인터페이스를 사용한 적이 있습니다. 메모리를 통해 -PubSub
을 실현합니다.ioredis
-은(는) graphql-redis-subscriptions
에서 사용하는 Redis 클라이언트입니다.우리의
RedisPubSub
을 사용하기 시작하려면 AppModule
을 조금만 조정하면 됩니다.이 항목을 변경하려면 다음과 같이 하십시오.
// ...
{
provide: 'PUB_SUB',
useValue: new PubSub(),
}
// ...
다음을 수행합니다.// ...
import { RedisPubSub } from 'graphql-redis-subscriptions';
import * as Redis from 'ioredis';
// ...
// ...
{
provide: 'PUB_SUB',
useFactory: () => {
const options = {
host: 'localhost',
port: 6379
};
return new RedisPubSub({
publisher: new Redis(options),
subscriber: new Redis(options),
});
},
},
// ...
docker 컨테이너에서 redis를 시작하여 localhost:6379
에서 사용할 수 있도록 합니다(위 RedisPubSub
인스턴스에 대한 옵션).docker run -it --rm --name gql-redis -p 6379:6379 redis:5-alpine
이제 애플리케이션을 중지하고 다시 시작해야 합니다(다른 터미널 세션에서):
npm start
화목하다PORT=3001 npm start
이 때, 구독은 예상대로 작동하고, 응용 프로그램의 한 사례에 발표된 이벤트는 클라이언트가 수신하고, 다른 사례에 구독합니다.다음은 엔진 덮개 아래에서 발생한 일입니다.
요약:
본고에서 우리는 Redis와 GQL을 사용하여 크로스 서버 응용 프로그램에 가입하는 여러 가지 실례를 통해 이벤트를 발표하는 방법을 배웠다.
우리는 또한 GQL 구독 이벤트 발표/구독 흐름을 더욱 잘 이해해야 한다.
소스 코드:
https://github.com/rychkog/gql-redis-subscriptions-article
이 문장을 좋아합니까?This Dot Labs으로 가서 우리를 보세요!우리는 자바스크립트와 전단의 모든 업무에 종사하는 기술 컨설팅 회사입니다.Angular, React 및 Vue 등의 소스 소프트웨어에 집중합니다.
Reference
이 문제에 관하여(Nest 포함 GraphQL 구독: 실행 중인 여러 서버에서 게시하는 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/thisdotmedia/graphql-subscriptions-with-nest-how-to-publish-across-multiple-running-servers-15e텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)