우리는 지금까지 계층형 아키텍처 패턴을 공부하고 있었다. 기억나지 않는다면 241002 TIL 로 다시 돌아가보자
클라이언트의 요청을 받고 응답을 반환하는 단. 요청에 대한 처리는 스무스하게 서비스에게 떠넘겨버리는 문지기.
컨트롤러한테 짬처리 당한 요청을 처리하는 실세중에 실세인 단. 그러나 얘도 DB 정보가 필요할 경우 리포지토리에게 요청을 떠넘겨버린다.
DB 관리 역할을 담당. DB 접근이 필요한 요청이 들어오면 서비스에게서 떠안은 요청을 처리하기 위해 DB의 CRUD 작업을 처리한다.
컨트롤러는 하위 계층의 내부 구조에 대해 신경쓰지 않는다. 외부에 공개된 메서드를 호출하기만 할 뿐. 이것이 가능하게 해주는 게 바로 '추상화'의 특성 덕분!
-> 컨트롤러 클래스는 전달된 요청 처리를 위해 서비스를 호출하도록 구현되어 있다.
-> 본인이 비즈니스 로직 수행하지 않고 클라이언트의 요청을 서비스 계층으로 전달한다 짬때리기
-> 전달 했으면 끝! 컨트롤러는 그뤈거 몰롸😎 서비스 계층이 어떻게 로직 돌리는지 알고 싶지도 않고, 그냥 일 다하고 응답 다되면 나한테 건네줬으면 하는 것. 마치 콜백함수 처럼(?)
-> 이런 식으로 각 계층이 자신의 역할에만 집중할 수 있고, 다른 계층의 세부사항에 대해 알 필요가 없어지는 것이 3계층 아키텍처 이다.
프레젠테이션 계층(컨트롤러)과 데이터 액세스 계층(리포지토리) 사이에서 중간다리 역할을 하며, 두 계층이 직접 통신하지 않도록 만들어 준다.
어플리케이션의 규모가 커질 수록 이 서비스 계층의 역할과 코드의 복잡도도 커진다.
어플리케이션의 핵심적인 비즈니스 로직을 수행, 클라이언트들의 요구사항을 반영하여 원하는 결과를 반환해주는 계층.
가짜 저장소...?
(대충 이렇게 되나보다)
대표적인 저장소 계층의 메서드
add(), create() : 새 원소를 저장소에 추가
get(), find(): 이전에 추가한 원소를 저장소에서 가져옴
이를테면 이렇게 나눠서 만들고 있을 때, 비밀번호가 맞아야만 게시글의 수정이나 삭제가 가능하게 된다고 생각해보자.
그러면 비밀번호 일치 여부에 대한 검증 로직은 어디에 들어가야 할까..?! 🤔
이전에는 에러가 생긴다면 return.res
절에 넣어 돌려줬으니 컨트롤러 단인가? 싶지만 그건 아닌 것 같다. 예전에는 이 세개의 로직이 다 한 곳에 들어있었기 때문에 그냥 그런 것 같은...
핵심 비즈니스 로직은 서비스단에 들어간다고 하니 서비스단인가? 싶기도 한데 비밀번호는 DB에 저장될테니 리포지토리인가? 싶기도 하다.
어디에 들어가야 하는걸까? 혹시 이 셋이 아니라 에러처리 미들웨어로 가는걸까? 🥺
참고 블로그 가 스파르타 선배님인 것 같다..! 흠흠. 아무튼.
참고 블로그를 보고 이 글을 상단으로 올려 다시 보니 내가 이미 써놓았구나. 3계층 아키텍처에서 예외처리는 컨트롤러 단에서 해주는 것 이었다.
(컨트롤러의 역할 중 하나가 하위 계층에서 발생한 예외를 처리해주는 것이기 때문)
아까 서비스 계층에서 에러처리를 어떻게든 해보고 싶어 throw new Error를 써본 적이 있었는데, 이 방법도 틀리지 않은가보다.
포스트 라우터에서 이렇게 /posts
라고 URL을 써 주었는데,
라우터 폴더에서 router.use('/posts/', PostsRouter)
라고 post 관련 라우터에 대한 기본 URL을 픽스해주었다. 그러니 포스트 라우터에서는 /posts
가 아니라 /
만 써주면 되는 것.
yarn run dev로 nodemon을 실행시키려는데 이런 메시지가 떴다. 뭐지? 프리즈마 작업이 안 됐나?🤔
npx prisma generate만 입력하면 되는 줄 알았는데, 뭐가 없니 마니 하면서 잘 되지 않았다. 힝🥺
-> 원인은 prisma client가 제대로 설치되지 않았다는 것. 그런데 난 node_modules 디렉토리에 이미 prisma와 @prisma가 다 있었다. 뭐지?🤔
-> 참고 블로그 는 React 문제였는데 React의 버전 차이라고 했다.
-> yarn으로 package.json에 있는 디펜던시 재설치 시도를 했고 다시 다 깔렸는데(이 과정에서 프리즈마 클라이언트가 재설치됨), 그럼에도 불구하고 제대로 되지 않았다. 😥
Environment variable not found: DATABASE_URL
라는 메시지가 뜨면서 env("DATABASE_URL") 에 빨간 줄과 화살표를 친절하게 그어주는 프리즈마.
npx prisma generate 해서 MySQL하고 연결도 됐고 DB랑 테이블 다 생겼는데 뭐지? 싶었는데, 결론은 재시작 해보니 되네, 였다. 시도 과정은 다음과 같다.
-> 참고 블로그 는 .env의 이름을 .env.local로 바꿨을 때 나타나는 현상이라서 나와는 다른 케이스였다. 언젠가 나도 .env의 이름을 바꿀 때가 올까? 🤔
-> yarn add dotenv로 dotenv 설치
-> npx prisma generate 시도
-> npx prisma db push 시도
-> 구글 검색 후 DATABASE_URL을 DB_URL로 바꾸는 등 이름변경 시도
-> 아니 왜안돼?! 하면서 VS Code 종료 후 재실행 - 성공
1=1은 당연한거 아냐? 어차피 참이니까 쓸 필요가 굳이 있나? 그런데 쿼리문 끝에 계속 붙어나온다. 용도가 있을 거 같은데 뭘까?
참고 블로그 를 보니 다음과 같은 이유가 있다고.
SELECT *
FROM POST
WHERE POSTID = '5'
AND POSTNAME LIKE 'liha%'
예를 들어 이렇게 써놓은 경우 WHERE절의 조건을 주석처리 하는게 귀찮아진다. POSTID = '5'를 주석처리 해야 한다면 줄바꿈을 지우고 뭐하고 뭐하고 해야하기 때문.
-> 동적 쿼리는 조건에 따라 결과값이 달라지는 쿼리를 말한다. 파라미터를 받아 조건을 거는 경우가 대표적이라고.
특정 상황마다 WHERE절을 다르게 작성해줘야 하는 경우는 생각보다 흔하다. 무언가를 조회할 때. 하다못해 주차정산 할때 차 번호를 입력하는 것도 해당.
그래서 Jest에서 제대로 돌아가는 정규식은 다음과 같다!
const localPartRegex = new RegExp(/^[a-zA-z+-_]+$/gi);
const domainRegex = new RegExp(/^[0-9a-zA-Z.-]+$/gi);
SELECT 절에 IFNULL(컬럼명, "NULL일때 다른걸로 치환하고 싶은 값")
으로 써주면 된다.
열선시트니 통풍시트니 찾는 문제에서 %시트
만 써서 헤맸는데, %시트%
를 써주니까 맞았다.
REPLACE(바꿀 컬럼, 현재 값, 바꿀 값)
select restaurant_name "원래 상점명",
replace(restaurant_name, 'Blue', 'Pink') "바뀐 상점명"
from food_orders
where restaurant_name like '%Blue Ribbon%'
SUBSTRING(문자열 추출할 컬럼, 시작 위치, 추출할 글자수)
select addr "원래 주소",
substr(addr, 1, 2) "시도"
from food_orders
where addr like '%서울특별시%'
CONCAT(붙일 값 1, 붙일 값 2, 붙일 값 3...)
select restaurant_name "원래 이름",
addr "원래 주소",
concat('[', substring(addr, 1, 2), '] ', restaurant_name) "바뀐 이름"
from food_orders
where addr like '%서울%'
240912 챌린지반 TIL 에서 내가 이 공부를 한 적이 있었다. 과거의 나 기특하다. (?)
SELECT i.NAME, i.DATETIME
FROM ANIMAL_INS as i
LEFT JOIN ANIMAL_OUTS as o ON i.ANIMAL_ID = o.ANIMAL_ID
WHERE 1=1
AND o.DATETIME is NULL
ORDER BY i.DATETIME ASC
LIMIT 3
WHERE절에 1=1 붙이는게 왠지 맛이 들려 버렸는데 나 괜찮은걸까(?)