<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>wooDevRecord</title>
        <link>https://velog.io/</link>
        <description>백엔드 성장 기록</description>
        <lastBuildDate>Thu, 09 Feb 2023 08:02:37 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>wooDevRecord</title>
            <url>https://velog.velcdn.com/images/woo_code/profile/2d59cafd-3cbc-4d5b-9400-d485eacdadc9/image.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. wooDevRecord. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/woo_code" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[notion 04 review]]></title>
            <link>https://velog.io/@woo_code/notion-04-review</link>
            <guid>https://velog.io/@woo_code/notion-04-review</guid>
            <pubDate>Thu, 09 Feb 2023 08:02:37 GMT</pubDate>
            <description><![CDATA[<p>이번엔 라우팅의 개념을 학습하고 refresh 도구인 nodemon을 설치하여 적용해보았다.</p>
<p>이전에 만들어 두었던 API를 Rest-API로 만들어본 뒤 express로 실행해 보았다. 또한, Swagger를 활용해 API-Docs를 제작했다.</p>
<p>코드캠프 동안 Nest.js와 GraphQL-API를 주로 사용하여 프로젝트를 진행해서 Node와 Rest-API는 확실히 익숙치가 않다.</p>
<h3 id="nodemon">nodemon</h3>
<p>코드를 수정할때마다 <strong>서버를 종료하고 다시 시작하기</strong>를 반복하는 문제점을 해결해주는 도구. </p>
<p>📌** 설치 방법**</p>
<ol>
<li><code>yarn add nodemon</code></li>
<li><code>package.json</code> 파일에 <code>scripts</code> 작성<pre><code>&quot;scripts&quot;: {
 &quot;dev&quot;: &quot;nodemon index.js&quot;
},</code></pre></li>
<li><code>yarn dev</code>로 서버 실행</li>
</ol>
<hr>
<h3 id="라우팅">라우팅</h3>
<blockquote>
<p>라우팅은 URI(또는 경로) 및 특정한 HTTP 요청 메소드(GET, POST 등)인 특정 엔드포인트에 대한 클라이언트 요청에 애플리케이션이 응답하는 방법을 결정하는 것을 말함.</p>
</blockquote>
<p><strong>라우팅의 기본 문법</strong>
<code>app.METHOD(PATH, HANDLER)</code></p>
<ul>
<li>app은 express의 인스턴스입니다.</li>
<li>METHOD는 HTTP 요청 메소드입니다.</li>
<li>PATH는 서버에서의 경로입니다.</li>
<li>HANDLER는 라우트가 일치할 때 실행되는 함수입니다.</li>
</ul>
<pre><code class="language-javascript">1. 홈페이지에서 &#39;Hello World!&#39;로 응답
app.get(&#39;/&#39;, function (req, res) {
  res.send(&#39;Hello World!&#39;);
});

2. 애플리케이션의 홈 페이지인 루트 라우트(/)에서 POST 요청에 응답
app.post(&#39;/&#39;, function (req, res) {
  res.send(&#39;Got a POST request&#39;);
});</code></pre>
<hr>
<h3 id="api-docs를-제작하기-위한-swagger-설치">API-Docs를 제작하기 위한 Swagger 설치</h3>
<p><strong>설치방법 :</strong><br><code>yarn add swagger-ui-express swagger-jsdoc</code></p>
<p><strong>Swagger 문법 :</strong> 
boards.swagger.js에 따로 작성</p>
<pre><code>/**
 * @swagger
 * /boards:
 *   get:
 *     summary: 게시글 가져오기
 *     tags: [Board]
 *     parameters:
 *          - in: query
 *            name: number
 *            type: int
 *     responses:
 *       200:
 *         description: 성공
 *         content:
 *           application/json:
 *              schema:
 *                  type: array
 *                  items:
 *                      properties:
 *                          number:
 *                              type: int
 *                              example: 3
 *                          writer:
 *                              type: string
 *                              example: 철수
 *                          title:
 *                              type: string
 *                              example: 제목입니다~~~
 *                          contents:
 *                              type: string
 *                              example: 내용입니다!!!
 */

/**
 * @swagger
 * /boards:
 *   post:
 *     summary: 게시글 등록하기
 *     tags: [Board]
 *     responses:
 *          200:
 *              description: 성공
 */</code></pre><p><strong>Swagger API문서를 만들어주는 문법</strong>
config.js에 따로 작성</p>
<pre><code class="language-Javascript">export const options = {
  definition: {
    openapi: &quot;3.0.0&quot;,
    info: {
      title: &quot;mini-poject-API-Docs&quot;,
      version: &quot;1.0.0&quot;,
    },
  },
  apis: [&quot;./swagger/*.swagger.js&quot;], // files containing annotations as above
};
</code></pre>
<p><strong>Swagger UI를 사용하기 위한 문법</strong>
index.js에 따로 추가</p>
<pre><code class="language-Javascript">import swaggerUi from &#39;swagger-ui-express&#39;
import swaggerJSDoc from &#39;swagger-jsdoc&#39;
import { options } from &#39;./swagger/config.js&#39;

...

app.use(&#39;/api-docs&#39;, swaggerUi.serve, swaggerUi.setup(swaggerJSDoc(options)));</code></pre>
<hr>
<h3 id="createtokenofphone를-rest-api로-만들기핸드폰-번호에-인증번호-전송-로직"><strong>createTokenOfPhone</strong>를 <strong>Rest-API</strong>로 만들기(핸드폰 번호에 인증번호 전송 로직)</h3>
<pre><code class="language-javascript">// index.js

import express from &quot;express&quot;;
import {
  checkValidationPhoneNumber,
  getToken,
  sendTokenToSMS,
} from &quot;./phone.js&quot;;
import swaggerUi from &quot;swagger-ui-express&quot;;
import swaggerJSDoc from &quot;swagger-jsdoc&quot;;
import { options } from &quot;./swagger/config.js&quot;;

const app = express();

app.use(express.json()); // express는 기본적으로 JSON을 읽지 못하므로 JSON을 읽을 수 있게 만들어주는 문법

app.use(&quot;/api-docs&quot;, swaggerUi.serve, swaggerUi.setup(swaggerJSDoc(options))); // swagger UI를 사용하기 위한 문법


app.post(&quot;/tokens/phone&quot;, (req, res) =&gt; {
  const myPhone = req.body.myPhone;

  // 1. 휴대폰 번호 자릿수 확인
  const isValid = checkValidationPhoneNumber(myPhone);
  if (isValid === true) {
    // 2. 핸드폰 토큰 6자리 만들기
    const myToken = getToken();

    // 3. 핸드폰 번호에 토큰 전송
    sendTokenToSMS(myPhone, myToken);
    res.send(&quot;인증 완료&quot;);
  }
});

app.listen(3000, () =&gt; {
  console.log(`Example app listening on port ${3000}`);
});</code></pre>
<br/>

<pre><code class="language-javascript">
// phone.js

export function checkValidationPhoneNumber(phoneNumber) {
  if (phoneNumber.length !== 10 &amp;&amp; phoneNumber.length !== 11) {
    console.log(&quot;Error, 핸드폰 번호를 정확히 입력해주세요.&quot;);
    return false;
  } else {
    return true;
  }
  // if문을 활용한 에러핸들링 추가(phoneNumber)
}

export function getToken() {
  const count = 6;

  if (count === undefined) {
    console.log(&quot;Error, count의 값을 입력해주세요.&quot;);
    return;
  } else if (count &lt;= 0) {
    console.log(&quot;Error, count의 값이 너무 작습니다.&quot;);
    return;
  } else if (count &gt; 10) {
    console.log(&quot;Error, count의 값이 너무 큽니다.&quot;);
    return;
  }
  // if문을 활용한 에러핸들링 추가(count)

  const Token = String(Math.floor(Math.random() * 10 ** count)).padStart(
    count,
    &quot;0&quot;
  );

  return Token;
}

export function sendTokenToSMS(phoneNumber, Token) {
  console.log(`${phoneNumber}번호로 인증번호 ${Token}이 전송되었습니다.`);
}
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[notion day3 review]]></title>
            <link>https://velog.io/@woo_code/notion-day3-review</link>
            <guid>https://velog.io/@woo_code/notion-day3-review</guid>
            <pubDate>Tue, 07 Feb 2023 04:52:53 GMT</pubDate>
            <description><![CDATA[<p>이번 시간엔 HTTP 통신의 개념과 요청(request), 응답(response)에 대해 공부했다.
HTTP가 어떤 방식으로 데이터를 주고 받는지에 대해 알게 되었으며, 시작라인, 헤더, 바디의 구성으로 이루어져있는 개념을 조금 더 확실하게 알게 되었다.</p>
<p>백엔드 개발자의 꽃 API의 종류와 특징에 대해서도 학습했으며, Rest-API와 GraphQL-API의 특징들과 CRUD의 적용 또한 다시 한번 확실하게 되짚고 넘어갔다.</p>
<p>API를 만드는 과정은 사실 잘 복사하고 그것을 잘 응용하여 계속 만지다보면 이해가 되었지만, 이런 이론적인 부분을 깊숙하게 이해하지못하고 넘어갔었다는걸 다시 한번 깨닫게 된다. 배울것이 너무 많다! 하지만 그걸 내것으로 이해하고 넘어가는 이 과정이 너무 즐겁다!!</p>
<h3 id="http-통신이란">HTTP 통신이란?</h3>
<blockquote>
<p>HyperText Transfer Protocol의 약자로 두 컴퓨터간에 텍스트 데이터를 주고 받는 길을 말함.</p>
</blockquote>
<p>HTTP란 길로 요청(request)과 응답(response)을 받을 수 있다.<img src="https://velog.velcdn.com/images/woo_code/post/d5f8648e-79e2-487f-8c6c-773f07f396b1/image.png" alt=""></p>
<hr/>

<h3 id="http-요청request">HTTP 요청(Request)</h3>
<p>웹브라우저에서 홈페이지(Front-end 컴퓨터)가 실행중이라면
작성한 게시물 텍스트 데이터를 HTTP를 통해 Back-end 컴퓨터로 보내고 ,
 Back-end 컴퓨터에게 이 데이터를 데이터베이스에 저장 해달라고 <strong>요청</strong>
 <img src="https://velog.velcdn.com/images/woo_code/post/69a710dd-3e2c-482a-8597-7a5a74b3d378/image.png" alt=""></p>
 <hr/>



<h3 id="http-응답response">HTTP 응답(Response)</h3>
<p> 요청을 받은 Back-end 컴퓨터가 성공, 실패 등 처리 결과를 <strong>응답</strong>
 <img src="https://velog.velcdn.com/images/woo_code/post/387d90da-7f34-4abe-97c9-483e6086c425/image.png" alt=""></p>
<blockquote>
<p><strong>Plus! **
**HTTP 상태 코드</strong>
Back-end 컴퓨터는 응답할 때, HTTP 상태 코드 라는 것도 함께 보내줍니다.
HTTP 상태 코드는 100~ 599까지의 숫자로 구성되어 있습니다.
자주 볼 수 있는 HTTP 상태 코드는 성공(200), Front-end 에러(400), Back-end 에러(500) 등이 있습니다.
예를 들면, 요청에 성공하였으면 성공 메시지와  HTTP 상태 코드 200을 함께 보내줍니다.</p>
</blockquote>
<p>다양한 HTTP 상태 코드(MDN): <a href="https://developer.mozilla.org/ko/docs/Web/HTTP/Status">https://developer.mozilla.org/ko/docs/Web/HTTP/Status</a></p>
<blockquote>
<p><strong>Plus!2</strong>
<strong>데이터베이스에 바로 요청하면 안되는 이유?</strong>
보안 및 데이터 정제 등의 이유로 Back-end에서 검증 과정을 거쳐야 하기 때문에, 아무나 함부로 데이터베이스에 요청할 수 없습니다.</p>
</blockquote>
<hr/>

<h3 id="api란">API란?</h3>
<blockquote>
<p>HTTP 요청을 Back-end 컴퓨터에 보냈을 때 실행되는 Back-end 기능</p>
</blockquote>
<p>예를 들어, 만약 게시물이 아닌 프로필 데이터를 저장하고 싶으면 어떻게 해야 할까??</p>
<p>그러기 위해선 <code>여러개의 HTTP 라는 길이 존재</code>해야 하고, 각각의 요청마다 담당자가 필요하며, 이러한 담당자를 <code>API</code> 라고 한다.<img src="https://velog.velcdn.com/images/woo_code/post/3d88f83f-9c51-4b16-9944-c15c8e1aa9ad/image.png" alt=""></p>
<p>API의 종류는 크게 Rest-API와 GraphQL-API가 있다.</p>
<p><strong>Rest-API</strong></p>
<ul>
<li><p>홈페이지 주소와 같은 이름
<a href="https://naver.com/board/1">https://naver.com/board/1</a>
  <a href="https://naver.com/profile/%EC%B2%A0%EC%88%98">https://naver.com/profile/철수</a></p>
</li>
<li><p>응답의 결과로 함수에서 보내주는 모든 데이터를 받아야만 함</p>
</li>
<li><p>요청 담당자는 axios</p>
</li>
</ul>
<p><strong>GraphQL</strong></p>
<ul>
<li>일반 함수와 같은 이름
board(1)
profile(&quot;철수&quot;)</li>
<li>응답의 결과를 함수에서 필요한 데이터만 골라 받아올 수 있음
요청 담당자는 apollo-client<blockquote>
<p><strong>axios, apollo-client란?</strong>
Front-end에서 설치하는 데이터를 백엔드에 요청할 때 사용하는 라이브러리</p>
</blockquote>
</li>
</ul>
<p>API 요청의 결과를 자세히 보면 <code>key</code>와 <code>value</code>처럼 보인다.
이를 자바스크립트(<strong>J</strong>ava<strong>s</strong>cript)의 객체(<strong>O</strong>bject)처럼 표기(<strong>N</strong>otation)할 수 있는데, 앞글자를 따서 <strong>JSON</strong>(API 요청 결과 타입)이라고 부른다.</p>
<pre><code class="language-JSON">{
    작성자: &quot;훈이&quot;,
    제목: &quot;좋은 아침입니다&quot;
}</code></pre>
<hr/>

<h3 id="http-헤더와-바디">HTTP 헤더와 바디</h3>
<blockquote>
<p>HTTP로 요청과 응답을 보낼 때, 그 메시지 안에는 <strong>시작라인, 헤더와 바디</strong>가 있다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/woo_code/post/a6ba2dda-7566-4b2a-8909-9c48902ade37/image.png" alt=""></p>
<p><strong>HTTP 요청 메시지</strong></p>
<ul>
<li><code>시작 라인</code><ul>
<li>HTTP 메서드 (GET, POST 등)</li>
<li>요청 엔드포인트 (&#39;/board&#39;)</li>
<li>HTTP 버전</li>
</ul>
</li>
<li><code>헤더</code><ul>
<li>Host : 요청을 보내는 브라우저의 주소</li>
<li>Content-Type : 응답하는 메시지의 내용이 어떤 종류인지</li>
</ul>
</li>
</ul>
<p><strong>HTTP 응답 메시지</strong></p>
<ul>
<li><code>시작 라인</code><ul>
<li>HTTP 버전</li>
<li>HTTP 상태 코드 (200, 400, 500 등)</li>
</ul>
</li>
<li><code>헤더</code><ul>
<li>Content-Type : 응답하는 메시지의 내용이 어떤 종류인지</li>
</ul>
</li>
</ul>
<p>요청과 응답 모두 Body가 들어갈 수 있으며, 실제 전송하려는 데이터가 이곳 Body 객체에 담을 수 있다.</p>
<hr>
<h3 id="api와-crud">API와 CRUD</h3>
<p>API는 크게 4가지 방식으로 구분할 수 있다.</p>
<ol>
<li>새로운 것을 <code>생성</code>하는 <code>API</code>    ⇒   <strong>C</strong>REATE</li>
<li>기존의 것을 <code>조회</code>하는 <code>API</code>    ⇒   <strong>R</strong>EAD</li>
<li>기존의 것을 <code>수정</code>하는 <code>API</code>    ⇒   <strong>U</strong>PDATE</li>
<li>기존의 것을 <code>삭제</code>하는 <code>API</code>    ⇒   <strong>D</strong>ELETE</li>
</ol>
<p>앞글자를 따서 CRUD라고 부르는데, <code>Rest-API</code>와 <code>GraphQL-API</code>에서 사용하는 방식이 다르다!</p>
<p><img src="https://velog.velcdn.com/images/woo_code/post/a07e3651-340a-408e-99be-e25eb4957081/image.png" alt=""></p>
<p><code>Rest-API</code>는 CRUD 마다 사용하는 방식(method)이 존재한다.
CREATE =&gt; <strong>POST</strong>
READ =&gt; <strong>GET</strong>
UPDATE =&gt; <strong>PUT</strong>
DELETE =&gt; <strong>DELETE</strong></p>
<p><code>GraphQL-API</code>는 데이터를 조작하지 않고 조회만 할때는 <strong>QUERY</strong>, 그 외의 데이터를 조작할 때는 <strong>MUTATION</strong>을 사용한다.</p>
<blockquote>
<p><strong>한장으로 정리!</strong>
<img src="https://velog.velcdn.com/images/woo_code/post/390f10ef-7d14-41cb-a87a-761dd52b7cde/image.png" alt=""></p>
</blockquote>
<p>API CRUD를 테스트 하기 위한 포스트맨, 스웨거, 플레이그라운드는 꽤 많이 사용해봤으니 이에 대한 사용법은 넘어가도 좋을거같다!..</p>
<hr>
<h3 id="express란">Express란?</h3>
<blockquote>
<p>Node에서 쉽게 웹 서버를 개발할 수 있도록 도와주는 프레임워크</p>
</blockquote>
<p><strong>Express의 역할</strong>
프론트에서 우리가 만든 백엔드 API로 요청을 할 때, 먼저 그 요청을 잘 받은 후 요청에 대해 응답을 잘 해주도록 도와주는게 <code>express</code>다.</p>
<p><strong>Express 실습!</strong></p>
<ol>
<li><p>실습할 파일에 <code>yarn init</code>으로 <code>package.json</code> 생성 후 ````&quot;type&quot;: &quot;module&quot;``` 추가</p>
</li>
<li><p>express Docs를 참조하여 <code>index.js</code> 작성</p>
<pre><code class="language-Javascript">import express from &#39;express&#39;
</code></pre>
</li>
</ol>
<p>const app = express()</p>
<p>// GET 요청이 들어왔을 때
app.get(&#39;/&#39;, (req, res) =&gt; {
  res.send(&#39;Hello World!&#39;) // 응답 보내기
})</p>
<p>app.listen(3000, () =&gt; {
  console.log(<code>Example app listening on port ${3000}</code>) 
}) // 3000번 포트에서 24시간 실행</p>
<p><code>3.</code>node index.js``` 로 서버 실행, 서버 종료는 control + c</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[notion day2 review]]></title>
            <link>https://velog.io/@woo_code/notion-day2-review</link>
            <guid>https://velog.io/@woo_code/notion-day2-review</guid>
            <pubDate>Tue, 07 Feb 2023 03:56:04 GMT</pubDate>
            <description><![CDATA[<p>이번엔 회원가입 성공 시 회원가입을 환영하는 이메일 템플릿을 node.js로 구현해보았다.</p>
<p>구조분해할당(Destructuring)과 shorthand property names에 대한 개념을 배우고 실습을 통하여 복습했다.</p>
<blockquote>
<p><strong>shorthand property names란?</strong>
객체를 정의할 때 동일한 key와 value의 이름으로 사용하게 되는 경우가 있는데, 이때 value를 생략할 수 있습니다. 이를 shorthand property names라고 합니다.</p>
</blockquote>
<p>구조분해할당을 사용할 땐 객체와 배열의 특성이 달리 적용되어 처음엔 조금 햇갈렸지만 실제로 사용해보고 console.log를 찍어보니 완벽히 이해가 되었다.</p>
<blockquote>
<p><strong>객체와 배열의 구조분해할당</strong>
객체 : 객체를 구조분해할당 하게 될 경우 객체 안의 key값을 가져와 할당 =&gt; 객체 안의 존재하는 key값의 이름으로 재할당해야하며 순서는 상관없음<br/>
배열 : 배열은 구조분해할당 시, 배열의 순서가 매우 중요함</p>
</blockquote>
<hr/>
<br/>

<h3 id="회원가입-템플릿">회원가입 템플릿</h3>
<p>이번에 만든 회원가입 템플릿 로직도 pacade 패턴을 적용하였다.</p>
<pre><code class="language-javascript">index.js
import { checkValidationEmail, getWelcomeTemplate, sendWelcomeTemplateToEmail } from &quot;./email.js&quot;;

function createUser(user){
    const isVaild = checkValidationEmail(user.email);
    if(isVaild === true){
        const template = getWelcomeTemplate(user);

        sendWelcomeTemplateToEmail(user.email, template)
    }
}

const user = {
    name: &#39;김지우&#39;,
    age: 28,
    school: &#39;다문대학교&#39;,
    email: &#39;wldn0000@naver.com&#39;,
  };

  createUser(user)

email.js
import { getToday } from &quot;./utils.js&quot;;

// 이메일 검증
export function checkValidationEmail(email) {
  if (email === undefined || !email.includes(&#39;@&#39;)) {
    console.log(&#39;정확한 이메일 주소를 입력해주세요.&#39;);
    return false;
  }
  return true;
}

// 회원가입 템플릿
export function getWelcomeTemplate({name, age, school}){
    return `
        &lt;html&gt;
            &lt;body&gt;
                &lt;h1&gt;${name}님 가입을 환영합니다.&lt;/h1&gt;
                &lt;hr /&gt;
                &lt;div&gt;이름: ${name}&lt;/div&gt;
                &lt;div&gt;나이: ${age}살&lt;/div&gt;
                &lt;div&gt;학교: ${school}&lt;/div&gt;
                &lt;div&gt;가입일: ${getToday()}&lt;/div&gt;
            &lt;/body&gt;
        &lt;/html&gt;
    `
}

// 템플릿을 이메일로 전송
export function sendWelcomeTemplateToEmail(email, template){
    // 템플릿을 이메일에 전송
    console.log(`${email}로 템플릿 ${template}를 전송합니다.`)
}</code></pre>
<p>가입일 부분은 <code>getToday</code> 함수를 만들어서 로직에 적용시켰으며, <code>new Date()</code>메서드를 활용하였다.</p>
<blockquote>
<p><strong>new Date()</strong>
const date = new Date()     // 자바스크립트 Date객체를 date라는 변수에 할당합니다.
date.getFullYear();         // 연도를 반환합니다.
date.getMonth();            // 월을 반환합니다. 0(월)부터 시작하므로 주의하세요!
date.getDate();             // 일을 반환합니다.
date.getDay();              // 요일을 반환합니다.(일요일: 0)
date.getHours();            // 시를 반환합니다.
date.getMinutes();          // 분을 반환합니다.
date.getSeconds();          // 초를 반환합니다.
date.getMilliseconds();     // 밀리초를 반환합니다.</p>
</blockquote>
<pre><code>export function getToday() {
    const date = new Date()
    const year = date.getFullYear()
    const month = date.getMonth() + 1
    const day = date.getDay()
    return `${year}-${month}-${day}`
}
console.log(getToday());</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[notion day1 review]]></title>
            <link>https://velog.io/@woo_code/notion-day1-review</link>
            <guid>https://velog.io/@woo_code/notion-day1-review</guid>
            <pubDate>Thu, 02 Feb 2023 05:21:38 GMT</pubDate>
            <description><![CDATA[<p>코드캠프에서 배웠던 기술 스택들은 짧고 빠르게 지나가서 많은걸 배웠음에도 깊게 익히지 못하고 넘어간것들이 많다.</p>
<p>내가 추구하는 개발자의 역량은 기본에서부터 나온다고 생각하기 때문에 수업때 배웠던 자료들을 바탕으로 복습을 하며 블로그에 기록을 하려고한다.</p>
<p><strong>Node.js와 npm, yarn을 설치하고 사용하는 방법을 익혔으며, 핸드폰 번호와 인증번호 자릿수를 입력하여 토큰을 받는 API를 하나 만들게 되었다.</strong></p>
<p>API를 만든 후에 <code>yarn init</code> 명령어로 package.jason파일을 만들고 import와 export를 사용할 수 있게 만든 후 Pacade 패턴을 적용하여 실무에 더욱 가깝게 로직을 만들어 보았다.</p>
<pre><code class="language-javascript">1. 핸드폰 번호 에러핸들링 로직
export function checkToPhoneNumber(phoneNumber){
    if(phoneNumber.length !== 10 &amp;&amp; phoneNumber.length !== 11){
        console.log(&quot;Error, 핸드폰 번호를 정확하게 입력해주세요.&quot;);
        return false;
    } else {
        return true;
    }
}

2. 인증번호 발급 로직, 에러핸들링 로직
export function getToken(count){
    if(count === undefined){
        console.log(&quot;Error, 인증번호의 자릿수를 입력해주세요.&quot;);
        return;
    } else if(count &gt; 12){
        console.log(&quot;Error, 인증번호의 자릿수가 너무 높습니다.&quot;);
        return;
    } else if(count &lt;= 0){
        console.log(&quot;Error, 인증번호의 자릿수가 너무 낮습니다.&quot;);
        return;
    }

    const token = String(Math.floor(Math.random() * 10 ** count)).padStart(count, &#39;0&#39;)

    return token;
}

3. 요청받은 핸드폰 번호로 인증번호를 전송하는 로직(아직 단순하게 console.log로 나타나게끔만 작성 됨)
export function sendTokenToSMS(phoneNumber, count){
    console.log(`${phoneNumber} 번호로 인증번호 ${count}를 전송합니다.`);
}

4. 인증번호 요청 API
import {checkToPhoneNumber, getToken, sendTokenToSMS} from &quot;./phone.js&quot;

function createTokenOfPhone(phoneNumber, count){
    const isVaild = checkToPhoneNumber(phoneNumber);

    if(isVaild === true){
        const token = getToken(count);
        sendTokenToSMS(phoneNumber, token);
    }
}

createTokenOfPhone(&quot;01012345678&quot;, 6)</code></pre>
<p>다만 여기서 한가지 문제점이 있는데, <code>getToken</code> 함수에서 자릿수를 크게 요청하면 <code>&quot;Error, 인증번호의 자릿수가 너무 높습니다.&quot;</code>가 정상적으로 출력되지만, <code>createTokenOfPhone</code> 함수에서 자릿수를 크게 요청하면 return이 적용이 안되고 <code>01012345678 번호로 인증번호 undefined를 전송합니다.</code>라는 메세지가 출력된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Node.js와 npm, yarn]]></title>
            <link>https://velog.io/@woo_code/Node.js%EC%99%80-npm-yarn</link>
            <guid>https://velog.io/@woo_code/Node.js%EC%99%80-npm-yarn</guid>
            <pubDate>Thu, 02 Feb 2023 03:26:06 GMT</pubDate>
            <description><![CDATA[<h3 id="nodejs란">Node.js란?</h3>
<p>웹 애플리케이션을 만들기 위해 브라우저 상에서 HTML, CSS, JavaScript 언어를 사용합니다. </p>
<p>이때 JavaScript 언어를 실행하기 위해서 우리는 매번 브라우저를 이용해야만 했습니다.</p>
<p>하지만 이러한 불편한 점을 개선하여 <strong>내 로컬 환경에서도 JavaScript 언어를 실행</strong>하기 위해 Node.js가 만들어졌습니다.</p>
<p>공식문서에는 Node.js를 <strong>Chrome V8 JavaScript 엔진으로 빌드 된 JavaScript 런타임(환경)</strong>이라고 설명하고 있습니다. </p>
<blockquote>
<p><strong>쉽게 말해서 Node.js란 JavaScript를 실행할 수 있는 프로그램이라고 볼 수 있습니다.</strong><br/>
Node.js가 만들어지기 전 브라우저만이 JavaScript 실행기였다면, Node.js가 만들어 진 후에는 JavaScript 실행기가 하나 더 만들어졌다고 말할 수 있습니다.</p>
</blockquote>
<hr/>
<br/>

<h3 id="npm이란">npm이란?</h3>
<p><strong>Node Package Manager</strong>로 Node.js 기반에서 실행될 수 있는 모듈(프로그램보다 작은 단위의 기능들)을 관리하는 패키지 매니저를 뜻합니다.</p>
<p>많은 개발자들이 자신이 만든 모듈, 라이브러리 등을 공유하기 위해 npm 사이트(공개 저장소)에 등록해 놓았고, 우리는 필요할 때 마다 이 모듈들을 가져와 사용함으로써 개발에 쓰이는 시간을 단축할 수 있게 됩니다.</p>
<p>npm 사이트를 방문하여 살펴보면 다른 사람들이 만들어놓은 소스코드들을 무료로 다운받아 올 수 있습니다.</p>
<hr/>
<br/>

<h3 id="yarn이란">yarn이란?</h3>
<p>페이스북이 자체 개발한 것으로 npm과 같은 역할을 하는 <strong>JavaScript 패키지 매니저</strong>입니다.</p>
<p>성능(속도)과 보안 이슈를 보완한 JavaScript 패키지 매니저라고 볼 수 있습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Node.js, yarn 설치]]></title>
            <link>https://velog.io/@woo_code/Node.js-yarn-%EC%84%A4%EC%B9%98</link>
            <guid>https://velog.io/@woo_code/Node.js-yarn-%EC%84%A4%EC%B9%98</guid>
            <pubDate>Thu, 02 Feb 2023 03:19:06 GMT</pubDate>
            <description><![CDATA[<h3 id="nodejs-설치for-mac">Node.js 설치(for mac)</h3>
<p><img src="https://velog.velcdn.com/images/woo_code/post/57b0773c-8d41-483d-8a04-36ef9eb4bb46/image.png" alt=""></p>
<ol>
<li>Mac OS라면 위의 버튼을 눌러 LTS 버전의 설치 파일을 다운로드</li>
<li>다운로드가 완료 되면 파일을 실행하고, 계속 next를 눌러 설치<hr/>
<br/>

</li>
</ol>
<h3 id="nodejs-설치-확인">Node.js 설치 확인</h3>
<p><img src="https://velog.velcdn.com/images/woo_code/post/e69fbe7e-8e89-45a5-abe1-491c4cc3e14c/image.png" alt="">
터미널에 <code>node -v</code>로 버전 확인 가능</p>
<blockquote>
<p>Node.js를 설치하면 npm도 함께 다운로드 된다.
<code>npm -v</code>로 버전 확인 가능</p>
</blockquote>
<hr/>
<br/>

<h3 id="yarn-설치">yarn 설치</h3>
<blockquote>
<p>npm을 이용한 yarn 설치
<img src="https://velog.velcdn.com/images/woo_code/post/fdeabc68-9abd-4516-8a84-f0b713413bb7/image.png" alt=""></p>
</blockquote>
<ol>
<li>터미널에 <code>sudo npm install -g yarn</code> 입력</li>
<li>Node.js와 마찬가지로 <code>yarn -v</code>로 버전 확인 가능</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[수료 회고록]]></title>
            <link>https://velog.io/@woo_code/%EC%88%98%EB%A3%8C-%ED%9A%8C%EA%B3%A0%EB%A1%9D</link>
            <guid>https://velog.io/@woo_code/%EC%88%98%EB%A3%8C-%ED%9A%8C%EA%B3%A0%EB%A1%9D</guid>
            <pubDate>Tue, 31 Jan 2023 06:41:59 GMT</pubDate>
            <description><![CDATA[<p>4개월간의 코드 캠프 커리큘럼을 무사히 마치고 수료를 하게 되었다.</p>
<p>비전공자에게 길다면 길고 짧다면 짧은 시간이었으며 수많은 이슈들을 해결하면서 개발자로서 성장했지만 돌이켜보니 꽤 많은 아쉬움이 남았다.</p>
<p>공부를 했던 방법이나 시간이 촉박하여 미뤄왔던 것들을 포함해서 머릿속이 복잡한데 그동안 미뤄왔던 가정사의 해결 해야 할 문제들도 해결하다보니 수료하고 일주일이 지난 이제서야 다시 코딩에 집중해야 할 시간이 갖춰졌다.</p>
<p>이제 취업을 향하여 달릴 일만 남았는데 여전히 시간은 급하지만 차분하고 꼼꼼하게 그동안 배워왔던 공부법과 함께 챙기지 못한 것들까지 공부하면서 힘차게 달려나가려 한다!</p>
<p>코드 캠프에서 배워왔던 기술들을 다시 복습하며 알고리즘 공부와 평소에 공부해 보고 싶었던 심화적인 부분까지 강의를 들으면서 블로그에 정리하며 공부를 할 것이다.</p>
<p>물론 팀원들끼리 만들 팀 프로젝트와 개인 프로젝트를 리팩토링하며 이력서와 포폴 준비도 해야된다.</p>
<p>할게 산더미 같고 취업까지 막막하긴 하지만 열심히! 꾸준히! 취업에 성공하는 그날까지 나를 믿으며 정진하자!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[8주간의 회고록]]></title>
            <link>https://velog.io/@woo_code/8%EC%A3%BC%EA%B0%84%EC%9D%98-%ED%9A%8C%EA%B3%A0%EB%A1%9D</link>
            <guid>https://velog.io/@woo_code/8%EC%A3%BC%EA%B0%84%EC%9D%98-%ED%9A%8C%EA%B3%A0%EB%A1%9D</guid>
            <pubDate>Fri, 23 Dec 2022 14:25:22 GMT</pubDate>
            <description><![CDATA[<h3 id="두-달-전의-내-모습과-현재의-내-모습">두 달 전의 내 모습과 현재의 내 모습..</h3>
<p>코드 캠프에 오기 전, 대학교를 졸업하기 전.. 즉 약 2년 전의 나는 공부와는 전혀 관계없는 직업을 선택하며 살아갔다. </p>
<p>이제 와서 생각해 보면 학창 시절부터 공부에 소질이 없진 않았는데, 공부를 하기 싫어서 포기하고 몸을 쓰는 일을 선택했던 것 같다.</p>
<p>그렇게 요식업과 여러 가지 일을 병행하면서 살아오다가 문득 뒤늦은 후회를 하게 되었다. 공부를 진작에 더 했다면 더 나은 인생을 살고 있지 않았을까? 그래서 남들보다 늦은 나이에 전문 대학에 들어가 졸업을 하고 뭘 하면서 살아야 할지 고민을 했다.</p>
<p>그 와중에 생전 겪었던 악재 중의 최대의 악재들이 겹치면서 방향을 잃어가던 찰나에 대학교 수업 때 배웠던 코딩 수업이 생각이 났다.</p>
<p>산업디자인과를 졸업한 내게 포토샵과 일러스트레이터보다 더욱 재밌었던 코딩, 물론 그땐 포트폴리오 용으로 간단히 만들 수 있도록 기본적인 Html과 CSS만 배웠지만 그 시간만큼을 수업 시간 때 졸지도 않고 무척 즐겁게 공부했었다.</p>
<p>이상한 소리지만 나름 컴퓨터 앞에 오래 앉아있는 것도 몇 안 되는 특기 중 하나였기에 컴퓨터로 개발하는 개발자에 이끌렸다.</p>
<p>그렇게 겨우 방향성을 잡고 나서 개발자가 되기 위한 길을 알아보았는데, 이 나이에 다시 컴공과를 입학하고 졸업하기엔 많은 용기가 필요했으며, 국비 지원 수업 또한 경험해 보지 못해서 도중에 포기를 할까 봐 겁이 났다.</p>
<p>몇날 며칠을 검색, 또 검색 한 결과 코드 캠프 홈페이지에 다다랐다. 남들에겐 상업적으로 보일 수 있는 홈페이지의 멘트들이 내게는 누구보다도 절박하게 읽혀왔으며, 정말 오랜만에 꿈에 대한 열정이 꿈틀거렸다.</p>
<p>다른 사람들에게는 몰라도 내게는 매우 부담되고 큰 금액이었지만 내가 살아가고 싶은 내 인생을 위해 과감하게 코드 캠프에 신청을 했다.</p>
<p>사실 어느 정도 코딩에 대해 쉽게 생각한 것도 있었다. 대학교 시절에 배운 개념도 조금은 있었으니 열심히만 한다면 3개월 후에 나는 코딩을 엄청 잘 하겠지? 라는 부푼 희망도 있었다.</p>
<p>그렇게 베이스캠프가 시작되고 어느새 정신을 차려보니 8주 차 수업까지 모두 수강을 한 상태였다.</p>
<p>지금 돌이켜보면 아쉬운 부분들이 너무 많았다. 잠을 좀 더 공부하거나 배우거나, 수업 시간에 조금 더 집중했으면 좀 달라졌을까?</p>
<p>겨우겨우 수업 커리큘럼을 따라가기에도 벅차서 수업 내용을 참고하지 않는 이상 오로지 내 힘으로만 코딩하기엔 아직 벅차다... </p>
<p>하지만 앞으로도 내가 포기만 하지 않는다면 언젠가는 내가 원하던 개발자의 모습으로 살아가는 나 자신을 상상하며 노력할 것이다.</p>
<p>지금 내 모습은 3개월 전에 내가 생각하던 모습보단 많이 미흡하지만, 그래도 성장한 것 또한 사실이니 스스로에게 응원을 해주고 싶다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[gitflow, workflow]]></title>
            <link>https://velog.io/@woo_code/gitflow-workflow</link>
            <guid>https://velog.io/@woo_code/gitflow-workflow</guid>
            <pubDate>Fri, 23 Dec 2022 14:03:24 GMT</pubDate>
            <description><![CDATA[<h3 id="1️⃣-branch">1️⃣ Branch</h3>
<blockquote>
<p>브랜치(Branch)란 독립적으로 어떤 작업을 진행하기 위한 개념입니다. 필요에 의해 만들어지는 각각의 브랜치는 다른 브랜치의 영향을 받지 않기 때문에, 여러 작업을 동시에 진행할 수 있습니다.</p>
</blockquote>
<p>개발자들은 협업을 진행할 때 동일한 소스코드를 함께 공유하게 됩니다.</p>
<p>개발자들마다 각각 역할을 나누는데 어떤 사람은 버그를 수정하고, 어떤 사람을 기능을 개발하기도 합니다. </p>
<p><strong>동일한 코드를 여러 사람이 다른 작업을 할 때 서로 다른 버전의 코드가 만들어지는데, 이 때 동시에 여러 작업을 할 수 있도록 Branch(브랜치)를 사용합니다.</strong></p>
<p>*<em>분리된 작업 영역에서 수정을 하고 나중에 원래 버전과 비교해서 하나의 새로운 버전을 만듭니다.
*</em>
<br/></p>
<h3 id="2️⃣-git-workflow">2️⃣ Git Workflow</h3>
<h4 id="git-branch-전략들">Git Branch 전략들</h4>
<blockquote>
<p><strong>master, develop, feature, release, hotfix</strong></p>
</blockquote>
<ul>
<li><p>master : 기준이 되는 브랜치로 제품을 배포하는 브랜치</p>
</li>
<li><p>develop : 개발 브랜치로 개발자들이 이 브랜치를 기준으로 각자 작업한 기능들을 Merge</p>
</li>
<li><p>feature : 단위 기능을 개발하는 브랜치로 기능 개발이 완료되면 develop 브랜치에 Merge</p>
</li>
<li><p>release : 배포를 위해 master 브랜치로 보내기 전에 먼저 QA(품질검사)를 하기위한 브랜치</p>
</li>
<li><p>hotfix : master 브랜치로 배포를 했는데 버그가 생겼을 떄 긴급 수정하는 브랜치
<img src="https://velog.velcdn.com/images/woo_code/post/fa1a3344-44d9-4b35-96d0-8238e80548da/image.png" alt=""></p>
</li>
</ul>
<br/>

<h3 id="3️⃣-git-fork-workflow---forking-repository">3️⃣ Git Fork Workflow - Forking Repository</h3>
<blockquote>
<p>Git Fork Workflow는 저장소를 fork(복제) 해서 협업하는 작업 과정을 말합니다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/woo_code/post/d1561be1-045e-4cb9-9cc8-568f6c938309/image.png" alt=""></p>
<p><code>&lt;출처&gt;</code> : <a href="https://www.notion.so/dingco/40-Git-Workflow-ef55a01ce71240aab83906ded49d936d#cae9722533284931a740cb9ea768c0be">Notion/ 40일차 Git Workflow</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[notion_13]]></title>
            <link>https://velog.io/@woo_code/notion13</link>
            <guid>https://velog.io/@woo_code/notion13</guid>
            <pubDate>Wed, 21 Dec 2022 08:32:58 GMT</pubDate>
            <description><![CDATA[<p>팀프로젝트 전에 복습하는 기록</p>
<h3 id="--nestjs-다운로드">- NestJS 다운로드</h3>
<pre><code class="language-javascript">1. 터미널에 다운로드 입력
yarn add -g @nestjs/cli
- permission denined 에러가 날 경우 명령어 앞에 sudo 를 붙여 관리자 권한으로 설치

- Missing list of packages to add to your project 에러가 날 경우
yarn add global @nestjs/cli 으로 설치

2. 설치 확인을 위해 nest -version를 입력하여 설치된 버전 확인</code></pre>
<h3 id="--nest-프로젝트-생성">- Nest 프로젝트 생성</h3>
<pre><code class="language-javascript">1. nest new aaa =&gt; aaa 이름으로 프로젝트 생성
nest 명령어로 설치 안될 경우 npx nest new aaa로 설치

2. 키보드를 이용하여 선택지 중 yarn으로 이동해 엔터</code></pre>
<h3 id="--nest-프로젝트-생성-git-clone-사용-">- Nest 프로젝트 생성( git clone 사용 )</h3>
<pre><code class="language-javascript">1. cd 명령어로 설치할 폴더로 이동

2. 터미널에 명령어 입력
- git clone https://github.com/nestjs/typescript-starter.git

- yarn install 입력</code></pre>
<h3 id="--nestjs-git파일-관리">- NestJS .git파일 관리</h3>
<blockquote>
<p>NestJs 를 만들게 되면 typescript 파일 등 여러 파일들과 함께 <code>.git 파일</code>도 자동으로 만들어지게 됩니다.<br/>
하지만, 최상단에 우리만의 .git 파일이 숨긴 파일로 존재하고 있습니다.<br/>
따라서, <strong>git 파일이 2개 이상 존재</strong>하게 되므로 git add, commit 후 push 할 때 에러가 발생되므로 NestJs 를 만들 때 <strong>자동 생성된 git 파일을 삭제</strong>해 주어야 합니다.</p>
</blockquote>
<pre><code class="language-javascript">1. 터미널에 명령어로 .git파일 제거 
rm -rf .git

2. 리스트 조회로 .git파일 제거 확이인
ls -al</code></pre>
<h3 id="--prettier-저장시-자동포멧팅">- prettier 저장시 자동포멧팅</h3>
<pre><code class="language-javascript">1. 최상단 위치에 .vscode 폴더 생성
2. settings.json 파일 생성
3. 파일 내에 코드 작성 
{
    &quot;editor.formatOnSave&quot;: true,
    &quot;editor.defaultFormatter&quot;: &quot;esbenp.prettier-vscode&quot;
}
- &quot;editor.formatOnSave&quot;: true : 저장하면 프리티어가 바로 적용될 수 있게 설정
- &quot;editor.defaultFormatter&quot;: &quot;esbenp.prettier-vscode” :  prettier 포멧 적용 설정</code></pre>
<h3 id="--graphql-설치">- GraphQL 설치</h3>
<pre><code class="language-javascript">1. 터미널에 명령어 입력
 yarn add @nestjs/graphql @nestjs/apollo graphql apollo-server-express

2. app.module.ts 파일에 GraphQL 세팅
import { Module } from &#39;@nestjs/common&#39;;
import { GraphQLModule } from &#39;@nestjs/graphql&#39;;
import { AppController } from &#39;./app.controller&#39;;
import { AppService } from &#39;./app.service&#39;;

@Module({
  imports: [
    GraphQLModule.forRoot&lt;ApolloDriverConfig&gt;({
      driver: ApolloDriver,
    }),
  ],
  // controllers: [AppController],
  // providers: [AppService],
})
export class AppModule {}

3. app.controller.ts 파일, app.service.ts 파일 삭제</code></pre>
<h3 id="--graphql-폴더-구조-셋팅module-resolver-service-생성">- GraphQL 폴더 구조 셋팅(module, resolver, service 생성)</h3>
<pre><code class="language-javascript">1. module 파일 형식
import { Module } from &#39;@nestjs/common&#39;;
import { BoardResolver } from &#39;./board.resolver&#39;;
import { BoardService } from &#39;./board.service&#39;;

@Module({
  // imports: [],
  // controllers:[],
  providers: [
    BoardResolver, //
    BoardService,
  ],
})
export class BoardModule {}


2. resolver 파일 형식
import { Query, Resolver } from &#39;@nestjs/graphql&#39;;
import { BoardService } from &#39;./board.service&#39;;

@Resolver()
export class BoardResolver {
  // 라우팅 개념을 통해 Resolver에 Service 의존성 주입
  constructor(
    private readonly boardService: BoardService, //
  ) {}

  @Query(() =&gt; String) // API Docs를 만들기 위한 GraqhQL 타입 선언
  getHello() {
    return this.boardService.aaa();
  }
}


3. service 파일 형식
import { Injectable } from &#39;@nestjs/common&#39;;

@Injectable()
export class BoardService {
  aaa() {
    return &#39;Hello World!&#39;;
  }
}


4. app.module.ts 에 BoardModule, autoSchemaFile 추가
import { ApolloDriver, ApolloDriverConfig } from &#39;@nestjs/apollo&#39;;
import { Module } from &#39;@nestjs/common&#39;;
import { GraphQLModule } from &#39;@nestjs/graphql&#39;;
import { BoardModule } from &#39;./apis/boards/board.module&#39;;

@Module({
  imports: [
    BoardModule,
    GraphQLModule.forRoot&lt;ApolloDriverConfig&gt;({
      driver: ApolloDriver,
      autoSchemaFile: &#39;src/common/graphql/schema.gql&#39;, // SchemaFile 자동 생성 및 위치 지정(Code-First)
    }),
  ],
  // controllers: [AppController],
  // providers: [AppService],
})
export class AppModule {}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Autoscale]]></title>
            <link>https://velog.io/@woo_code/Autoscale</link>
            <guid>https://velog.io/@woo_code/Autoscale</guid>
            <pubDate>Fri, 16 Dec 2022 12:29:57 GMT</pubDate>
            <description><![CDATA[<h3 id="1️⃣-ec2와-elb">1️⃣ EC2와 ELB</h3>
<blockquote>
<p>*<em>EC2 : *</em>자동으로 인스턴스를 생성하고,
** ELB : **  EC2로 만들어진 인스턴스를 묶어서 서비스를 제공합니다.</p>
</blockquote>
<p>서비스는 접속자가 많을 때도 있고, 적을 때도 있으며, 어떤 서비스는 완만하게 성장하는 경우도 있고, 어떤 서비스는 특정 시간에 접속이 집중될수도 있습니다.</p>
<p>따라서 <strong>서비스의 흥행상황은 항상 유동적</strong>이라고 할 수 있습니다.  </p>
<p>또한 예측하지 못한 순간에 시스템이 폭주하는 경우도 있습니다.</p>
<p><strong>이런 상황에 대한 준비가 되어 있지 않다면 비즈니스적으로 이득을 챙기기 어려우며, 큰 손해도 입을 수 있습니다.</strong></p>
<p>하지만 평소에도 항상 충분한 시스템을 준비하여 대비하기에는 많은 비용이 듭니다. </p>
<p>이런 상황에서 사용할 수 있는 서비스가 <strong>EC2</strong>와 <strong>ELB</strong>입니다. </p>
<h3 id="2️⃣-autoscale">2️⃣ Autoscale</h3>
<blockquote>
<p>auto scaling 또는 auto-scaling이라고도 하며 자동 크기 조정이라고도 말합니다.</p>
</blockquote>
<p>Autoscale이라고 하면 일반적으로 활성 서버 수로 측정되는 서버 팜의 계산 리소스 양을 동적으로 조정하는 클라우드 컴퓨팅에서 사용되는 방법입니다.</p>
<p>클라우드 컴퓨팅의 대표적인 장점으로는 <strong>필요에 따라 서비스를 빠르게 확장하거나 축소할 수 있는 유연성</strong>이라고 할 수 있습니다.</p>
<p>즉, Auto Scaling은 <strong>클라우드의 유연성을 돋보이게 하는 핵심기술</strong>로 CPU, 메모리, 디스크, 네트워크 트래픽과 같은 시스템 자원들의 메트릭(Metric) 값을 모니터링하여 <strong>서버 사이즈를 자동으로 조절 하는 서비스를 말합니다.</strong></p>
<br/>

<h3 id="3️⃣-autoscale-동작-방식">3️⃣ Autoscale 동작 방식</h3>
<ol>
<li><p>트래픽 폭주</p>
</li>
<li><p>서비스에 참여하고 있던 서버들의 CPU 점유율 증가</p>
</li>
<li><p>CPU 점유율이 80%를 넘으면 미리 준비된 이미지(AMIs)를 이용해서 인스턴스를 생성 </p>
</li>
<li><p>ELB에 연결해서 트래픽을 새로 생성한 EC2 인스턴스에 분산 </p>
</li>
<li><p>트래픽이 줄어들면서 CPU 사용률이 20% 아래로 떨어지면 EC2 인스턴스가 순차적으로 제거</p>
</li>
<li><p>비용 절감</p>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[CI/CD]]></title>
            <link>https://velog.io/@woo_code/CICD</link>
            <guid>https://velog.io/@woo_code/CICD</guid>
            <pubDate>Fri, 16 Dec 2022 11:50:28 GMT</pubDate>
            <description><![CDATA[<h3 id="1️⃣-cicd">1️⃣ CI/CD</h3>
<blockquote>
<p><strong>CI:</strong> 지속적 통합(Continuous Integration)
<strong>CD:</strong> 지속적 배포(Continuous Deployment)</p>
</blockquote>
<h3 id="💡-ci란">💡 CI란?</h3>
<p>*<em>코드의 빌드/테스트 자동화 과정 과정입니다. *</em></p>
<p>개발자를 위한 자동화 프로세스인 지속적인 통합(Continuous Integration)을 의미하며, <strong>CI를 성공적으로 구현할 경우 애플리케이션에 대한 새로운 코드 변경 사항이 정기적으로 빌드 및 테스트되어 공유 리포지토리에 통합</strong>됩니다.</p>
<p>즉, <strong>커밋할 때마다 빌드와 일련의 자동 테스트가 이루어져 동작을 확인하고 변경으로 인해 문제가 생기는 부분이 없도록 보장</strong>해줍니다.</p>
<p>그러므로 <strong>여러 명의 개발자가 동시에 애플리케이션 개발과 관련된 코드 작업을 할 경우 서로 충돌할 수 있는 문제를 해결</strong>할 수 있습니다.</p>
<h3 id="💡-cd란">💡 CD란?</h3>
<p><strong>배포의 자동화 과정입니다.</strong></p>
<p>CD는 지속적 배포(Continuous Deployment)를 의미하며,** 파이프라인의 추가 단계에 대한 자동화를 말합니다. **</p>
<p>때로는 얼마나 많은 자동화가 이루어지고 있는지 통계를 낼 때에도 사용됩니다.</p>
<p><strong>코드의 변경이 파이프라인의 이전 단계를 모두 성공적으로 통과하면 수동 개입 없이 해당 변경 사항이 프로덕션에 자동으로 배포됩니다. 
**
지속적 배포를 채택하면 품질 저하 없이 **최대한 빨리 사용자에게 새로운 기능을 제공</strong>할 수 있습니다.</p>
<br/>

<h3 id="2️⃣-cicd-유무의-차이">2️⃣ CI/CD 유무의 차이</h3>
<h4 id="📍-cicd를-적용-전">📍 CI/CD를 적용 전</h4>
<p>=&gt; 개발자들이 코드를 수정합니다.<br/>
=&gt; 각자의 코드를 push합니다. <br/>
=&gt; 각자의 코드를 git에 올리고 통합(Intergration)합니다.<br/>
=&gt; 에러가 발생한다면 에러를 직접 찾아낸 후 디버깅하고 코드를 수정합니다.<br/>
=&gt; 장애를 없앨 때 까지 처음부터 과정을 반복합니다.</p>
<p>❗️많은 시간을 할애하여 에러가 해결되었으면 배포를 시작합니다. 하지만 배포과정 또한, 개발자가 직접 배포과정을 거치므로 많은 시간을 소요합니다.</p>
<h4 id="💡-cicd를-적용-후">💡 CI/CD를 적용 후</h4>
<p> =&gt; 개발자들이 개발하여 각자의 코드를 push합니다. <br/>
 =&gt; git push를 통해 Trigger되어 CI서버에서 알아서 Build, Test, Lint를 실행하고 결과를 전송합니다. <br/>
=&gt; 결과를 전송받고 에러가 난 부분이 있다면 에러부분을 수정하고 코드를 master 브랜치에 merge합니다. <br/>
=&gt; master 브랜치에 코드를 merge하고 Build, Test가 정상적으로 수행이 되었다면 CI서버에서 알아서 Deploy 과정을 수행합니다.</p>
<h3 id="3️⃣-cicd-종류">3️⃣ CI/CD 종류</h3>
<blockquote>
<ul>
<li>Jenkins</li>
</ul>
</blockquote>
<ul>
<li>CircleCI</li>
<li>TravisCI</li>
<li>Github Actions</li>
<li>etc </li>
</ul>
<p><code>&lt;출처&gt;</code> : <a href="https://www.redhat.com/ko/topics/devops/what-is-ci-cd">Red Hat</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[서버리스]]></title>
            <link>https://velog.io/@woo_code/%EC%84%9C%EB%B2%84%EB%A6%AC%EC%8A%A4</link>
            <guid>https://velog.io/@woo_code/%EC%84%9C%EB%B2%84%EB%A6%AC%EC%8A%A4</guid>
            <pubDate>Fri, 16 Dec 2022 11:31:50 GMT</pubDate>
            <description><![CDATA[<h3 id="1️⃣-서버리스-란">1️⃣ 서버리스 란?</h3>
<blockquote>
<p><strong>서버리스(serverless):</strong>
개발자가 서버를 관리할 필요 없이 애플리케이션을 빌드하고 실행할 수 있도록 하는 클라우드 네이티브 개발 모델입니다.</p>
</blockquote>
<p>서버리스 모델에도 서버가 존재하긴 하지만, 애플리케이션 개발에서와 달리 추상화되어 있습니다.</p>
<p>서버리스 애플리케이션은 배포되고 나면 필요에 따라 자동으로 scale-up과 scale-down을 진행합니다.
<img src="https://velog.velcdn.com/images/woo_code/post/609022bb-b1e7-4c5c-92ce-b46a41e99e2f/image.png" alt=""></p>
<p>정리하자면 서버리스란? </p>
<ul>
<li><p>서버가 필요 없다는 뜻이 아닌, 서버를 관리하거나 신경 쓸 필요가 없다는 뜻입니다.</p>
</li>
<li><p>나노 수준의 함수로 구성되어 있습니다.</p>
</li>
</ul>
<p><code>&lt;출처&gt;</code> : <a href="https://jaehoney.tistory.com/77">서버리스(Serverless)란 무엇인가?</a></p>
<br/>

<h3 id="2️⃣-서버리스-아키텍처의-구현-방식">2️⃣ 서버리스 아키텍처의 구현 방식</h3>
<blockquote>
<p><strong>서버리스는 BaaS 보다는 FaaS에 더 가깝습니다</strong>.
<strong>BaaS</strong> (Backend as a Service)
<strong>FaaS</strong> (Function as a Service)</p>
</blockquote>
<ul>
<li>BaaS의 종류 : Firebase, Kinvey, Parse ... </li>
<li>Faas의 종류 : AWS Lambda, Azure Functions, Google Cloud Functions ...</li>
</ul>
<h4 id="📍-baas-특징">📍 BaaS 특징</h4>
<ul>
<li><p>일반적으로 SPA, 안드로이드와 같은 클라이언트 중심으로 개발된 애플리케이션입니다. </p>
</li>
<li><p>BaaS가 제공하는 인증, DB, 사용자 관리 등과 같은 외부 서비스를 사용해서 대부분의 비즈니스 로직을 처리합니다.</p>
</li>
</ul>
<h4 id="📍-faas-특징">📍 FaaS 특징</h4>
<ul>
<li><p>무상태(Stateless) 함수가 서버 측 비즈니스 로직을 포함합니다. </p>
</li>
<li><p>Backend를 작은 함수로 쪼개서 사용자가 직접 관리하지 않는 서버로 올립니다. </p>
</li>
<li><p>함수들은 특정한 조건 또는 주기, 요청 등으로 trigger 되어서 서버가 알아서 실행되고 종료됩니다. </p>
</li>
</ul>
<br/>

<h3 id="3️⃣-서버리스의-장단점">3️⃣ 서버리스의 장단점</h3>
<h4 id="💡-장점">💡 장점</h4>
<ul>
<li><p>일정 주기, 조건 등에 함수를 호출하므로 리소스를 낭비하지 않게 되어서 비용이 저렴합니다.</p>
</li>
<li><p>인프라 구성, 운영, 보안 등에 신경쓰지 않고 비즈니스 로직에 집중할 수 있습니다.</p>
</li>
<li><p>auto-scaling이 적용됩니다.</p>
</li>
<li><p>패키징 및 배포가 간단합니다.</p>
</li>
<li><p>릴리즈 주기가 감소하여 생산성 또한 높아집니다.</p>
</li>
</ul>
<h4 id="❗️-단점">❗️ 단점</h4>
<ul>
<li><p>trigger에 의해 서버를 실행 및 종료를 반복하기 때문에 실시간 서비스에는 적합하지 않습니다.</p>
</li>
<li><p>클라우드 서비스 업체에 종속됩니다.</p>
</li>
<li><p>실행 시간에 한계가 있습니다.</p>
</li>
<li><p>Stateless 형태로 로컬 데이터를 사용할 수 없습니다.</p>
</li>
<li><p>위의 단점들 때문에 디버깅이나 코드 테스팅에 불편함이 따릅니다.</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Kubernetes]]></title>
            <link>https://velog.io/@woo_code/Kubernetes</link>
            <guid>https://velog.io/@woo_code/Kubernetes</guid>
            <pubDate>Fri, 16 Dec 2022 11:15:06 GMT</pubDate>
            <description><![CDATA[<h3 id="1️⃣-kubernetes쿠버네티스">1️⃣ Kubernetes(쿠버네티스)</h3>
<blockquote>
<p><strong>Kubernetes:</strong>
컨테이너화된 애플리케이션의 자동 디플로이, 스케일링 등을 제공하는 관리시스템으로, 오픈 소스 기반 시스템입니다. </p>
</blockquote>
<p>Kubernetes(쿠버네티스)는 컨테이너를 쉽고 빠르게 배포/확장하고 관리를 자동화해주는 오픈소스 플랫폼입니다.</p>
<p>1주일에 수십억 개의 컨테이너를 생성하는 구글이 내부 배포시스템으로 사용하던 borg를 기반으로 2014년 프로젝트를 시작했으며, 여러 커뮤니티의 아이디어와 좋은 사례를 모아 빠르게 발전하고 있습니다.</p>
<p>단순한 컨테이너 플랫폼이 아닌 마이크로서비스, 클라우드 플랫폼을 지향하고 컨테이너로 이루어진 것들을 손쉽게 담고 관리할 수 있는 그릇 역할을 합니다.</p>
<h3 id="2️⃣-kubernetes-특징">2️⃣ Kubernetes 특징</h3>
<ul>
<li><strong>구글과 대형 회사들의 개발 참여</strong>
쿠버네티스는 전 세계적 스케일의 경험과 기술이 고스란히 녹아들어 있습니다. <br/>
서비스메시(Istio, linkerd), CI(Tekton, Spinnaker), 컨테이너 서버리스(Knative), 머신러닝(kubeflow)등등 다양한 기능들이 모두 쿠버네티스의 환경에서 돌아갑니다.</li>
</ul>
<br/>

<ul>
<li><strong>다양한 배포 방식</strong>
<img src="https://velog.velcdn.com/images/woo_code/post/deb7b628-a510-4b9d-8cec-c92c38c1812d/image.png" alt="">
쿠버네티스는 Deployment, StatefulSets, DaemonSet, Job, CronJob등 다양한 배포 방식을 지원합니다.</li>
</ul>
<br/>

<ul>
<li><strong>클라우드 지원</strong>
<img src="https://velog.velcdn.com/images/woo_code/post/e0d7d565-23ac-4b88-a81b-6c9853dca11a/image.png" alt="">
쿠버네티스는 <strong>서버 부하에 따라 자동으로 서버를 늘리는 기능인 AutoScaling이 있으며, IP를 할당받아 LoadBalancer로 사용할 수 있습니다.</strong> <br/>
또한, <strong>Cloud Controller</strong>를 이용하여 클라우드 연동을 손쉽게 확장할 수 있습니다. AWS, 구글 클라우드, 마이크로소프트에서는 물론 수십 개의 클라우드 업체에서 모듈을 제공하여 <strong>관리자는 동일한 설정 파일을 서로 다른 클라우드에서 동일하게 사용할 수 있는 장점이 있습니다.</strong></li>
</ul>
<br/>

<ul>
<li>** CRD(Custom Resource Definitaion)**
CRD를 이용하여 다른 도구, 방식을 익힐 필요 없이 다양한 기능을 손쉽게 확장할 수 있습니다.<br/></li>
</ul>
<p>💡예시) 쿠버네티스는 기본적으로 SSL 인증서 관리 기능을 제공하지 않지만, cert-manager를 설치하고 Certificate 리소스를 이용하면 익숙한 쿠버네티스 명령어로 인증서를 관리할 수 있습니다. </p>
<p><code>&lt;출처&gt;</code> : <a href="https://subicura.com/2019/05/19/kubernetes-basic-1.html">쿠버네티스 시작하기 - Kubernetes란 무엇인가?</a></p>
<br/>

<h3 id="3️⃣-kubernetes-사용-이유">3️⃣ Kubernetes 사용 이유</h3>
<blockquote>
<p>쿠버네티스를 이용하여 <strong>컨테이너화된 애플리케이션 환경(Containerized Application)을 탄력적으로 실행할 수 있게 됩니다.</strong></p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/woo_code/post/7e4c885d-1414-4754-a8eb-8801c20434ae/image.png" alt=""></p>
<p>프로덕션 환경에서는 애플리케이션을 실행하는 컨테이너를 관리하고 가동 중지 시간이 없는지 확인해야 합니다. </p>
<p>즉, 컨테이너가 다운된다면 다른 컨테이너를 다시 시작하여 가동 중지 시간을 최소화하여야 합니다.</p>
<p>이러한 문제를 시스템에 의해 관리되도록 하는 것이 쿠버네티스의 사용 이유 입니다.
<code>&lt;출처&gt;</code> : <a href="https://kubernetes.io">https://kubernetes.io</a></p>
<br/>

<h3 id="4️⃣-kubernetes-기능">4️⃣ kubernetes 기능</h3>
<p><img src="https://velog.velcdn.com/images/woo_code/post/5584cae0-a713-4c6b-8efa-ad0d828bc616/image.png" alt=""></p>
<ul>
<li><p>*<em>서비스 디스커버리와 로드 밸런싱 *</em>
DNS 이름을 사용하거나 자체 IP 주소를 사용하여 컨테이너를 노출합니다.</p>
</li>
<li><p><strong>스토리지 오케스트레이션</strong>
로컬 저장소, 공용 클라우드 공급자 등과 같이 원하는 저장소 시스템을 자동으로 적용 해줍니다.</p>
</li>
<li><p><strong>자동화된 롤아웃과 롤백</strong>
원하는 상태를 서술하고 현재 상태를 원하는 상태로 설정한 속도에 따라 변경이 가능합니다.</p>
</li>
<li><p><strong>자동화된 빈 패킹</strong>
각 컨테이너가 필요로 하는 CPU와 메모리(RAM)를 제공합니다.</p>
</li>
<li><p><strong>자동화된 복구(self-healing)</strong> 
가동 실패한 컨테이너를 다시 시작하고, 컨테이너를 교체합니다.</p>
</li>
<li><p><strong>시크릿과 구성 관리</strong> 
Password, OAuth 토큰 및 SSH 키와 같은 중요한 정보를 저장하고 관리합니다.</p>
</li>
</ul>
<p><code>&lt;출처&gt;</code> : <a href="https://www.xenonstack.com/insights/kubernetes-deployment">kubernetes-deployment</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[SSL, HTTPS]]></title>
            <link>https://velog.io/@woo_code/SSL-HTTPS</link>
            <guid>https://velog.io/@woo_code/SSL-HTTPS</guid>
            <pubDate>Fri, 16 Dec 2022 10:44:48 GMT</pubDate>
            <description><![CDATA[<h2 id="ssl-https">SSL, HTTPS</h2>
<h3 id="1️⃣-ssl-tls-https-란">1️⃣ SSL, TLS, HTTPS 란?</h3>
<blockquote>
<p><strong>SSL</strong>(Secure Socket Layer)
<strong>TLS</strong>(Transport Layer Security)
<strong>HTTPS</strong>(Hypertext Transfer Protocol Over Secure Socket Layer)</p>
</blockquote>
<ul>
<li><p><strong>SSL :</strong> 들어오고 나가는 데이터들을 암호화하는 보안 기능을 갖고 있는 <strong><code>보안 인증서</code></strong>를 칭합니다.</p>
</li>
<li><p><strong>TLS :</strong>  SSL의 업그레이드 버전이며, SSL과 특별하게 구분하지 않고 일반적으로는 SSL이라고 칭합니다.</p>
</li>
<li><p><strong>HTTPS :</strong> HTTP에 SSL를 적용하여 데이터 전송 기능의 보안을 강화한 전송 기능입니다.</p>
</li>
</ul>
<br/>

<h3 id="2️⃣-http의-문제점과-https의-필요-이유">2️⃣ HTTP의 문제점과 HTTPS의 필요 이유</h3>
<p><code>HTTP</code>로 요청했을 때:
pcap 내 <strong>로그인한 유저의 정보(이메일, 패스워드)가 그대로 들어와서</strong> 데이터를 확인을 할 수 있기 때문에 해킹의 위험이 존재합니다.</p>
<p><code>HTTPS</code>로 요청했을 때:
데이터가 <strong>암호화가 되어 전달</strong>이 되기 때문에 pcap을 확인해 보아도 <strong>해쉬된 문자열만 확인되며, 해당 유저의 정보를 볼 수 없습니다.</strong></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Firewall(DMZ) / VPC]]></title>
            <link>https://velog.io/@woo_code/FirewallDMZ-VPC</link>
            <guid>https://velog.io/@woo_code/FirewallDMZ-VPC</guid>
            <pubDate>Fri, 16 Dec 2022 10:25:05 GMT</pubDate>
            <description><![CDATA[<h2 id="firewalldmz">Firewall(DMZ)</h2>
<blockquote>
<p>** Firewall(DMZ):**
미리 정의된 보안 규칙에 기반한 시스템으로, 들어오고 나가는 네트워크 트래픽을 모니터링하고 제어하는 네트워크 보안 시스템입니다.</p>
</blockquote>
<h3 id="1️⃣-firewalldmz란">1️⃣ Firewall(DMZ)란?</h3>
<p>침입차단 시스템으로 부르기도 하는데, <strong>방화벽은 일반적으로 신뢰할 수 있는 내부 네트워크, 신뢰할 수 없는 외부 네트워크 간의 장벽을 구성합니다</strong></p>
<p>즉, 외부 네트워크(악의적인 해킹 등...)로부터 내부 네트워크 혹은 내부 자산(서버, DB등)을 보호하는 보안 시스템을 말합니다.</p>
<h3 id="2️⃣-firewalldmz-기능">2️⃣ Firewall(DMZ) 기능</h3>
<ul>
<li><strong>접근 통제</strong>
외부에서 내부 네트워크로 접근하는 것을 패킷 필터링을 통해 통제하는 기능입니다.</li>
</ul>
<blockquote>
<p>💡 *<em>패킷 필터링이란? *</em>
내부 네트워크로 접근하는 패킷의 IP, Port 등 검열하여 내부와 외부 네트워크에 대한 접근을 통제합니다.</p>
</blockquote>
<ul>
<li><p><strong>인증</strong></p>
</li>
<li><p><em>메시지 인증*</em> : VPN과 같은 신뢰할 수 있는 통신선을 통해 전송되는 메시지의 신뢰성을 보장합니다.<br/></p>
</li>
<li><p><em>사용자 인증*</em> : 방화벽을 지나가는 트래픽에 대한 사용자가 누군지에 대해 증명하는 기능입니다.</p>
</li>
<li><p><strong>감사 및 로깅</strong>
정책 설정 및 변경, 관리자 접근, 네트워크 트래픽 허용 또는 차단과 관련한 사항 등 접속 정보를 로그로 남깁니다.</p>
</li>
<li><p><strong>프록시 기능</strong>
보안정책에 따라 실제 서비스를 수행하는 서버를 프록시라고 합니다.<br/>
프록시 기능은 클라이언트의 서비스 요청을 받아 전달하고, 결과를 수신하여 사용자에게 전달하는 기능입니다.</p>
</li>
<li><p><strong>NAT 기능</strong>
주소변환 기능으로, 외부 호스트의 IP나 목적지 호스트 IP를 전송 단계에서 변환하여 전달하는 기능으로, 네트워크에서 외부망과 내부망을 나눠주는 기능을 가능하게 합니다.</p>
</li>
</ul>
<h3 id="3️⃣-vpc-란">3️⃣ VPC 란?</h3>
<blockquote>
<p><strong>VPC(Virtual Private Cloud):</strong>
일종의 <strong>가상 네트워크 센터</strong>이며, IP 주소 범위 선택, 서브넷 생성, 라우팅 테이블 및 네트워크 게이트웨이 구성 등 가상 네트워킹 환경을 말합니다.</p>
</blockquote>
<p>VPC는 실제 네트워크와 동일한 방식으로 작동하며, 데이터 센터의 지역 가상 서브넷으로 구성 되어있습니다.</p>
<h4 id="💡-vpc-네트워크의-특징">💡 VPC 네트워크의 특징</h4>
<ul>
<li><p>연결된 라우터와 방화벽 규칙을 포함한 전역 리소스입니다.</p>
</li>
<li><p>방화벽 규칙은 인스턴스에서 송수신 되는 트래픽을 제어할 수 있습니다.</p>
</li>
<li><p>서브넷을 지역 리소스로, 각 서브넷은 CIDR을 이용해 IP 주소의 범위를 정의합니다.</p>
</li>
<li><p>내부 IP 주소가 있는 인스턴스는 Google API 및 서비스와 통신 가능하다.</p>
</li>
<li><p>네트워크 관리는 IAM을 사용해 관리가 가능하다.</p>
</li>
<li><p>VPC 공유를 이용하면 VPC 네트워크를 공용 Host project에 유지할 수 있습니다.</p>
</li>
<li><p>VPC 피어링으로 VPC 네트워크를 다른 프로젝트의 다른 VPC 네트워크에 연결 가능하다.</p>
</li>
</ul>
<p>📌 <strong>VPC 피어링(VPC Perring)이란?</strong>
서로 다른 VPC 간 통신이 가능하도록 연결하는 것을 의미합니다.</p>
<ul>
<li>각 프로젝트는 사전 정의된 기본 네트워크로 시작하며 원하면 커스텀을 통한 네트워크도 가능합니다.</li>
</ul>
<p><code>&lt;출처&gt;</code> : <a href="https://techblog-history-younghunjo1.tistory.com/21">[GCP]VPC(Virtual Private Cloud)</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[DNS / Load Balancer]]></title>
            <link>https://velog.io/@woo_code/DNS-Load-Balancer</link>
            <guid>https://velog.io/@woo_code/DNS-Load-Balancer</guid>
            <pubDate>Fri, 16 Dec 2022 10:00:20 GMT</pubDate>
            <description><![CDATA[<h2 id="dns-load-balancer">DNS Load Balancer</h2>
<blockquote>
<p><strong>DNS Load Balancer:</strong>
도메인에 대한 클라이언트 요청이 서버 시스템 그룹에 분산되도록 DNS(LDomain Name System)에서 도메인을 구성하는 방식입니다.</p>
</blockquote>
<h3 id="1️⃣-dns-란">1️⃣ DNS 란?</h3>
<p>DNS는 인터넷의 &quot;전화번호부&quot; 역할을 하는데, 전화번호부에 있는 개인 이름이나 회사 이름에 해당하는 <a href="http://www.abc.com%EA%B3%BC">www.abc.com과</a> 같은 도메인 이름을 전화번호에 해당하는 172.16.205.3과 같은 인터넷 프로토콜(IP) 주소에 저장합니다. </p>
<p>인터넷에서 데이터를 송수신하는 모든 장치에는 고유한 IP 주소가 있으며, 인터넷의 라우팅 소프트웨어와 하드웨어는 장치를 식별하고 위치를 파악하는 데 사용합니다.</p>
<p>클라이언트가 도메인 이름의 확인을 요청할 때 DNS는 단일 서버의 IP 주소를 반환합니다. </p>
<p>오늘날 많은 도메인은 서버 장애로부터 보호하거나 높은 트래픽 양을 처리하기 위해 여러 서버 시스템을 사용하며, 이 경우 DNS는 이름 확인 요청에 대한 응답으로 모든 서버의 IP 주소 목록을 반환합니다.</p>
<p><code>&lt;출처&gt;</code> : <a href="https://www.nginx.com/resources/glossary/dns-load-balancing/">NGINX</a></p>
<h3 id="2️⃣-load-balancer">2️⃣ Load Balancer</h3>
<blockquote>
<p><strong>Load Balancer:</strong>
 서버에 가해지는 부하를 분산시켜주는 장치로써, 클라이언트와 서버 사이에 위치하여 서버의 트래픽을 관리해줍니다.</p>
</blockquote>
<p>Load Balancer는 쉽게 말해 백앤드 컴퓨터들이 과부하되지 않도록 업무를 분담시켜 주는 도구이며, 분담하는 방식은 크게 두가지가 있습니다.</p>
<ul>
<li><p><strong>Least connection 알고리즘</strong>
가장 접속이 적은곳으로 몰아주는 방법</p>
</li>
<li><p><strong>Round Robin 알고리즘 (Google cloud)</strong>
컴퓨터 한대에 하나씩돌면서 업무를 배분하는 방법</p>
</li>
</ul>
<h4 id="💡-load-balancer-설정--auto-scaling">💡 Load Balancer 설정 : Auto-Scaling</h4>
<p><strong><code>Auto-Scaling</code> :</strong> 
<strong>scale-in :</strong> 사용량이 많아질 경우 알아서 컴퓨터를 생성하여 분담하는 기능입니다.</p>
<p>** scale-out:** 사용하지 않는 컴퓨터가 너무 많으면 알아서 덜어내기도 한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[# TDD]]></title>
            <link>https://velog.io/@woo_code/TDD</link>
            <guid>https://velog.io/@woo_code/TDD</guid>
            <pubDate>Fri, 16 Dec 2022 05:41:14 GMT</pubDate>
            <description><![CDATA[<h2 id="tdd">TDD</h2>
<blockquote>
<p>** TDD : **
Test Driven Development의 약자로 ‘테스트 주도 개발’이라고 합니다.</p>
</blockquote>
<h3 id="1️⃣-tdd란">1️⃣ TDD란?</h3>
<p><strong>반복 테스트를 이용한 소프트웨어 방법론으로 작은 단위의 테스트 케이스를 작성하고 이를 통과하는 코드를 추가하는 단계를 반복하여 구현합니다.</strong></p>
<p>짧은 개발 주기의 반복에 의존하는 개발 프로세스이며, 애자일 방법론 중 하나인 eXtream Programming(XP)의 ‘Test-First’ 개념에 기반을 둔 단순한 설계를 중요시합니다.</p>
<p>📌<code>eXtream Programming(XP)란?</code>
미래에 대한 예측을 최대한 하지 않고 지속적으로 프로토타입을 완성하는 애자일 기방법론 중 하나입니다.</p>
<p>이 기법을 개발했거나 ‘재발견’한 것으로 인정되는 Kent Beck은 2003년 TDD가 단순한 설계를 장려하고 자신감을 불어넣어 준다고 말합니다.</p>
<br/>

<h3 id="2️⃣-tdd-개발-과정">2️⃣ TDD 개발 과정</h3>
<p><img src="https://velog.velcdn.com/images/woo_code/post/31c46f6c-e063-4945-86f7-be5de881b44b/image.png" alt=""></p>
<h3 id="3️⃣-tdd-테스트-종류">3️⃣ TDD 테스트 종류</h3>
<p><strong>unit test(단위 테스트)</strong> : 함수처럼 가장 작은 단위를 테스트합니다.</p>
<p><strong>integration test(통합 테스트)</strong> : 유닛들을 모아서 함께 테스트합니다. 즉, 서버의 구성 요소들이 함께 잘 작동하는지를 테스트하기 위함입니다.</p>
<p><strong>e2e(end-to-end) test</strong> : 사용자의 입장에서 사용자의 상황을 처음부터 끝까지 가정하여 올바르게 작동하는지 테스트 합니다.</p>
<p>e2e test 프론트엔드 도구: Cypress, Selenium... 등등</p>
<br/>

<h3 id="4️⃣-jest">4️⃣ Jest</h3>
<blockquote>
<p>페이스북에서 개발한 프레임 워크이며, 자바스크립트에서 테스트 코드를 작성하는 것을 도와주는 프레임 워크 입니다.</p>
</blockquote>
<p>Nest.js에서는 <strong>기본적으로 JavaScript 테스트 프레임워크인 jest를 지원</strong>하고 있습니다. </p>
<p>Jest는** 테스트 코드의 모양이 직관적이고 문서화가 잘되어 있어 요즘 많이 활용되고 있는 Framework**입니다.</p>
<h3 id="📍-jest-특징">📍 Jest 특징</h3>
<ul>
<li><p><strong>여러가지 상황을 설정하고 그 상황에 맞는 로직과 결과가 나오는지 자동으로 테스트</strong>해줍니다.</p>
</li>
<li><p>Jest 이전에는 여러가지 테스트 라이브러리를 섞어 사용했지만, Jest를 사용하면 <strong>거의 모든 기능을 한 번에 지원</strong>하기 때문에 아주 효율적인 Test Framework라 할 수 있습니다.</p>
</li>
</ul>
<h3 id="📌-info">📌 Info</h3>
<p>Jest 이전에는 자바스크립트 코드를 테스트하라면 여러가지 테스팅 라이브러리를 조합해서 사용하곤 했습니다.</p>
<p>예를 들어, Mocha나 Jasmin을 Test Runner로 사용하고, Chai나 Expect와 같은 Test Mathcher를 사용했으며, 또한 Sinon과 Testdouble 같은 Test Mock 라이브러리도 필요했었습니다.</p>
<p>이 라이브러리들은 굉장히 유사하지만 살짝씩 다른 API를 가지고 있었기 때문에, 여러 프로젝트에 걸쳐서 일하는 자바스크립트 개발자들에게 많은 혼란을 주었습니다.</p>
<p>하지만 Jest는 라이브러리 하나만 설치하면, Test Runner와 Test Mathcher 그리고 Test Mock 프레임워크까지 제공해주기 때문에 현재 가장 많이 사용하는 Test Framework 라고 할 수 있습니다.</p>
<p><code>&lt;출처&gt;</code> : <a href="https://inpa.tistory.com/entry/JEST-%F0%9F%93%9A-jest-%EB%AC%B8%EB%B2%95-%EC%A0%95%EB%A6%AC">[JEST] 📚 JEST 소개 &amp; 기본 사용법 정리</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[로그아웃 프로세스의 이해]]></title>
            <link>https://velog.io/@woo_code/%EB%A1%9C%EA%B7%B8%EC%95%84%EC%9B%83-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4%EC%9D%98-%EC%9D%B4%ED%95%B4</link>
            <guid>https://velog.io/@woo_code/%EB%A1%9C%EA%B7%B8%EC%95%84%EC%9B%83-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4%EC%9D%98-%EC%9D%B4%ED%95%B4</guid>
            <pubDate>Fri, 16 Dec 2022 05:30:21 GMT</pubDate>
            <description><![CDATA[<h2 id="jwt--redis를-사용한-로그아웃-로직">JWT + Redis를 사용한 로그아웃 로직</h2>
<p>클라이언트로 부터 accessToken , refresh Token을 둘 다 받습니다.</p>
<p>=&gt; 로그아웃 API가 호출되면 JWT를 Redis에 저장됩니다.</p>
<p>=&gt; Redis에 넣을 때 expiration time 을 JWT의 exiration time 과 current time 을 계산해서 저장됩니다.</p>
<p>=&gt; 만료 시간이 지난 토큰이면 Redis에서 자동 삭제됩니다.</p>
<p>=&gt; 클라이언트가 기존 토큰으로 요청시 JwtFilter에 있는 validate 과정에서 redis로 해당 accessToken 있는지 확인합니다.</p>
<p>=&gt; Redis에 값이 있으면 요청을 거부, 없으면 요청을 승인합니다.</p>
<pre><code class="language-javascript">1. auth.resolver.ts 에 logout API 생성

  @UseGuards(GqlAuthRefreshGuard)
  @Mutation(() =&gt; String)
  async logout(
    @Context() context: IContext, //
  ) {
    return this.authService.logout({ req: context.req, res: context.res });
  }

2. auth.service.ts에 Token을 검증 해줄 jwt.verify 로직과 logout API 로직 생성

verify({ accessToken, refreshToken }) {
    try {
      const decodedAccessToken = jwt.verify(
        accessToken,
        process.env.JWT_ACCESS_KEY,
      );
      const decodedRefreshToken = jwt.verify(
        refreshToken,
        process.env.JWT_REFRESH_KEY,
      );
      return { decodedAccessToken, decodedRefreshToken };
    } catch (error) {
      throw new UnauthorizedException(&#39;검증되지 않은 토큰입니다.&#39;);
    }
  }

  async logout({ req, res }) {
    const accessToken = req.headers.authorization.replace(&#39;Bearer &#39;, &#39;&#39;);
    const refreshToken = req.headers.cookie.replace(&#39;refreshToken=&#39;, &#39;&#39;);

    const { decodedAccessToken, decodedRefreshToken } = this.verify({
      accessToken,
      refreshToken,
    });

    const date = new Date().getTime();

    const AccessTokenTtl = Math.trunc(
      (decodedAccessToken[&#39;exp&#39;] * 1000 - date) / 1000,
    );

    const RefreshTokenTtl = Math.trunc(
      (decodedRefreshToken[&#39;exp&#39;] * 1000 - date) / 1000,
    );

    await this.cacheManager.set(`accessToken:${accessToken}`, accessToken, {
      ttl: AccessTokenTtl,
    });

    await this.cacheManager.set(`refreshToken:${refreshToken}`, refreshToken, {
      ttl: RefreshTokenTtl,
    });

    res.setHeader(&#39;Set-Cookie&#39;, `refreshToken=; path=/; Secure; httpOnly;`);

    return &#39;로그아웃 완료&#39;;
  }

3. jwt-access.strategy.ts 와 jwt-refresh.strategy.ts의 validate에 재검증 로직 생성

  async validate(req, payload) {
    const accessToken = req.headers.authorization.replace(&#39;Bearer &#39;, &#39;&#39;);
    const checkAccessToken = await this.cacheManager.get(
      `accessToken:${accessToken}`,
    );

    if (checkAccessToken)
      throw new UnauthorizedException(&#39;로그인이 필요한 서비스입니다.&#39;);

    // console.log(payload);
    return {
      email: payload.email,
      id: payload.sub,
    };
  }</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[ACID]]></title>
            <link>https://velog.io/@woo_code/ACID</link>
            <guid>https://velog.io/@woo_code/ACID</guid>
            <pubDate>Fri, 16 Dec 2022 05:00:46 GMT</pubDate>
            <description><![CDATA[<h2 id="acid">ACID</h2>
<blockquote>
<p><strong>A</strong> tomicity
<strong>C</strong> onsistency
<strong>I</strong> solation
<strong>D</strong> urability</p>
</blockquote>
<h3 id="1️⃣-acid란">1️⃣ ACID란?</h3>
<p>*<em>ACID(원자성, 일관성, 독립성, 지속성)는 트랜잭션이 안전하게 수행된다는 것을 보장하기 위한 성질을 가리키는 약어입니다. *</em></p>
<p>1970년대 말에 신뢰할 수 있는 트랜잭션 시스템의 이러한 특성들을 <code>짐 그레이</code>가 정의하였으며 자동으로 이들을 수행하는 기술을 개발해 냈으며,</p>
<p>1983년 <code>안드레아스 로이테르(Andreas Reuter)</code>와 <code>테오 해르데르(Theo Härder)</code>는 ACID라는 용어를 만들면서 이를 기술했습니다.</p>
<h3 id="2️⃣-트랜잭션-이란">2️⃣ 트랜잭션 이란?</h3>
<p><strong>데이터베이스에서 데이터에 대한 하나의 논리적 실행단계를 트랜잭션이라고 말합니다.</strong></p>
<p>💡 예시) 은행의 계좌이체 API
계좌이체 API안에서 송신자 계좌의 금액 감소와 수신자 계좌의 금액 증가 로직 두가지가 있을 때 이 과정을 하나의 실행단계로 묶는 것을 트랜잭션이라고 정의합니다.</p>
<h3 id="3️⃣-acid">3️⃣ ACID</h3>
<p><strong>Atomicity(원자성):</strong> 트랜잭션과 관련된 작업들이 부분적으로 실행되다가 중단되지 않는 것을 보장해야 합니다.</p>
<p><strong>Consistency(일관성):</strong> 트랜잭션이 실행을 성공적으로 완료하면 언제나 일관성 있는 데이터베이스 상태로 유지하는 것을 의미합니다.</p>
<p><strong>Isolation(독립성):</strong> 트랜잭션을 수행 시 다른 트랜잭션의 연산 작업이 끼어들지 못하도록 보장하는 것을 의미합니다. 즉 트랜잭션 밖에 있는 어떤 연산도 중간 단계의 데이터를 볼 수 없음을 의미합니다.</p>
<p><strong>Durability(지속성):</strong> 성공적으로 수행된 트랜잭션은 영원히 반영되어야 함을 의미합니다. 시스템 문제, DB 일관성 체크 등을 하더라도 유지되어야 하며, 전형적으로 모든 트랜잭션은 로그로 남고 시스템 장애 발생 전 상태로 되돌릴 수 있게 합니다.</p>
<p>트랜잭션은 로그에 모든 것이 저장된 후에만 commit 상태로 간주될 수 있습니다.</p>
<p><code>&lt;출처&gt;</code> : <a href="https://ko.wikipedia.org/wiki/ACID">위키백과</a></p>
]]></description>
        </item>
    </channel>
</rss>