블록체인 TIL-5Week-30Day

디오·2023년 4월 11일
0
post-thumbnail

오늘은 어제 배웠던 백엔드부분을 다시 복습하고 보다 좀 더 디테일하게 백엔드의 기초적인 부분을 배웠다. 그리고 배운 부분들을 사용하여 Todolist를 만들어보는 시간을 가졌다. 다행히도 백엔드부분은 직관적으로 코드를 작성했기 때문에 이해하는데 있어서 이전에 React를 했을때 보다는 좀 더 쉬웠고, 특히 오후에 진행했던 Todolist 만드는 수업은 생각외로 재밌어서 놀랐다. 일단은 어제 배웠던 부분들에 대해서 정리못했던 부분을 강사님의 교안을 바탕으로 간단하게 정리를 하고 오늘 수업에서 진행했던 코드를 리뷰해보도록 하겠다.



☑️ 어제 배웠던 내용들.

💠 Rest API

Rest API란 무엇인가?

  • REpresentational State Transfer의 약어로 자원을 이름으로 구분해서 해당 자원을 주고 받는 모든 것을 일컫는다.

Rest API의 특징.

  • 자원의 이름과 전달 방식만으로 해당역할을 추론할 수 있다.

  • HTTP Methods를 통해서 해당 자원에 대한 CRUD Operation을 적용한다.

    • (HTTP Methods - GET, POST, PUT, DELETE)
    • (CRUD - Create, Read, Update, Delete)

Rest API의 특징 및 장, 단점

  • Rest API의 특징

    • Server - Client 구조로 되어 있다.

    • 자윈을 가지고 있는 쪽이 서버, 제공받는 쪽이 클라이언트가 된다.

    • Stateless(무상태)다.

    • HTTP 프로토콜을 사용하므로 HTTP 프로토콜처럼 무상태성을 가지고 있다.

    • 클라이언트의 context를 서버에 저장하지 않는다. (서버는 신경쓸 것 없이 본연에 업무에만 집중하면 된다.)

    • 서버는 각각에 요청에 대한 응답만 하면 된다.

  • Rest API의 장, 단점!

Rest API의 적용

  • 실제 Get요청, Post요청을 통해 Rest API를 사용할 수 있다.

    • AXIOS는 HTTP 통신을 위한 라이브러리다.

    • Insomnia(Postman)는 REST API를 테스트 할 수 있는 툴이다.



💠 React Icons

React Icons는 리액트 진영에서 사용하는 아이콘 라이브러리다.

How to use

  • npm i react-icons



💠 Async / Await

프론트엔드는 백엔드 서버와의 통신을 위해서라도 비동기 처리를 해야되는 상황이 발생한다.

비동기 처리를 위해서 사용하는 문법인 async / await에 대해서 살펴보도록 하겠다.

Async/Await(Promise)

  • 프로미스는 비동기 처리(미래) 작업에 대한 완료와 실패를 처리할 수 있는 문법이다.

Code

async function checkPromise() {
  let promise = new Promise((resolve, reject) => {
    setTimeout(() => resolve("완료!"), 1000);
  });

  // Promise가 있는 경우 없는 경우 둘 다 실행해보세요.
  // let result = promise;
  let result = await promise;

  console.log(result);
}

checkPromise();

  • await 키워드를 붙였을 때는 정상적으로 나타낸다.

  • await 키워드를 사용하기 위해서는 함수를 반드시 async(비동기)로 만들어야 한다.

  • await를 사용하지 않은 promise는 pending 상태를 출력하게 된다.

try/catch

  • try/catch문은 비동기 처리와 함께 사용된다.
    에러가 발생할 경우 catch문이 동작하는 형태다.

Code & Result



✅ 어제,오늘 배운 내용들.

🪷 ExpressJS

NodeJS의 등장으로 자바스크립트는 프론트엔드 영역을 넘어, 백엔드 영역까지 확장하게 되었다.
그 중에서도 ExpressJS를 공부하여 백 엔드는 어떻게 구성되어 있고, 백엔드와 프론트엔드는 어떻게 소통이 이루어지는지 살펴보도록 하겠다.

ExpressJS 설치

  • npm init

  • 해당 이미지에 맞게
    터미널에서 작성진행

  • npm i express (npm install express --save)

  • (추가) app.js 생성.

Code & Result.

  • 백엔드 서버가 구동되기 시작하면 listen이 실행된다.

  • 웹 브라우저에서 3010을 접속하게 되면 Get요청을 받을 수 있다.

ExpressJS를 사용하여 CRUD 구현하기

  • Read : 현재 To do list를 보여준다.

  • Create : 새로운 To do를 생성한다.

  • Update : 기존의 To do를 업데이트 한다.

  • Delete : To do를 삭제한다.



🪷 JS Module System

모듈시스템 이란?

  • 자바스크립트의 모듈 시스템을 이해하고 내 프로젝트에 맞는 모듈 시스템을 적용할 수 있다.

Module System이란?

  • 모듈 시스템 등장 이전의 자바스크립트 개발은 <script src=”…”>로 불러와야 했다.

  • 모듈 시스템에 등장으로 보기에 직관적이고, 효율성 있는 개발이 가능하게 됐다.

ES6

  • ES - ECMAScript의 약어이며, 자바스크립트의 표준을 나타내는 용어다.

  • ES6 - 2015년에 등장한 자바스크립트 표준이다.

    • let, const
    • 템플릿 리터럴(백틱)
    • 객체 리터럴
    • 화살표함수
    • 구조 분해 할당
    • Promise
    • Class
    • Module System 등이 등장했다.
  • import/export를 사용해서 모듈 시스템을 구현한다.

CommonJS

  • 2009년에 자바스크립트의 표준을 만들기 위해서 등장하였다.

  • 주로 서버 사이드(백엔드)에서 사용되는 모듈 시스템이다.

  • require 사용하여 모듈시스템을 구현한다.

CommonJS 모듈 시스템의 사용

<a.js>

function goModule() {
  console.log("Hello, Module!");
}

module.exports = goModule;
<b.js>

const goModule = require("./a");

goModule();

  • CommonJS의 모듈 시스템은 module.exports를 통해 export 한다.

  • require를 통해 import 할 수 있다.



🪷 ExpressJS - Routing

많은 API 요청이 생긴다면 app.js의 내용이 길어지게 된다. 이때 ExpressJS의 라우팅 기능을 활용하면 효율적으로 API를 관리할 수 있다.

Code & Result

<app.js>

const express = require("express");

const userRouter = require("./routes/user"); 
const tweetRouter = require("./routes/tweet"); 


const app = express(); 

const port = 3010; 

app.use("/user", userRouter);
app.use("/tweet", tweetRouter);

app.get("/", (req, res) => {
  res.send("Hello, Express!");
});

app.listen(port, () => {
  console.log(`Server listening on port: ${port} 🚀🚀🚀`);
});
  • 해당 코드는 Node.js와 Express.js를 사용하여 서버를 구축하는 코드다. 간단하게 REST API를 생성하는 것이 목적이다.
  • const express = require("express");

    • import를 대체한다.
  • const userRouter = require("./routes/user");

    • user라우터를 연결시킴.
  • const tweetRouter = require("./routes/tweet");

    • tweet라우터를 연결시킴.
  • const app = express();

    • express를 실행하여 앱 객체를 생성.
  • const port = 3010;

    • react서버와 겹치지 않게 서버가 실행될 포트 번호를 3010으로 설정
  • app.use("/user", userRouter);

    • userRouter 모듈이 /user 엔드포인트에서 작동하도록 설정
  • app.use("/tweet", tweetRouter);

    • tweetRouter 모듈이 /tweet 엔드포인트에서 작동하도록 설정
  • app.get("/", (req, res) => {
    res.send("Hello, Express!");
    });

    • 루트 URL (/)로 GET 요청이 들어왔을 때 "Hello, Express!" 메시지를 출력하도록 함.
  • app.listen(port, () => {
    console.log(Server listening on port: ${port} 🚀🚀🚀);
    });

    • listen() 함수를 사용하여 서버를 시작하고, 포트 번호가 log에 출력



<user.js>

const express = require("express");

const router = express.Router();

router.get("/:id", (req, res) => {
  
  res.send("유저 조회");
});

router.post("/", (req, res) => {
  res.send("신규 유저 생성");
});

router.put("/:id", (req, res) => {
  res.send("유저 정보 수정");
});

router.delete("/:id", (req, res) => {
  res.send("유저 삭제");
});

module.exports = router; 
  • 해당 코드는 Express.js의 라우팅 기능을 사용하여 User CRUD(Create, Read, Update, Delete) API를 구현하는 코드다.
  • const express = require("express");

    • express 모듈을 가져와서 express 변수에 할당
  • const router = express.Router();

    • express 객체의 Router 메소드를 사용하여 새로운 라우터 객체를 생성
  • router.get("/:id", (req, res) => {

    res.send("유저 조회");
    });

    • GET 메소드를 사용하여 /id 파라미터를 사용해 특정 유저 조회를 하는 엔드포인트를 정의
  • router.post("/", (req, res) => {
    res.send("신규 유저 생성");
    });

    • POST 메소드를 사용하여 새로운 유저를 생성하는 엔드포인트를 정의
  • router.put("/:id", (req, res) => {
    res.send("유저 정보 수정");
    });

    • PUT 메소드를 사용하여 /id 파라미터를 사용하여 특정 유저 정보를 수정하는 엔드포인트를 정의
  • router.delete("/:id", (req, res) => {
    res.send("유저 삭제");
    });

    • DELETE 메소드를 사용하여 /id 파라미터를 사용하여 특정 유저를 삭제하는 엔드포인트를 정의
  • module.exports = router;

    • module.exports를 사용하여 해당 라우터를 모듈로 내보내어 다른 모듈에서 사용할 수 있도록 함.



const express = require("express");

const router = express.Router();

router.get("/", (req, res) => {
  res.send("전체 트윗 조회");
});

router.get("/:id", (req, res) => {

  console.log(req.params); 
  res.send("특정 트윗 조회");
});

router.post("/", (req, res) => {
  res.send("신규 트윗 생성");
});

router.put("/:id", (req, res) => {
  res.send("특정 트윗 게시물 수정");
});

router.delete("/:id", (req, res) => {
  res.send("특정 트윗 게시물 삭제");
});

module.exports = router;
  • 해당코드는 Express.js의 라우팅 기능을 사용하여 Tweet CRUD(Create, Read, Update, Delete) API를 구현하는 코드입니다.
  • const express = require("express");

    • express 모듈을 가져와서 express 변수에 할당
  • const router = express.Router();

    • express 객체의 Router 메소드를 사용하여 새로운 라우터 객체를 생성
  • router.get("/", (req, res) => {
    res.send("전체 트윗 조회");
    });

    • GET 메소드를 사용하여 전체 트윗을 조회하는 엔드포인트를 정의
  • router.get("/:id", (req, res) => {

    console.log(req.params);
    res.send("특정 트윗 조회");
    });

    • GET 메소드를 사용하여 /id 파라미터를 사용하여 특정 트윗을 조회하는 엔드포인트를 정의
  • router.post("/", (req, res) => {
    res.send("신규 트윗 생성");
    });

    • POST 메소드를 사용하여 새로운 트윗을 생성하는 엔드포인트를 정의
  • router.put("/:id", (req, res) => {
    res.send("특정 트윗 게시물 수정");
    });

    • PUT 메소드를 사용하여 /id 파라미터를 사용하여 특정 트윗 게시물을 수정하는 엔드포인트를 정의
  • router.delete("/:id", (req, res) => {
    res.send("특정 트윗 게시물 삭제");
    });

    • DELETE 메소드를 사용하여 /id 파라미터를 사용하여 특정 트윗 게시물을 삭제하는 엔드포인트를 정의
  • module.exports = router;

    • module.exports를 사용하여 해당 라우터를 모듈로 내보내어 다른 모듈에서 사용할 수 있도록 함.



🪷 Filter 함수

자바스크립트 필터 함수를 사용하면 특정 조건에 맞는 요소로만 새로운 배열을 구성할 수 있다.

필터함수 사용(1)

  • v.length >= 5;

    • 길이를 5글자 이상으로 조건 설정.
  • return할때 어떤 조건을 입력하는지에 따라서 바뀐다.



필터함수 사용(2)

  • v.type === "fruit";

    • 타입과 과일이 같을때로 조건 설정.



map함수 vs filter함수

  • filter함수를 사용하면 조건에 부합하지 않으면 값을 저장하지 않음.

  • 반면, map함수를 사용하면 조건에 부합하지 않아도 값을 저장할 수 있음.

  • 정확한 값을 지정하기 위해선 filter함수를 사용하는게 좋음.



🦁 Todolist-noDB

지금까지 배웠던 내용을 기반으로 todolist를 만들어보았다.

<app.js>

const express = require("express");
const todoRouter = require("./routes/todo"); 

const app = express(); 

const port = 3010;

app.use(express.json()); 
app.use("/todo", todoRouter); 

app.get("/", (req, res) => {
  res.send("Hello, My World!!");
}); 
app.listen(port, () => {
  console.log(`Server listening on port: ${port}🦁 `);
}); 
  • 해당코드는 Node.js를 사용하여 Todo List 웹 애플리케이션을 작성하는데 필요한 코드다.
  • 해당코드는 Express.js를 사용하여 간단한 RESTful API 서버를 구축하는 코드입니다.

  • const express = require("express");

    • express 모듈을 가져와서 app 변수에 할당
  • const todoRouter = require("./routes/todo");

    • todoRouter 모듈을 가져와서 /todo 경로로 마운트
  • const app = express();

    • express를 실행하여 앱 객체를 생성.
  • const port = 3010;

    • react서버와 겹치지 않게 서버가 실행될 포트 번호를 3010으로 설정
  • app.use(express.json());

    • JSON 형식의 요청 본문을 구문 분석하기 위해 express.json() 미들웨어를 사용

    • (미들웨어: 서로 다른 애플리케이션이 서로 통신하는 데 사용되는 소프트웨어)

  • app.use("/todo", todoRouter);

    • todoRouter 모듈이 /todo 엔드포인트에서 작동하도록 설정
  • app.get("/", (req, res) => {
    res.send("Hello, My World!!");
    });

    • 루트 URL (/)로 GET 요청이 들어왔을 때 "Hello, Express!" 메시지를 출력하도록 함.
  • app.listen(port, () => {
    console.log(Server listening on port: ${port}🦁 );
    });

    • listen() 함수를 사용하여 서버를 시작하고, 포트 번호가 log에 출력



<todo.js>

const express = require("express");

let todoData = require("../todoData.json");

const router = express.Router();


router.get("/", (req, res) => {
  console.log(todoData);

  res.json(todoData);
});

router.get("/:id", (req, res) => {
 
  const { id } = req.params;

  if (parseInt(id) >= todoData.length) {
    return res.status(400).json({ error: "존재하지 않는 ID입니다." });
  }

  res.json(todoData[parseInt(id)]); 
});


router.post("/", (req, res) => {
 
  const { title, desc } = req.body;

  if (!title || !desc) {
    
    return res
      .status(400)
      .json({ error: "타이틀이나 설명 중에 하나의 값은 입력해야 합니다." });
  }

  todoData.push({ title, desc, isDone: false });

  res.json(todoData);
});


router.put("/:id", (req, res) => {
 
  const { id } = req.params; 
  const { title, desc } = req.body; 

  if (parseInt(id) >= todoData.length) {
    return res.status(400).json({ erroe: "존재하지 않는 ID입니다." });
  }

  if (!title && !desc) {
    
    return res
      .status(400)
      .json({ error: "타이틀이나 설명 중에 하나의 값은 입력해야 합니다." });
  }

  todoData[parseInt(id)] = {
    title: title ? title : todoData[parseInt(id)].title,
    desc: desc ? desc : todoData[parseInt(id)].desc, 
    isDone: todoData[parseInt(id)].isDone,
  };

  res.json(todoData);
});

router.put("/done/:id", (req, res) => {
 
  const { id } = req.params; 

  if (parseInt(id) >= todoData.length) {
    return res.status(400).json({ erroe: "존재하지 않는 ID입니다." });
  }

  todoData[parseInt(id)] = {
    title: todoData[parseInt(id)].title,
    desc: todoData[parseInt(id)].desc,
    isDone: !todoData[parseInt(id)].isDone,
  };

  res.json(todoData);
});


router.delete("/:id", (req, res) => {
 
  const { id } = req.params;

  if (parseInt(id) >= todoData.length) {
    return res.status(400).json({ erroe: "존재하지 않는 ID입니다." }); 
  } 

  todoData = todoData.filter((v, i) => {
    return parseInt(id) !== i;
  });

  res.json(todoData);
});

module.exports = router;
  • 해당코드는 Node.js 기반의 Express 프레임워크를 사용하여 작성된 RESTful API의 라우팅을 처리하는 코드다.
    해당코드는 길기 때문에 최대한 축약해서 작성해보도록 하겠다.
  • 먼저 express 모듈을 가져오고, todoData라는 변수에 "../todoData.json" 파일의 내용을 할당한다. 이 파일에는 현재 Todo 앱에 등록된 Todo 항목들의 정보가 저장되어 있다.

  • router라는 객체를 생성하고, HTTP 요청의 메서드(GET, POST, PUT, DELETE)에 따라 다른 함수를 실행시키도록 한다. 전체 투두리스트를 조회할 수 있다.

  • GET /:id 요청을 받았을 때, 해당 id에 해당하는 Todo 항목을 반환한다. 만약 요청한 id가 todoData의 길이보다 크거나 같으면 "존재하지 않는 ID입니다."라는 에러를 반환한다.

    • 기존 DB에 있는 todo를 가져오고 DB에 없으면 error 가 뜨도록 만든 코드다.

    • 특정한 값을 얻기 위해서 parseInt(id) 를 추가함.

    • 특정 투두리스트를 조회할 수 있다.



  • POST / 요청을 받았을 때, 요청 본문에서 title과 desc를 추출하여 새로운 Todo 항목을 생성한다. 만약 title과 desc 중 하나라도 입력하지 않았다면 "타이틀이나 설명 중에 하나의 값은 입력해야 합니다."라는 에러를 반환한다.

    • 기존 내용에 내가 원하는 내용을 집어넣는 코드.

    • if문으로 둘 중 하나라도 없다는 조건이 만족할 때, 결과적으로 둘 중 하나라도 없을때의 조건이 성립할때 error 내용일 출력되도록 한다.

    • todoData.push({ title, desc, isDone: false }); 를 작성해 todoData DB에 push를 해주면 DB에 추가가 되도록 함.



  • PUT /:id 요청을 받았을 때, 해당 id에 해당하는 Todo 항목의 title과 desc 값을 수정한다. 만약 요청한 id가 todoData의 길이보다 크거나 같으면 "존재하지 않는 ID입니다."라는 에러를 반환한다. 또한, title과 desc 모두 입력하지 않았다면 "타이틀이나 설명 중에 하나의 값은 입력해야 합니다."라는 에러를 반환한다.

    • 특정 저장된 내용을 내가 원하는 내용으로 전체 변경하는 코드.

    • const { id } = req.params; 코드는 params로 todo를 받음. params는 하나만 받아올 수 있어서 body와는 다르다.

    • const { title, desc } = req.body; 코드는 json 형식으로 todo를 받아와야 해서 body를 사용.

    • 해당 코드에는 두개의 if문이 있는데 첫번째 if문의 조건은 요청한 id가 todoData의 길이보다 크거나 같으면이고, 두번째 if문의 조건은 둘 다 타이들이 없다는 조건을 만족할 때 이다.

    • title과 desc에 삼항연산자를 사용함으로서 title이나 desc중 원하는 값만 바꾸고 싶을때 사용한다. 기존에 값이 있으면 기존값이 사용되도록 한다.



  • PUT /done/:id 요청을 받았을 때, 해당 id에 해당하는 Todo 항목의 isDone 값을 반대로 전환한다. 만약 요청한 id가 todoData의 길이보다 크거나 같으면 "존재하지 않는 ID입니다."라는 에러를 반환한다.

    • 저장되어 있는 결과값(done)을 바꾸는 코드(업데이트).

    • isDone: !todoData[parseInt(id)].isDone,

      • 이코드는 !가 앞에 들어가기 때문에 결과값을 뒤집는다. true,false가 있으면 결과값이 바뀌어서 나온다.



  • DELETE /:id 요청을 받았을 때, 해당 id에 해당하는 Todo 항목을 삭제한다. 만약 요청한 id가 todoData의 길이보다 크거나 같으면 "존재하지 않는 ID입니다."라는 에러를 반환한다.

    • 저장되어 있는 내용 중 지우고 싶은 내용을 지울 수 있는 코드.

    • 위 모드 코드에 있는 status(400)는 text뿐만 아니라 코드의 오류를 알리기 위해 작성됨.

    • return parseInt(id) !== i;

      • parseInt(id)는 조회할때 쓰는 아이디 , !== 은 조건이 다른지를 묻는다. i는 같지가 않으면 살리고 같으면 삭제한다.



🌜하루를 마치며..

드디어 다 정리했다... 어제 못했던 부분까지 정리하려니
시간이 정말.. 휴...
그래도 다 정리하고 나니 뿌듯하긴 하다.
이것말고도 할일이 많은데 급하지 않은건 주말에 해야겠다.
오늘 강현님이 내 벨로그를 수업중에 얘기하셔서 너무 당황했다; 부족한 벨로그를 누군가 볼까봐 후다닥 비공개를 해버렸는데 막상 비공개 한것도 웃기기도 하고..
내가 틀릴지언정 내 노력이 부끄러운건 아니니까
다시 공개를 했다. 나의 블체스 마지막 벨로그는 지금보다 훨씬 완벽하겠지... 싶다?

profile
개발자가 되어가는 개린이"

0개의 댓글