본문 바로가기
서버 개발/GraphQL

[GraphQL] Subscription: Realtime, 양방향 통신 서버

by JIMYEONG 2024. 9. 12.
반응형

요즘 웹사이트 이용하다보면, Socket 통신이 요즘 트렌드 인것 같다.

 

익숙해져서 일까?

 

GraphQL공부할겸,  Todo list를 만드는데,

새로고침 해야지만 업데이트가 반영되는 것이 눈에 영 거슬리고, 지나칠 수가 없다.

 

서버에서 클라이언트로 메시지를 보내기 위해서,

GraphQL의 Subscription 이라는 섹션 을 공부했다.

 

과거에, nodeJS에서는 채팅서버 구현해서, 서비스 해본적이 있었는데,

또 다른 library를 쓰니깐, 용어부터, 참 새롭다

 

Express, Socket.io 조합 에서는 이벤트 리스너를 등록하고, 서버에서 이벤트를 발생시킬 수도 있어서, 

직관적이었고, 사용하기 쉬웠다. 

 

그런데, ApolloQL에서는, 서버에서 어떻게 클라이언트로 이벤트를 날리겠다는 건지,  메카니즘이 잘 이해가 안됐다.

문서를 몇번씩 들여다보면서, 드디어 기본적인 원리를 파악해서 정리해본다.

 

응용 할 수 있는 방법과, 예외는 항상 있겠지만,


일반적으로는, Client에서 Mutation 이벤트를 서버로 전달할 때, 서버에서 해당 코드 블럭에서, Subscription 에 등록되 있는 관련 함수를 호출하고, 그 블럭 안에서 다시 클라이언트로 메시지를 보낸다.

 

GraphQL에서, Server에서 클라이언트에 메시지를 보내는 메커니즘

 

요약하면,

서버에선, Mutation 으로 입력을 받아서, Subscription 으로 돌리고,

Subscription에서 클라이언트로 이벤트를 내보낸다.

 

 

Server side

Example)

import { PubSub } from "graphql-subscriptions";

const pubsub = new PubSub();

const resolver = {
    Subscription: {
        postCreated: {
            subscribe: () => pubsub.asyncIterator(["**POST_CREATED**"]),
        }
    }
    
    ...,
    
    Mutation: {
    
    	..., 
        
        createPost: (variables) => {
        
            // Subscription에 등록된, POST_CREATED로 variables를 넘긴다.
                pubsub.publish("**POST_CREATED**", { postCreated: variables });
                return variables;
            },
  	},
}
반응형

 

typeDefs.ts

Server side

const typeDefs = `#graphql
    type Query{
        hello: String
    }
    type Mutation{
        createPost(author: String, comment: String):Post
    }
    type Post{
        author: String
        comment: String
    }
    type Subscription{
        postCreated: Post
        
    }
`;

export { typeDefs };

 

Client side

const CREATE_POST = gql`
  mutation createPost($author: String!, $comment: String!) {
    createPost(author: $author, comment: $comment) {
      author
      comment
    }
  }
`;

const SUBSCRIPTION_UPDATED = gql`
  subscription postFeed {
    postCreated {
      author
      comment
    }
  }
`;

const App = ()=>{
    const [createPost, {}] = useMutation(CREATE_POST, {
    variables: { author: "hello", comment: "world" },
  }); 
    
    const { data, loading } = useSubscription(SUBSCRIPTION_UPDATED);
    const { postCreated } = data || {};
    
    // data.postCreaed.author = 'hello'
    // data.postCreaed.comment = 'world'
    console.log(data)
    return <>EXAMPLE<>

}

요렇게 구성을 하고나면,

클라이언트에서 서버쪽으로 Mutation: createPost 요청을 했을 때, 서버에서 클라이언트로 variables변수를 보내준다.

 

소스코드: https://github.com/jimyeong/graphql_study/tree/feature/subscription_basic

 

GitHub - jimyeong/graphql_study

Contribute to jimyeong/graphql_study development by creating an account on GitHub.

github.com

 

반응형