[Prisma] 메시지 보내기

Review/백엔드 - 인스타그램 클론

[Prisma] 메시지 보내기

조커린 2020. 2. 18. 22:38

데이터 모델

1
2
3
4
5
6
7
8
9
10
11
12
13
type Room {
  id: ID! @id
  participants: [User!]!
  messages: [Message!]!  @relation(name"MessageOfRoom" , onDelete: CASCADE)
}
 
type Message {
  id: ID! @id
  text: String!
  from: User! @relation(name"From")
  to: User! @relation(name"To")
  room: Room! @relation(name"MessageOfRoom"
}
cs

 

Room 내부에서 메시지 보내고 받음

그래서 전체 Rooms를 볼 수 있는 seeRooms 쿼리과 

하나의 룸에서 주고 받는 메시지만 볼 수 있는 seeRoom 쿼리가 있음

 

seeRooms 는 로그인 된 유저이면 볼 수 있도록 만들었고, 

SeeRoom 은 roomId가 데이터 내부에 있는 것과 일치하면 볼 수 있도록 만듬

 

seeRoom.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import { prisma } from "../../../../generated/prisma-client";
import {ROOM_FRAGMENT} from "../../../fragments";
 
export default {
    Query :{
        seeRoom: async (_, args,{request, isAuthenticated}) => {
            isAuthenticated( request);
            const { id } = args;
            const { user } = request;
            const canSee = await prisma.$exists.room({
                participants_some : {
                    id : user.id
                }
            });
 
            if (canSee){
                return prisma.room({ id }).$fragment(ROOM_FRAGMENT);
            } else{
                throw Error (" You can't see this");
             }
        }
    }
}
cs

 

문제는 sendmessage 인데 생각보다 까다로웠다

 

메세지를 보내려면 
내가 participants인 Room을 찾아야 한다.  

 

메세지를 보낸다는 함수를 호출시 roomId 가 있으면 그 곳으로 메세지를 보내고 

없으면 내가 메세지를 보낼 사람과의 room을 만든다.

 

이게 기본 로직이다. 

 

일단 룸아이디가 없을 때 어떤 식으로 리턴되는지 알기 위해서 
sendMessage Mutation 내부에 return null을 하고
console.log( roomId ) 해본다.

 

 

확인 결과 undefined 뜨는 것을 확인할 수 있었다. 

 

참고로 인자는 toId ( 받는 사람)도 추가해줌

 

roomId 가 없을 때 ( 메세지를 주고 받은 적이 없을 때)

1
2
3
4
5
6
7
8
9
10
11
if (roomId === undefined) {
        if (user.id !== toId) {
          room = await prisma
            .createRoom({
              participants: {
                connect: [{ id: toId }, { id: user.id }]
              }
            })
            .$fragment(ROOM_FRAGMENT);
        }
      } 
cs

room 을 만들어서 participants ([User])

array 에는 저런 식으로 데이터를 만들어 줄 수 있다. 

 

 

room이 있을 때 

1
2
3
 else {
        room = await prisma.room({ id: roomId }).$fragment(ROOM_FRAGMENT);
      }
cs

 

 

room 이 없다면 해줄 에러처리까지 완성 후 message의 room 부분은 완성이 되었다.

 

보낼 사람은 participants 라는 array 에서 내가 아닌 사람을 찾는 것이니

1
2
3
const getTo = room.participants.filter(
        participant => participant.id !== user.id
      )[0];
cs

 

만들어준 것들로 최종적으로 createMessage를 return함

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import { prisma } from "../../../generated/prisma-client";
import { ROOM_FRAGMENT } from "../../fragments";
 
export default {
  Mutation: {
    sendMessage: async (_, args, { request, isAuthenticated }) => {
      isAuthenticated(request);
      const { user } = request;
      const { roomId, message, toId } = args;
      let room;
      if (roomId === undefined) {
        if (user.id !== toId) {
          room = await prisma
            .createRoom({
              participants: {
                connect: [{ id: toId }, { id: user.id }]
              }
            })
            .$fragment(ROOM_FRAGMENT);
        }
      } else {
        room = await prisma.room({ id: roomId }).$fragment(ROOM_FRAGMENT);
      }
      if (!room) {
        throw Error("Room not found");
      }
      const getTo = room.participants.filter(
        participant => participant.id !== user.id
      )[0];
      return prisma.createMessage({
        text: message,
        from: {
          connect: { id: user.id }
        },
        to: {
          connect: {
            id: roomId ? getTo.id : toId
          }
        },
        room: {
          connect: {
            id: room.id
          }
        }
      });
    }
  }
};
cs