4주 프로젝트 - dev log #7

Joshua Song / 송성현·2020년 2월 8일
0

im_16 프로젝트

목록 보기
14/21

어제에 이어 열심히 라우팅 코드를 짜고 있다. 목요일 데브 로그를 쓰는 것을 까먹어 목요일 금요일 내용을 합쳐 오늘 쓴다. 정신없이 코드를 짜니 데브 로그 쓸 시간은 부족하고...하루가 정신없이 지나간다. 시간도 계속 지나가는데 어느정도 얼추 마무리가 되는 것을 보니 뿌듯하다.

일단 코드적인 측면에서 이야기 해보면 현재 있는 스택으로 구현 가능한 라우팅 문서를 모두 완성했다. 일단 어느정도 쿼리빌더에 익숙해지면 나오는 에러를 고치고 코드를 짜는 과정을 반복했고 코드에 맞춰서 API 문서도 수정하고 또 리팩토링도 어느정도 했다. 익숙해지기 까지 시간이 많이 걸렸고 험난한 과정이었지만 그래도 다 해냈다. Insert인지, Select인지, Update인지, Delete인지에 따라서 타입을 적절하게 지정해줬고 또 changedRow 혹은 affectedRow의 숫자로 디비에서 정보를 잘 처리했는지도 확인할 수 있었다.

ManyToMany 테이블에서 정보를 가져올때 한가지 인상깊었던건 JoinTable은 한 entitiy에서 해주더라도 ManyToMany관계는 양쪽에서 성립해줘야 한다는 것이었다. 이 부분을 고치기 위해 정말 많이 시간이 걸렸다. 공식문서에 나오긴 했지만 알게 모르게 에러가 났고...영차영차 고생을 해 해결할 수 있었다.

코드를 다 작성한 후 포스트맨을 돌려 결과가 잘 나오는지 확인했고 또 메시지도 상황에 맞게 보내도록 설정해주었다. Insert와 Update은 보다 수월했는데...join을 해서 가져오는 것이 매우...까다로웠다.

router.get("/catlist/:userId", async (req:express.Request, res:express.Response) => {
    const { userId }:{userId?:string} = req.params;
    try {
        const getCat:Array<object> = await getRepository(User).createQueryBuilder("user")
            .where("user.id = :id", { id: Number(userId) })
            .leftJoinAndSelect("user.cats", "cat")
            .select(["user.id", "user.nickname", "user.photoPath", "user.createAt",
                "cat.id", "cat.description", "cat.location", "cat.nickname", "cat.species"])
            .leftJoinAndSelect("cat.photos", "photo", "photo.isProfile = :isProfile", { isProfile: "Y" })
            .select(["user.id", "user.nickname", "user.photoPath", "user.createAt",
                "cat.id", "cat.description", "cat.location", "cat.nickname", "cat.species",
                "photo.path"])
            .getMany();
        if (!getCat) {
            res.status(409).send("User's list not found");
        }
        res.status(200).send(getCat);
    } catch (e) {
        res.status(400).send(e);
    }
});

위에 코드는 ManyToMany로 합쳐놓은 테이블을 기반으로 Join을 해서 정보를 가져오는 것인데 연결되어 있는 user테이블의 cats를 가져오는 것이다. 이후 Select을 통해 원하는 정보만 가져와서 보내주도록 하였다. 지금 정리된 코드를 보면 직관적이지만 중간에 많은 에러를 직면했다.

가장 까다로웠던 코드는...음...많았다. 여러가지 기능을 합쳐놓은 코드들이 어려웠다. 예를 들어서 태그를 등록하는 코드는 태그가 있는 지 확인한 후 있다면 추가하는 구조였는데 일단 코드 길이자체도 길었고 흐름을 잘 계획해서 진행해야 했다.


// update Tag
router.post("/updateTag", async (req:express.Request, res:express.Response) => {
    const { userId, catId, catTag }:{userId: number, catId:number, catTag:string} = req.body;
    try {
        const connection:QueryBuilder<any> = await getConnection().createQueryBuilder();
        const checkTag:Tag|undefined = await connection
            .select("tag").from(Tag, "tag")
            .where("tag.content = :content", { content: catTag })
            .select(["tag.id"])
            .getOne();
        if (checkTag) {
            const updateTag:InsertResult = await connection
                .insert()
                .into("cat_tag")
                .values([{
                    user: userId, cat: catId, tag: checkTag.id, status: "Y",
                }])
                .execute();
            if (updateTag.raw.affectedRows === 0) {
                res.status(409).send("Tag update failed");
            }
            const result = `{"message": "Tag updated successfully", "addedcatTag": ${catTag}}`;
            res.status(200).send(result);
        } else {
            const newTag:InsertResult = await connection
                .insert()
                .into("tag")
                .values([
                    {
                        content: catTag,
                    },
                ])
                .execute();
            if (newTag.raw.affectedRows === 0) {
                res.status(409).send("Tag update failed");
                return;
            }
            const updateTag:InsertResult = await connection
                .insert()
                .into("cat_tag")
                .values([{
                    user: userId, cat: catId, tag: newTag.identifiers[0].id, status: "Y",
                }])
                .execute();
            if (updateTag.raw.affectedRows === 0) {
                res.status(409).send("Tag update failed");
            }
            const result = `{"message": "Tag updated successfully", "addedcatTag": ${catTag}}`;
            res.status(201).send(result);
        }
    } catch (e) {
        res.status(400).send(e);
    }
});

길이가 엄청나게 길긴 하지만 eslint를 적용해서 줄을 엔터식으로 옮기기 때문에 길이가 길어진 부분에 한몫했다.

그리고 한가지 클라이언트에 건의한 사항은 고양이를 등록할 때 고양이 상태 태그를 배열로 받아 디비에 추가해주는 식으로 코드를 짰는데 이 과정이 태그를 디비에 있는지 확인 후 추가 해줘야 하는 단계여서 배열 속 각 요소마다 반복문으로 실행한 것인데 다른 요소들도 각 디비에 다 추가해줘야했기 때문에 request timeout이 났다. 그래서 해결책으로 고양이 상태는 고양이 등록 페이지가 아닌 고양이 바이오 페이지로 옮기기로 했다. 어떻게 보면 고양이 상태는 그때그때 바뀌는 상태이고 기본 데이터가 아니기 때문에 옮겨도 될 것같다고 팀도 동의를 했다. 고양이 등록 페이지는 정말 위치와 종, 사진이나 정말 기본 정보들을 담아둔 페이지로 유지하기로 합의했다.

소통도 꾸준히 잘 해주었고 서로의 의견도 잘 존중해주어 팀 분위기는 매우 좋은 것 같다. 이제 API 루트 문서를 어느정도 했으니 이미지를 업로드 했을 때 S3에 담아주는 것을 학습한 후 작성할 것이다. 화이팅~

profile
Grow Joshua, Grow!

0개의 댓글