#1 개요
나무위키로 치면 아래와 같은 기능을 만드려고 한다.
원래는 document 스키마 내부에 주석 배열을 넣어서 해당 주석을 만들려고 했다.
그러나 주석은 문서 내용과 또 달리 추가, 수정 빈도가 더 높을 것으로 예상되며,
특히 일부를 수정할 때, 강제적으로 모든 주석의 배열을 불러와야 하는 것은 비효율적일 수 있다는 생각을 하였다.
이는 수정할 때마다 배열을 수정해야하기 때문에 더욱 그렇다.
따라서 주석의 스키마를 nosql이지만 정규화를 하듯 분리하는 방식을 사용해보고자 했다.
#2 mongoose .populate() 메소드와
1) 1:1 관계에서의 .populate() 함수
Schema를 정의할 때 다음과 같이 ObjectId 타입과, ref를 통해 어떤 Schema의 Id를 참조하는지 선언할 수 있다.
const annoationSchema = mongoose.Schema({
document:{ type: mongoose.Schema.Types.ObjectId, ref:"Document", required: true,},
})
이렇게 하면 데이터로 ID를 저장했을 때, .populate() 함수를 통해 해당 id를 가진 object(Schema정보를 담은) 전체를 다 가져오는 메소드이다.
populate의 인자로는 이렇게 object id를 object 정보로 변환해줄 데이터의 이름을 받는다.
2) 1:N 관계에서의
위에서처럼 Schema를 정리할 때, Object id 타입 선언을 배열안에서 해주면 다음과 같이된다.
annotations:[{
type: mongoose.Schema.Types.ObjectId,
ref: "Annotation"
}],
위와 같이 배열 내부에서 타입을 선언해주고 평소에는 object id를 배열로 저장하고 있다가
populate를 사용하면 내부에 모든 id가 내용으로 교체된다.
이렇게 문서에는 여러개의 주석 id를 저장하고,
주석에는 한개의 문서 id를 저장하여 연동되도록 설계한다.
#3 Front 단에서 주석 작성
어떤 내용과 연동되는지 주석 머리,
주석의 내용
두 가지를 input으로 받는 form을 만든다.
댓글 작성 구조에서 착안해서, 순서를 바꿀 수 있는 기능을 넣어줄 예정이다.
## front의 js 파일에 백엔드의 정보 넘겨주는 법 - data-something (data-set 기능)
front html에서 data- 로 명명한 속성에 값을 넣어주고, 이를 js로 가져와서 사용한다.
<h1 class="word__title" data-title="<%= title %>"><%= title %></h1>
위 코드로 dataset을 설정하고
const handleSubmit = (event) => {
const doc = docTitle.dataset.title;
}
위와 같이 사용해준다.
#4 fetch로 주석 보내주기
0. fetch가 동작할 수 있게 사전 설정
js의 object는 브라우저에서 전달할 시, 그대로 전달되지 않는다. (network를 확인하면 [object] 로 뜨는 것)
즉, object를 주고 받을 때 데이터가 온전하지 않는다는 건데, 따라서 object 데이터를 확인하기 위해서는 json형태로 바꾸어 읽기, 수정 등을 진행해야 한다.
다음 코드로 json의 stringfy를 진행한다.
{
method: "POST",
body: JSON.stringify({annotation_title: annotation_title, annotation: annotation})
}
그러나 이렇게 데이터를 전달하게 되면 사실상 구조만 object 인 string과 다를바 없다.
즉, req.body.annoation 과 같은 형태로 접근이 불가능한 것.
따라서 서버가 json구조로 string인 데이터를 json으로 바꿔주는 middleware가 존재하고,
이 코드를 먼저 미들웨어로 추가한다.
//server.js
app.use(express.json());
(만약 text형태를 fetch로 받고자 한다면 app.use(express.text())를 써줄 수 있다.)
위 코드는 미들웨어가 JSON.parse() 를 해주는 셈.
다만 fetch에서 보내는 데이터가 text가 아닌, text화 된 json이라고 미리 알려줘야 하는데,
이는 req의 데이터에 대한 설명을 담는 header 옵션 내부에 적어준다.
fetch(`/api/docs/${doc}/annotation`, {
method: "POST",
headers:{
"Content-Type": "application/json"
},
});
1. fetch를 받아줄 api url 생성
fetch(url, data object) 구조로 post request를 보내준다. url 변경 없이 post request를 만들어 줄 수 있다는게 fetch의 가장 핵심 기능.
따라서 최종적인 구조는 다음과 같다.
fetch(`/api/docs/${doc}/annotation`, {
method: "POST",
headers:{
"Content-Type": "application/json"
},
body: JSON.stringify({annotation_title: annotation_title, annotation: annotation})
});
body의 경우 html에서 post는 자동으로 form 내부 데이터들을 body로 만들어주는 것.
+2. fetch 팁
백엔드로 보내는 모든 req는 쿠키와 함께 전달된다.
따라서 만약 annotation의 작성자의 정보를 알고 싶다면(댓글처럼)
req에 있는 쿠키 정보로 => 백엔드에 있는 session정보 를 뒤져 사용자 정보를 알아낼 수 있다.
'프로젝트 기록 > 러시아어 사전 및 검색 웹' 카테고리의 다른 글
개발 과정 리뷰 -20- 개선해야할 버그 및 수정사항 목록 (0) | 2024.04.29 |
---|---|
개발 과정 리뷰 -19- 테스트 코드 작성 (0) | 2024.04.06 |
개발 과정 리뷰 -17- 카테고리 및 페이지네이션 (0) | 2024.03.30 |
개발 과정 리뷰 -16- 한글 유니코드로 ㄱㄴㄷ 카테고리 분리하기 (0) | 2024.03.27 |
개발 과정 리뷰 -15- SummerNote 관련 (0) | 2024.03.25 |