## 음악 조회 기능 구현

풍선을 생성할때 음악을 보여줘야 겠다고 생각했다. 이 링크가 잘못된 링크면 풍선 생성이 실패했다는 토스트가 떠오를텐데 사용자 입장에선 처음부터 다시 입력하기 귀찮다.

때문에 생성할때 첫번째 화면에서 음악 주소를 입력하면서 조회도 하고, 검증하는 기능을 넣었다.

백엔드에 /music?streamingUrl= 으로 GET 요청을 보내는 방식이다.

 

## 알록달록 풍선

풍선의 색깔을 좀 다양하게 만들어봤다. 

색은 풍선 엔티티에 직접 저장되며 아래와 같이 풍선 추가 모달의 두번째 페이지에서 고를 수 있다.

 

이런식으로 다양한 색깔을 제공한다.

위의 헤더의 레이아웃도 손을 봤다. 로고를 중앙에서 왼쪽으로, 기록 과 알림(아래 설명)은 왼쪽으로 배치했다.

 

사실 색깔 팔레트를 제공하고 있지만 사실 직접 백엔드 api를 호출하면 아무 색상이나 선택할 수 있다.

하지만 문자열로 받는다면 정말 이상한 아무값이나 요청할 수도 있어서 Validation 을 만들었다.

public record CreateBalloonRequest(
	…

        @NotNull
        @ColorCode
        @Schema(example = "#F06292")
        String colorCode
) {
}

public class ColorCodeValidator implements ConstraintValidator<ColorCode, String> {

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if (value == null) {
            return true;
        }

        return value.matches("^#[A-Fa-f0-9]{6}$");
    }
}

 

 

## 풍선 기록

이전에 주웠던 풍선의 기록을 다시 볼 수 있게 만들었다.

이 쪽은 어떻게 꾸밀지 몰라서 디자인이 좀 허접하다.

 

그래도 있을 건 다 있다.

 

일단 백엔드 GET /balloon/picked 라는 api를 만들어서 페이지당 풍선을 10개씩 응답해주게 했다.

그런 뒤에 프론트엔드 에서는 리스트의 스크롤을 마지막까지 내리면 다음 페이지를 불러와서 갱신하는 로직으로 만들었다.

이해가 잘 안된다면 유튜브의 검색 기록과 비슷하게 아래로 내리면 계속 불러오게끔 구현되어 있다고 생각하면 좋다.

 

여기서 각 풍선을 누르면 맵 페이지에서 볼 수 있었던 모달 창이 나타난다.

 

 

## 알림 구현

이 부분은 따로 글을 쓸까 하다가 그냥 같이 쓴다.

다른 사람이 풍선에 반응을 해줬을때 알림이 오게 하고 싶었다. (누가 이 서비스를 쓸까 싶지만..)

이때부터 프론트엔드에서는 MUI 템플릿을 사용했다. 프론트엔드는 이번에 깊게 공부하진 않았지만 대충 알게 된 부분이 있어서 적용하는데 큰 무리는 없었다.

알림을 받으면 상단 알림 이모지에 개수가 뱃지 형태로 표시된다. 

누르면 아래 팝업창이 나오고 누가 어디에 어떤 반응을 보였는지 보여준다.

 

이 알림은 백엔드에서 SseEmitter를 이용해 전송해준다.

Emitter는 GET /notification/reaction/subscribe 로 받아올 수 있게 했다. 이때, 응답의 타입은 text/event-stream 이다.

Server-Send Events(SSE)는 서버 푸시 기술중에 하나인데, 단일 HTTP 커넥션으로 서버가 클라이언트에게 단방향으로 이벤트를 전송해줄 수 있다. 보통 스트리밍 데이터를 전송할때 쓰인다.

 

이벤트는 다음과 같은 형식을 갖는다.

id:[이벤트식별자]

event:[구분]

data:[내용]

 

프론트엔드에서는 위 API를 호출해서 알림을 구독하는데, 이벤트는 EventSource를 이용해서 받아온다.

EventSource는 커넥션을 연결할때 헤더로 Last-Event-Id를 보내는데, 이것으로 미처받지 못했던 이벤트들을 받게 할 수 있다. (헤더로 보내는것만 자동이고 나머지는 백엔드에서 알아서 해야 함)

그래서 난 Notification 의 생성날짜를 이벤트 식별자로 정했다.

또, event는 ‘Reaction-Notification’ data는 응답 dto를 json으로 직렬화해서 넣어줬다.

 

그러니까, 결국 이벤트는 이렇게 된다.

id:[알림의 생성날짜]

event:Reaction-Notification

data:{어쩌고 저쩌고}

 

뭔가 설명이 길어지는데, 이놈은 테스트 코드를 작성하기 까다로웠는데 다행히도 깃허브에 비슷한 예시가 있어서 참고했다.

 

 

## 마지막

이제 얼마 안남았다. 서버를 구축하고 시험 운영해보면 될것 같다.

(근데.. 이렇게 프로젝트가 쌓이면 서버 운영비 감당이 안되는데.. 작은 프로젝트를 뭉쳐서 비용을 절약할 없을까?)

 

2jun0