Apollo Server와 Prisma를 이용한 자바스크립트 실시간 데이터 동기화

지금까지 웹 애플리케이션의 실시간 데이터 동기화를 구현하기 위해서는 여러 가지 기술과 도구를 사용해야 했습니다. 그러나 Apollo Server와 Prisma를 이용하면 간편하게 자바스크립트(JavaScript) 기반의 웹 애플리케이션에서도 실시간 데이터 동기화를 구현할 수 있습니다. 이번 글에서는 Apollo Server와 Prisma를 사용하여 자바스크립트로 실시간 데이터 동기화를 구현하는 방법을 알아보겠습니다.

1. Apollo Server란?

Apollo Server는 GraphQL을 위한 강력한 서버 사이드 프레임워크입니다. Apollo Server를 사용하면 쉽게 GraphQL 스키마를 정의하고, 데이터를 조회하고, 변이(mutations)를 수행할 수 있습니다. 또한 Apollo Server는 실시간 데이터 동기화를 지원하여 데이터가 변경될 때마다 클라이언트에게 실시간으로 업데이트를 제공할 수 있습니다.

2. Prisma란?

Prisma는 데이터베이스를 다루는 일련의 작업을 쉽게 처리할 수 있는 ORM(Object-Relational Mapping) 도구입니다. Prisma를 사용하면 자바스크립트로 데이터베이스에 접근하고 쿼리를 작성하는 작업을 더욱 간편하게 처리할 수 있습니다. Prisma는 데이터의 변경 이벤트를 자동으로 감지하고 Apollo Server에 실시간 업데이트를 전달하는 기능을 제공합니다.

3. Apollo Server와 Prisma를 이용한 실시간 데이터 동기화 구현 방법

3.1 데이터베이스 모델 정의

먼저 Prisma를 사용하여 데이터베이스 모델을 정의합니다. Prisma는 데이터베이스 스키마를 이용하여 자동으로 데이터베이스 접근을 위한 코드를 생성할 수 있습니다. 예를 들어, 사용자(User)와 포스트(Post)라는 두 개의 데이터베이스 테이블을 정의하고 관계를 설정할 수 있습니다.

model User {
  id    String  @id @default(uuid())
  name  String
  posts Post[]
}

model Post {
  id     String  @id @default(uuid())
  title  String
  author User    @relation(fields: [authorId], references: [id])
  authorId String
}

3.2 Apollo Server 설정

Apollo Server를 설정하여 GraphQL 스키마와 리졸버를 정의합니다. 이때 Prisma를 사용하여 데이터베이스와 연동합니다. 예를 들어, 사용자(User) 정보를 조회하는 리졸버를 작성할 수 있습니다.

const { ApolloServer, gql } = require('apollo-server');
const { PrismaClient } = require('@prisma/client');

const prisma = new PrismaClient();

const typeDefs = gql`
  type User {
    id: String
    name: String
    posts: [Post]
  }

  type Query {
    getUser(id: String!): User
  }
`;

const resolvers = {
  Query: {
    getUser: async (_, { id }) => {
      return prisma.user.findUnique({
        where: {
          id,
        },
        include: {
          posts: true,
        },
      });
    },
  },
};

const server = new ApolloServer({
  typeDefs,
  resolvers,
});

3.3 실시간 데이터 동기화 구현

마지막으로 Apollo Server에 Prisma의 실시간 업데이트를 위한 기능을 추가합니다. 이를 위해 pubsub 객체와 withFilter 함수를 사용하여 데이터의 변경 이벤트를 구독하고, 변경된 데이터를 실시간으로 업데이트할 수 있습니다.

const { ApolloServer, gql, PubSub, withFilter } = require('apollo-server');
const { PrismaClient } = require('@prisma/client');

const prisma = new PrismaClient();
const pubsub = new PubSub();

const typeDefs = gql`
  type User {
    id: String
    name: String
    posts: [Post]
  }

  type Post {
    id: String
    title: String
    author: User
    authorId: String
  }

  type Query {
    getUser(id: String!): User
  }

  type Subscription {
    postAdded: Post
  }
`;

const resolvers = {
  Query: {
    getUser: async (_, { id }) => {
      return prisma.user.findUnique({
        where: {
          id,
        },
        include: {
          posts: true,
        },
      });
    },
  },
  Subscription: {
    postAdded: {
      subscribe: withFilter(
        () => pubsub.asyncIterator('POST_ADDED_CHANNEL'),
        (payload, variables) => {
          // 특정 사용자의 포스트 변경 이벤트만 필터링하여 구독합니다.
          return payload.postAdded.authorId === variables.userId;
        }
      ),
    },
  },
};

const server = new ApolloServer({
  typeDefs,
  resolvers,
  subscriptions: {
    onConnect: () => console.log('Connected to websocket'),
    onDisconnect: () => console.log('Disconnected from websocket'),
  },
});

server.listen().then(({ url }) => {
  console.log(`🚀 Server ready at ${url}`);
});

위의 예시에서는 postAdded라는 이름의 Subscription을 정의하고, pubsub.asyncIterator 함수를 사용하여 POST_ADDED_CHANNEL 채널의 변경 이벤트를 구독합니다. withFilter 함수를 사용하여 특정 사용자의 포스트 변경 이벤트만 필터링하여 구독할 수 있습니다.

실제로 서버에서 데이터가 변경되면 pubsub.publish 함수를 사용하여 변경된 데이터를 POST_ADDED_CHANNEL 채널로 전달합니다. 이렇게 전달된 데이터는 클라이언트의 Subscription에서 실시간으로 업데이트됩니다.

결론

Apollo Server와 Prisma를 사용하여 자바스크립트 기반의 웹 애플리케이션에서 실시간 데이터 동기화를 쉽게 구현할 수 있습니다. Apollo Server를 통해 GraphQL 스키마를 정의하고, Prisma를 사용하여 데이터베이스와 연동하며, pubsub과 withFilter를 이용하여 실시간 업데이트를 구현할 수 있습니다. 이러한 기술과 도구를 적절히 활용하면 웹 애플리케이션에서 쉽게 실시간 데이터 동기화를 구현할 수 있습니다.

*참고 자료:

#graphql #javascript