node.js | 인스타그램: 게시글 CRUD

2022. 10. 4. 00:25·TIL
반응형

Create

1. 알맞은 API 호출 URL을 설정하여서 클라이언트와(httpie/postman) 통신을 성공해주세요. -> '/postings': 포스팅 관련임을 알아볼수 있다
2. 알맞은 http 메소드를 선정하여서 게시글 내용 및 유저의 id 값을 백엔드 서버에 전달해주세요. -> post: body에 데이터를 담아 보낼때, 뭔가 생성할때
3. 데이터가 생성됬을 때에 알맞는 http 상태코드를 반환해주세요. -> 201: 무언가가 잘 생성됐을때 상태코드
5. http response로 반환하는 JSON 데이터의 형태는 다음과 같습니다.

{
  "message" : "postCreated"
}

 

req.body에는 어느 유저가 쓰는 글인지를 알기 위해 user의 id가 필수로 들어가고 내용은 없어도됨.

유저-포스팅은 1대다 관계이기 때문에 user_id만 넣으면 관계설정이 된다.

 

// app.js
app.post('/postings', async (req, res) => {
    const {userId, contents} = req.body;
    await myDataSource.query(
        `INSERT INTO postings (user_id, contents)
        VALUES (?, ?)`
        , [userId, contents]);
    res.status(201).json({"message" : "postCreated"});
});

아직 로그인기능 없이 유저아이디를 body에 받기 때문에 회원가입과 똑같이 작성해주면 된다.

 

 

Read

- 게시글 리스트 불러오기 API
    1. 알맞은 API 호출 URL을 설정하여서 클라이언트와(httpie/postman) 통신을 성공해주세요. -> '/postings' : posting관련이기때문에
    2. 데이터가 호출될 때의 알맞는 http 상태코드를 반환해주세요. -> 200: 요청에대한 처리가 성공했을 때 코드. 데이터를 읽기만 하니까
    3. http response로 반환하는 데이터의 형태는 다음과 같습니다. 

{
    "data" : [
	{
            "userId"           : 1,
            "userProfileImage" : "userProfileImage1",
            "postingId"        : 1,
            "postingContent"   : "sampleContent1"
	},
	{
            "userId"           : 2,
            "userProfileImage" : "userProfileImage2",
            "postingId"        : 2,
            "postingContent"   : "sampleContent2"
	},
	...
]}

 

postings 테이블에서 가지고 있지 않은 usreProfileImage가 필요하다. 이 속성은 users테이블에 있는데 userId를 이용해서 가져와야 한다. -> join이용

그리고 각 컬럼의 이름도 카멜케이스로 변경해야한다. -> as 이용

"data" : [{},{},{},...] 의 형태로 반환해야 한다.

app.get('/postings', async (req, res) => {
    await myDataSource.query(`
        SELECT 
            users.id AS userId, 
            users.profile_image AS userProfileImage,
            postings.id AS postingId, 
            postings.contents AS postingContent 
        FROM postings JOIN users ON postings.user_id=users.id;
        `, (err, rows) => {
            res.status(200).json({data: rows});
        });
});

 

Read2

- 특정 유저가 작성한 게시글 상세 API
    1. 알맞은 API 호출 URL을 설정하여서 클라이언트와(httpie/postman) 통신을 성공해주세요. -> 포스팅을 보는거니까 일단 /postings로 들어가야 할것 같고, user의 id를 쿼리파라미터로 받으면 될 것 같다. -> 아직 모르니까 /postings/user/1로 고정으로 1번유저 포스팅들만 가져오는걸로 하기
    2. 하나의 유저가 올린 여러개의 게시글을 보여주는 상세 페이지용 API를 작성해주세요.
    3. 데이터가 호출될 때에 알맞는 http 상태코드를 반환해주세요. -> 200
    4. Http response로 반환하는 데이터의 형태는 다음과 같습니다.

{
    "data" : {
        "userId"           : 1,
        "userProfileImage" : "userProfileImage1",
        "postings"         : [{
            "postingId"        : 1,
            "postingContent"   : "samplePostingContent1"
        },{
            "postingId"        : 2,
            "postingContent"   : "samplePostingContent2"
        },{
            "postingId"        : 3,
            "postingContent"   : "samplePostingContent3"
        }]
    }
}

data 안에 유저id와 프로필이미지하고 postings를 주는데, postings에 해당 유저의 포스팅 객체들이 배열로 들어있다.

-> 어떻게하지.........

📍 JSON_ARRAYAGG, JSON_OBJECT

https://dev.mysql.com/doc/refman/5.7/en/aggregate-functions.html#function_json-arrayagg

mysql> SELECT o_id, attribute, value FROM t3;
+------+-----------+-------+
| o_id | attribute | value |
+------+-----------+-------+
|    2 | color     | red   |
|    2 | fabric    | silk  |
|    3 | color     | green |
|    3 | shape     | square|
+------+-----------+-------+
4 rows in set (0.00 sec)

mysql> SELECT o_id, JSON_ARRAYAGG(attribute) AS attributes
    -> FROM t3 GROUP BY o_id;
+------+---------------------+
| o_id | attributes          |
+------+---------------------+
|    2 | ["color", "fabric"] |
|    3 | ["color", "shape"]  |
+------+---------------------+
2 rows in set (0.00 sec)

JSON_ARRAYAGG를 이용하면 제이슨요소가 담긴 1차원배열로 결과가 나온다.

그리고 그 안에 JSON_OBJECT(키, 밸류)를 이용하면 json_arrayagg에 담긴 요소를 객체로 만들 수 있다.

SELECT
      users.id as userId,
      users.profile_image as userProfileImage,
      JSON_ARRAYAGG(
        JSON_OBJECT(
          'postingId', postings.id,
          'postingContents', postings.contents
        )
      ) as postings
    FROM postings
    JOIN users ON users.id = postings.user_id
    WHERE users.id = 1
    GROUP BY users.id
  ;

이걸 코드에 적용하면

app.get('/postings/user/1', async (req, res) => {
    const data = await myDataSource.query(`
        SELECT
            users.id as userId,
            users.profile_image as userProfileImage,
            JSON_ARRAYAGG(
                JSON_OBJECT(
                    'postingId', postings.id,
                    'postingContents', postings.contents
                )
            ) as postings
        FROM postings
        JOIN users ON users.id = postings.user_id
        WHERE users.id = 1
        GROUP BY users.id
        ;`);
    res.status(200).json({data: data});
});

 

Update

- 게시글 정보 수정 엔드포인트 요구 사항
    1. 알맞은 API 호출 URL을 설정하여서 클라이언트와(httpie/postman) 통신을 성공해주세요. -> 포스팅중에 1번을 수정하는거니까 'postings/1'로 한다.
    2. 데이터베이스에 저장되어있는 1번 id 유저의 1번 id 게시글을 확인합니다. 이후 해당 내역의 content를 기존의 데이터와 다른 내용으로 수정하여 저장합니다.
    3. postingId가 1번인 게시물의 내용을 “기존과 다르게 수정한 내용입니다.”로 수정한다면, 데이터베이스에서 끌어와 http response로 반환하는 데이터의 형태는 다음과 같습니다.

{
    "data" : {
        "userId"           : 1,
        "userName"         : "weCode",
        "postingId"        : 1,
        "postingContent"   : "기존과 다르게 수정한 내용입니다."
    }
}
app.patch('/posting/1', async (req, res) => {
    const {contents} = req.body;
    await myDataSource.query(
        `UPDATE postings
        SET contents = ?
        WHERE id = 1;`, [contents]);

    const data = await myDataSource.query(
        `SELECT 
            postings.user_id AS userId,
            users.nickname AS userName,
            postings.id AS postingId,
            postings.contents AS postingContent
        FROM postings
        JOIN users ON users.id = postings.user_id
        WHERE postings.id = 1;
        `);
    res.status(200).json({data: data});
});

왜 배열로 감싸져서 나올까? select면 여러줄일수 있는데 내가 그냥 조건을 하나만 나올 조건으로 정해논거라서?

-> const [data] = await myDataSource.query(...)하면 알맹이만 data에 들어간다.

 

 

Delete

- 게시글 삭제 API
    1. 알맞은 API 호출 URL을 설정하여서 클라이언트와(httpie/postman) 통신을 성공해주세요. -> postings/6으로 해서 6번 게시글 삭제
    2. 데이터가 삭제 될 때에 알맞는 http 상태코드를 반환해주세요. -> 204: 주로 delete메소드 요청이 성공했을때 
    3. http response로 반환하는 JSON 데이터의 형태는 다음과 같습니다.

{
	"message" : "postingDeleted"
}
app.delete('/postings/6', async (req, res) => {
    await myDataSource.query(
        `DELETE FROM postings
        WHERE id = 6;`);
    res.status(204).json({message: "postingDeleted"});
});

메세지 보냈는데 왜 안나오지? 204라서?

삭제는 잘 됐다.

반응형
저작자표시 비영리 변경금지 (새창열림)

'TIL' 카테고리의 다른 글

NestJS | 패키지 버전 지정해서 세팅하기  (0) 2022.11.19
node.js | 인스타그램: 비밀번호 암호화(bcrypt)  (1) 2022.10.04
node.js | 인스타그램: 서버-db연결, 회원가입  (1) 2022.10.03
node.js | express, TypeORM 적용한 CRUD API만들기 - 2 API작성  (0) 2022.10.02
node.js | express, TypeORM 적용한 CRUD API만들기 - 1 db(dbmate)  (0) 2022.10.02
'TIL' 카테고리의 다른 글
  • NestJS | 패키지 버전 지정해서 세팅하기
  • node.js | 인스타그램: 비밀번호 암호화(bcrypt)
  • node.js | 인스타그램: 서버-db연결, 회원가입
  • node.js | express, TypeORM 적용한 CRUD API만들기 - 2 API작성
이라후
이라후
  • 이라후
    화이팅
    이라후
  • 전체
    오늘
    어제
    • 분류 전체보기 (133)
      • TIL (23)
      • 기타 (26)
      • Python (14)
      • Django (10)
      • JavaScript (8)
      • git & GitHub (8)
      • Web (10)
      • Go (3)
      • wecode (31)
  • 반응형
  • 인기 글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
이라후
node.js | 인스타그램: 게시글 CRUD
상단으로

티스토리툴바