BE_Simple API Server_Assignment#6_10.28

송철진·2022년 10월 28일
0

Assignment

Assignment 5에서 만들었던 app.js 파일에 이어서 과제를 진행해주세요.

  • app.js 파일에 사용자와 사용자가 등록한 게시글 목록 조회 엔드포인트 구현 코드를 작성해주세요.
    • 알맞은 API 호출 URL을 설정하여서 클라이언트와(httpie/postman) 통신을 성공해주세요.
    • 하나의 유저가 작성한 여러개의 게시글을 보여주는 상세 페이지용 API를 작성해주세요.
    • 데이터가 호출될 때에 알맞는 http 상태코드를 반환해주세요.
    • 사용자 ID가 1번인 유저 정보를 요청했을 때, Http response로 반환하는 데이터의 형태가 다음과 같은 구조를 갖도록 만들어주세요.
{
  "data" : {
    "userID"   : 1,
	"userName" : "Rebekah Johnson",
	"postings" : 
    [
	  {
	    "postingId"      : 1,
	    "postingName"    : "간단한 HTTP API 개발 시작!",
		"postingContent" : "Node.js에 내장되어 있는 http 모듈을 사용해서 HTTP server를 구현."
	  },
	  {
	    "postingId"      : 2,
	    "postingTitle"   : "HTTP의 특성",
		"postingContent" : "Request/Response와 Stateless!!"
	  },
	  {
	    "postingId"      : 3,
	    "postingName"    : "새롭게 추가된 포스팅",
		"postingContent" : "새롭게 추가된 포스팅 내용"
	  }
	]
  } 
} 

1. 전체 소스코드

const http = require("http");
const server = http.createServer();
const users = [
    {
      id: 1,
      name: "Rebekah Johnson",
      email: "Glover12345@gmail.com",
      password: "123qwe",
    },
    {
      id: 2,
      name: "Fabian Predovic",
      email: "Connell29@gmail.com",
      password: "password",
    },
];
  
let posts = [
    {
      id: 1,
      title: "간단한 HTTP API 개발 시작!",
      content: "Node.js에 내장되어 있는 http 모듈을 사용해서 HTTP server를 구현.",
      userId: 1,
    },
    {
      id: 2,
      title: "HTTP의 특성",
      content: "Request/Response와 Stateless!!",
      userId: 1,
    },
];

const data = function(){
    let dataArray = [];
    for(let i = 0; i<posts.length; i++){
        for(let j = 0; j<users.length; j++){
            if (users[j].id === posts[i].userId){
                let userPost = {
                    "userID"           : users[j].id,
                    "userName"         : users[j].name,
                    "postingId"        : posts[i].id,
                    "postingTitle"     : posts[i].title,
                    "postingContent"   : posts[i].content 
                }
                dataArray.push(userPost);
            }
        }
    }
    return dataArray;
}
// 입력받은 배열arr의 키id가 입력받은 num과 같으면 그 요소를 제거하고 나머지를 배열로 반환하는 함수
const subA = function(arr, num){
    arrNew =[];
    for(let i=0; i<arr.length; i++){
        if(arr[i].id!==num){
            arrNew.push(arr[i]);
        }
    }
    return arrNew;
  }

  const postFind = function (arr, idx){ // posts와 idx를 입력하면
    let result =[];
    for(let i=0; i<arr.length; i++){
      if(arr[i].userId === idx){
        result.push({
          "postingId"       : arr[i].id,
          "postingName"     : arr[i].title,
          "postingContent"  : arr[i].content  
        });
      }
    }
    return result; // 이런 형태의 객체를 반환하는 함수
  }
  
  const userFind = function (arr1, arr2, userId){ // users, posts, idx를 입력받으면
    let result = {};
    for(let i in arr1){
      if(arr1[i].id === userId){
        result = {
          "userID"    : arr1[i].id,
          "userName"  : arr1[i].name,
          "postings"  : postFind(arr2, userId)
        }
      }
    }
    return result;
  }

const httpRequestListener =  function(request, response){
    const { url, method } = request;
    if (method === 'GET'){
        if (url === '/ping'){ // health check
            response.writeHead(200, {'Content-Type' : 'appliction/json'});
            response.end(JSON.stringify({message : 'pong'}));
        }else if (url === '/posts/inquire'){
            response.writeHead(200, {'Content-Type' : 'appliction/json'});
            response.end(JSON.stringify({ "data" : data() }));
        }else if (url === '/users/posts/inquire'){
            let body = "";

            request.on("data", (data) => { 
                body += data;
            });

            request.on("end", ()=>{
                const user = JSON.parse(body);
                
                let result={}; 
                result = userFind(users, posts, user.id); 
                
                response.writeHead(200, {'Content-Type':'appliction/json'});
                response.end(JSON.stringify({"data" : result}));
            });
            
        }
    }else if(method === "POST"){
        //response.writeHead(200, {'Content-Type':'appliction/json'})
        // url이 /users/signup 이면 회원가입을 실행:
        if (url === "/users/signup") {
            let body = "";

            //콜백함수: 데이터를 모아서 하나의 스트링으로
            request.on("data", (data) => { 
                body += data;
            });

            //콜백함수: 
            request.on("end", ()=>{
                // 하나의 스트링으로 만든 body를 파싱해서 user에 할당
                const user = JSON.parse(body);

                // 전역변수 users에 입력받은 객체를 추가
                users.push({
                    id: user.id,
                    name: user.name,
                    email: user.email,
                    password: user.password,
                });

                // 데이터타입은 json으로 
                response.writeHead(200, {'Content-Type':'appliction/json'});

                // json으로 작성된 stringify(...)의 ...을 응답'body'에 표시
                response.end(JSON.stringify({
                    message : "userCreated",
                    "users" : users
                }));
            });
        // url이 /posts/signup 이면 게시글 입력을 실행:
        }else if(url === "/posts/signup"){
            let body = "";

            //콜백함수: 데이터를 모아서 하나의 스트링으로
            request.on("data", (data) => { 
                body += data;
            });

            //콜백함수: 요청의 body(end)에 대해 실행하겠다?
            request.on("end", ()=>{
                // 스트링 body를 JSON형태로 파싱해서 post에 할당
                const post = JSON.parse(body);

                 // 전역변수 posts에 입력받은 객체를 추가
                posts.push({
                    id: post.id,
                    title: post.title,
                    content: post.content,
                    userId: post.userId,
                });
                // 데이터타입은 json으로 
                response.writeHead(200, {'Content-Type':'appliction/json'});

                // json으로 작성된 stringify()의 객체 내용을 응답'body'에 표시
                response.end(JSON.stringify({
                    message : "postCreated",
                    "posts" : posts }));
            });
        }
    }else if(method === "PATCH"){
        if(url === '/posts/change'){
            let body = "";
            
            request.on("data", (data) => { 
                body += data;
            });
            
            request.on("end", ()=>{
                const post = JSON.parse(body);

                for(let i in posts){
                    if (posts[i].id === post.id){
                         posts[i].content = post.content;
                    } 
                    
                }
                
                response.writeHead(200, {'Content-Type' : 'appliction/json'});
                response.end(JSON.stringify({ "data" : data() }));
            });
        }
    
    }else if(method === "DELETE"){
        if(url === '/posts/delete'){
            let body = "";

            request.on("data", (data) => { 
                body += data;
            });
            request.on("end", ()=>{
                const post = JSON.parse(body);
                
                posts = subA(posts, post.id);
                response.writeHead(200, {'Content-Type' : 'appliction/json'});
                response.end(JSON.stringify({ "message" : "postingDeleted", "posts" : posts }));
            });
            
        }
    }
}
server.on("request", httpRequestListener);

const IP = '127.0.0.1';
const PORT = 8000;

server.listen(PORT, IP, function(){
    console.log(`Listening to request on ip ${IP} & port ${PORT}`);
})

1-1. 추가된 소스코드

const postFind = function (arr, idx){ // posts와 idx를 입력하면
  let result =[];
  for(let i=0; i<arr.length; i++){
    if(arr[i].userId === idx){
      result.push({
        "postingId"       : arr[i].id,
        "postingName"     : arr[i].title,
        "postingContent"  : arr[i].content  
      });
    }
  }
  return result; // 이런 형태의 객체를 반환하는 함수
}
  
const userFind = function (arr1, arr2, userId){ // users, posts, idx를 입력받으면
  let result = {};
  for(let i in arr1){
    if(arr1[i].id === userId){
      result = {
        "userID"    : arr1[i].id,
        "userName"  : arr1[i].name,
        "postings"  : postFind(arr2, userId)
      }
    }
  }
  return result;
}
if (method === 'GET'){
  if (url === '/users/posts/inquire'){
    let body = "";

    request.on("data", (data) => { 
      body += data;
    });

    request.on("end", ()=>{
      const user = JSON.parse(body);
                
      let result={}; 
      result = userFind(users, posts, user.id); 
                
      response.writeHead(200, {'Content-Type':'appliction/json'});
      response.end(JSON.stringify({"data" : result}));
    });          
  }
}

2. 리스닝

3. 실행 결과

3-1. posts 게시물 추가하기

id=3, userId=1 인 게시글 추가:

3-2. 유저 정보(게시물 목록 포함) 불러오기

id=1인 유저 정보 불러오기

보완해야할 점?
1. 코드가 너무 복잡
👉 Simple API Wrap-up(솔루션 참조 나중에) 간단하게 짜는 방법 연습?
2. url 조건을 더 구체적으로
👉 ex) id가 1인 게시글 정보를 불러온다면 /posts/inquire/1
3.

profile
검색하고 기록하며 학습하는 백엔드 개발자

0개의 댓글