일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 제네릭 타입
- 상속
- yield
- Switch Expressions
- 항해99
- 자바할래
- System.err
- System.in
- 자바스터디
- Study Halle
- 접근지시자
- github api
- docker
- auto.create.topics.enable
- junit 5
- 브릿지 메소드
- 프리미티브 타입
- System.out
- 제네릭 와일드 카드
- 람다식
- 익명 클래스
- 합병 정렬
- annotation processor
- 정렬
- 로컬 클래스
- throwable
- 바운디드 타입
- raw 타입
- 스파르타코딩클럽
- 함수형 인터페이스
- Today
- Total
코딩하는 털보
21.09.17 TIL 본문
항해99 DAY 5
오늘은 미니 프로젝트 마감일이다.
진행 중 어려웠던 것들
Response(), jsonify(), render_template()
스프링을 할 때도 그렇지만 View에 리스폰스를 제공할 때 이런 여러가지 메서드들 때문에 골치가 아프다.
하나로 통일하자니 실제 동작시 어려움이 많았다. 이 부분은 내가 조원들에게 소통을 더 많이했다면 나았을까 싶다.
- jsonify() 메서드는 response를 보내기 위해 아규먼트들을 json 타입으로 만드는 메서드이다. Response 타입 객체를 반환한다.
때문에 Rest API에서는 이 메서드를 많이 사용하지 않을까 예상한다. - render_template() 메서드는 매칭되는 html 파일을 전달해준다.
스프링에서 @ResponseBody가 아닌 기본적인 핸들러들이 return 값을 통해 view를 매핑해줬던 것과 유사하다.
model을 담아서 view에 전달하는 것 까지 이 메서드 하나로 처리할 수 있다. - Response()
나는 이 메서드를 비동기 통신에 사용하였다. 특히 예외를 처리할때..
response에 메시지와 상태 코드를 담아서 넘겨주고 프론트에서 얼럿으로 메시지를 사용자에게 전달해주는 식으로 만들었다.
jsonify과 마찬가지로 Response 타입 객체를 반환한다.
그런데 다음날 보니... 나는 왜 파이썬에도 객체가 있다는 것을 간과하고 있었을까. 이건 메서드가 아니고 Response 클래스의 생성자였다.
jsonify는 Response 객체를 생성하고 반환하는 메서드이다. 아마도 jsonify에서도 내부적으로 이 생성자를 사용할 듯 하다.
결국 jsonify()와 Response 생성자는 둘 다 Response 객체를 반환한다.
이렇게 쓰고나니 머릿속에 조금은 가닥이 잡힌다. 그냥 정리 먼저할껄
다음주 부터는 스프링을 사용한 프로젝트를 진행할 듯 한데 그땐 요부분 한번더 정리하자.
MongoDB
나는 NoSQL을 항해99에서 처음 접해본다.
처음에는 테이블(컬렉션..anyway)에 리스트가 포함되어 있는 것이 (RDB에서는 ORM으로 매핑을 해주어야 하는 상속 관계) 너무 싱기방기해서 게시글 도메인에 좋아요든 댓글이든 다 리스트로 담으려고 했다.
근데 컬렉션 내부의 리스트에는 자동으로 ID가 들어가지 않는다는 것을 알고는 다 분해해버렸다.
사실 당연히 NoSQL 보다는 RDM가 적합한 서비스였기 때문이긴 하지만 좀아쉬웠다. (Nosql이 비정형 데이터에 유리하다는데 한편 드는 생각은 그래서 비정형 데이터가 가져오는 이점은 무엇이며 기술블로그들에는 왜 다들 정의만 해놓고 직접적인 예시는 들지 못했는가...)
MongoDB의 도큐먼트 ID는 ObjectId 타입이다 항해99 질문방에 이 타입에 대한 질문이 여러번나왔다.
ObjectId가 문자열이 아니기 때문에 예상과 다른 오류들이 발생한 것 같다. (특히 jsonify() 인것 같다.)
ObjectId를 리스펀스로 넘기기 전에 문자열로 바꾸는 우회법을 사용한다.
comment["_id"] = str(comment["_id"])
일단 자바와 달리 특정 변수에 대한 정해진 타입이 없기때문에 (var...anyway) 이런 코딩이 가능하다는게 매우 놀랍다.
나처럼 자바만 아는 사람이 이 문장을 보면 이렇게 생각할 듯 하다.
"comment의 _id가 ObjectId 타입이라며, 근데 왜 문자열을 집어넣는거여?"
다시 한번 파이썬은 자바와 달리 특정 변수에 대한 정해진 타입이 없다. 그래서 위와 같이 실행하면 comment의 _id는 그냥 문자열로 바뀐다.
사실 이 우회법은 내 생각에는 조금 부자연스럽다.
MongoDB에는 분명히 comment의 _id에 ObjectId(str)처럼 들어가 있다.
프론트에서 받아서 사용할 comment의 _id가 이 ObjectId(str)와 과연 같은가.
같다고 생각할 수도 있다 어차피 프론트엔드에서 받는 _id는 이 ObjectId(str)들을 분류하는 유일한 값이니까.
그러나 그 쓰임이 같을 수는 없다고 생각한다. 문자열은 문자열 역할만 할뿐 ObjectId의 역할을 할 수 없다. 반대도 그렇다.
(요청에서 받아온 _id는 다시 ObjectId(_id)로 만들어야 제대로 사용할 수 있는것 처럼.)
comment["comment_id"] = str(comment["_id"])
이렇게 했으면 어땠을까 사실 별로 다른지 모르겠다.
변수만 봐도 "야 내가 너한테 줄라고 ObjectId에서 문자열로 변환해서 넣어놨어"라는 의미를 전달할 수 있다면 좋을 것 같다.
근데 지금 당장은 생각이 안남.
한편 ObjectId가 jsonify의 아규먼트가 될 수 없는 이유는 한번 찾아봐야 될 것 같다.
MongoDB의 쿼리 메서드들은 잘 추상화되어있다.
난 이번 프로젝트에서 모든 메서드를 사용할 때 아래처럼 사용했다.db.likes.update_one({"post_id": post_id_receive, "user_id": user["user_id"]}, {"$set": {"like": -1}})
싫다 이런 길고 보기어려운 줄. 처음이니까 한번은 넘어가고 담에 mongoDB 또쓴다면 이렇게 해보자.
query = {
"post_id": post_id_receive,
"user_id": user["user_id"]
}
projection = {
{"$set": {"like": -1}}
}
db.collection.find(query, projection)
깰꼼쓰
우리 조의 프로젝트는 아래와 같이 설계했다.
페이지 설계
메인 페이지
- 전체 재판 목록 확인
- 최근에 저장된 재판 순으로 전체 재판 목록 확인
- 목록의 오른쪽 끝에서 해당 재판의 공감 수를 확인
- 클릭하면 해당 재판의 상세 페이지로 이동
- 한 페이지에 7개 씩 출력
- 재판 저장
- 로그인하지 않았으면 얼럿 띄우기
- 오늘의 TOP3 / 이번 주 TOP3
- 오늘 또는 한 주간의 재판 중 공감 수가 높은 순으로 각 3개 확인
- 전체 재판 목록 확인
재판 상세 페이지
- 재판 상세 내용 확인
- 재판의 제목, 내용, 작성자, 작성 시간, 조회 수, 공감 수, 비공감 수, 댓글, 댓글 수를 확인
- 재판 수정과 삭제
- 재판의 작성자가 아니면 얼럿 띄우기
- 공감과 비공감
- 공감 또는 비공감 중복 선택 불가
- 두번 이상 선택 불가
- 댓글
- 댓글을 작성하고 목록을 확인
- 댓글 목록에는 댓글의 내용, 작성자, 작성 시간을 확인할 수 있음
- 댓글의 작성자만 댓글을 삭제할 수 있음
- 재판 상세 내용 확인
재판 수정 페이지
- 재판의 제목 또는 내용을 수정
마이 페이지
- 내가 작성한 재판 및 댓글 목록 확인
- 최근에 저장된 글 순으로 목록 확인
- 작성한 재판 목록의 오른쪽 끝에서 해당 재판의 공감 수를 확인
- 작성한 댓글 내용과 어떤 제목의 재판에 달렸는 지 확인
- 클릭하면 해당 재판의 상세 페이지로 이동
- 한 페이지에 10개 씩 출력
- 내가 작성한 재판 및 댓글 목록 확인
로그인 페이지
- 로그인 또는 회원가입
에러 페이지
- 잘못된 URL로 접근 시 404 페이지
- 토큰 시간이 만료되거나 토큰 정보가 잘못되어 있으면 401 페이지
API
기능 | URL | Method | Request | Response |
---|---|---|---|---|
로그인 | POST | /login | ||
회원가입 | POST | /register | { |
|
회원가입 중복 확인 | POST | /register/check_dup | { |
|
게시글 목록 리뷰 | GET | /posts | 전체 게시글 목록 | |
게시글 상세 내용 | GET | /post | 해당 게시글 Objectid, 게시글 DB | |
게시글 작성 | POST | /post | { |
|
조회수 증가 | POST | /view | { |
|
댓글 작성 | POST | /post | { |
|
게시글 삭제 | DELETE | /post | { |
|
공감 비공감 이벤트 | POST | /like | { |
|
댓글 제거 | DELETE | /comment | { |
|
게시판 수정 | PUT | /post | { |