모각코 8회차(5.17)

기먼지·2023년 5월 22일
0

인생작

목록 보기
8/9

Axios

Axios는 브라우저, Node.js를 위한 HTTP 비동기 통신 라이브러리

  • 운영 환경에 따라 브라우저의 XMLHttpRequest 객체 또는 Node.js의 HTTP API 사용
  • Promise(ES6) API 사용
  • Async/Await(ES7) API 사용
  • 요청과 응답 데이터의 변형
  • HTTP 요청 취소 및 요청과 응답을 JSON 형태로 자동 변경
yarn add axios

Axios 응답 제어

.then

비동기 통신이 성공했을 경우, .then()은 콜백을 인자로 받아 결괏값을 처리

.catch

.catch()를 통해 오류를 처리

error 객체에서는 오류에 대한 주요 정보를 확인할 수 있음

.catch에서 받아오는 error 객체를 통해 error.response.status 응답 상태 코드와 error.response.headers 응답 헤더 정보를 파악할 수 있음

axios.get('/hello')
		 .catch(function (error) {
				if (error.response) {
					console.log(error.response.status);
					console.log(error.response.headers);
				}
		  }

Axios HTTP 요청 메서드 종류

axios.get(url[, config])

서버에서 데이터를 가져올 때 사용하는 메서드

두 번째 파라미터 config 객체에는 헤더(header), 응답 초과시간(timeout), 인자값(params) 등의 요청 값을 같이 넘길 수 있음

axios.post(url[, data[, config]])

서버에 데이터를 새로 생성할 때 사용하는 메서드

두 번째 파라미터로 생성할 데이터를 넘김

axios.put(url[, data[, config]])

특정 데이터를 수정할 때 요청하는 메서드

put은 새로운 리소스를 생성하거나, 이미 존재하는 데이터를 대체할 때 사용

post와의 다른 점은 post는 여러 번 호출할 경우, 새로운 데이터가 지속적으로 추가

반면, put은 한 번 요청을 하거나 여러 번 지속적으로 요청해도 결과값이 동일

(예를 들어, 유저의 이름을 “Iron Man”으로 수정하기 위해 axios.put 요청을 보내게 되면, put 요청을 한 번 보내거나 여러 번 보내도 유저의 이름은 “Iron Man”으로 동일하게 수정)

axios.delete(url[, config])

특정 데이터나 값을 삭제할 때 요청하는 메서드

Callback

크게 2가지 의미가 있음

  1. 다른 함수의 인자로 이용되는 함수
  2. 이벤트에 의해 호출되는 함수

다른 함수의 인자로 이용되는 함수

인자로 문자열, 숫자열, 배열, 객체 뿐만 아니라 함수가 들어갈 수도 있음

function add (x, y, callback) {
	let result = x * y;
	callback(result);
}

function result (data) {
	console.log(data, "콜백함수 실행")
}

add(5, 10, result)

이 때, add 함수의 인자로 사용된 result 함수를 callback 함수라고 함

이벤트에 의해 호출되는 함수

이벤트에는 onClick, onChange 등이 있음

onClick, onChange는 HTML에서 미리 만들어 놓은 함수

<button onClick={handleClickFunction}></button>

button을 클릭하면 onClick 함수가 실행되고, onClick에서는 다시 handleClickFunction이 실행

함수의 인자로 handleClickFunction이 들어가기 때문에 handleClickFunctioncallback 함수라고 함

이런 상황에서 “handleClickFunction을 호출한다, 가 호출된다”라고도 함

이러한 callback 함수는 다시 2가지로 나눌 수 있음

  1. 동기적 함수
  2. 비동기적 함수

동기(synchronous)적 방식 : 현재 실행 중인 코드가 완료된 후 다음 코드를 실행

비동기(asynchronous)적 방식 : 현재 실행 중인 코드의 완료 여부와 무관하게 즉시 다음 코드로 넘어가서 실행

JavaScript는 Single-Thread/Non-Blocking 방식으로 코드를 실행

한 번에 하나의 코드만 실행할 수 있으나(Single-Thread), 코드를 실행하고 해당 결과를 기다리지 않고 다음 코드를 실행(Non-Blocking)

비동기적 Callback

비동기적 함수는 결과를 기다리지 않고 다음 코드를 실행

비동기적 callback 함수의 가장 좋은 예시는 setTimeout

setTimeout 함수는 시간 지연 함수. 한 줄씩 내려오며 실행되던 코드를 지정한 시간만큼 보류

function Test () {
	console.log("3초 기다리기")
}

setTimeout(Test, 3000);
console.log('이건 바로 실행);

/*
"이건 바로 실행"
"3초 기다리기"
*/

callback 지옥

비동기적 callback을 연속적으로 계속해서 사용하게 되는 경우, callback 지옥에 빠지게 됨

callback 지옥은 콜백 함수를 익명 함수로 전달하는 과정이 반복되어 코드의 들여쓰기 수준이 감당하기 힘들 정도로 깊어지는 현상

Promise

callback 지옥을 해결하기 위해 자바스크립트는 ES6의 Promise를 추가

axios는 기본적으로 Promise를 지원하는 라이브러리

이번에는 Promiseaxios를 이용해 GET 요청을 보내 data를 받아오는 코드 작성

const url = 'https://koreanjson.com/posts/1';

function getData() {
  return new Promise(function (resolve, reject) {
    axios.get(url).then(function (response) {
      if (response) {
        resolve(response.data);
      }
      reject(new Error('Request is failed'));
    });
  });
}

let result = [];
getData()
  .then(function (data) {
    for (let v of Object.values(data)) {
      result.push(v);
    }
    console.log(result);
  })
  .catch(function (err) {
    console.error(err);
  });

new 연산자와 함께 호출한 Promise의 인자로 넘겨주는 콜백 함수는 호출할 때 바로 실행되지만 그 내부에 resolve 또는 reject 함수를 호출하는 구문이 있을 경우 둘 중 하나가 실행되기 전까지는 then 또는 catch로 넘어가지 않음

보통 resolve는 성공했을 때의 반환값을, reject는 실패했을 경우를 나타냄

async/await

axios는 기본적으로 async/await를 지원하는 라이브러리

이번에는 async/awaitaxios를 이용해 GET 요청을 보내 data를 받아오는 코드 작성

async function getData(url){
  let data = (await axios.get(url)).data;
	return data;
  }

let url = 'https://koreanjson.com/posts/1';

async function dataArr(){
    let data = await getData(url);
    let result = [];
    for(let v of Object.values(data)){
        result.push(v);
    }
    console.log(result);
}

dataArr();

비동기 작업을 수행하고자 하는 함수 앞에 async를 표기하고, 함수 내부에서 실질적인 비동기 작업이 필요한 위치마다 await를 표기하는 것만으로 뒤에 내용을 Promise로 자동 전환하고 해당 내용이 resolve된 이후에 다음으로 진행

await 유무로 동기적 함수와 비동기적 함수를 구분할 수 있음

→ 비동기적 작업을 수행하기 위해 콜백 함수를 익명 함수로 전달하는 과정에서 생기는 콜백 지옥을 Promise, async/await 등을 사용해서 방지할 수 있음

Axios로 GET 요청 보내기(동기, 비동기 방식)

import axios from 'axios';

// 비동기 방식
function fetchPost() {
    const result = axios.get('https://koreanjson.com/posts/1');
    console.log(result);  // Promise { <pending> }
}

fetchPost();

// 동기 방식
async function fetchPost2() {
    const result = await axios.get('https://koreanjson.com/posts/1');
    // console.log(result)  // 실제 데이터
    console.log(result.data);  // 실제 데이터
}

fetchPost2();

fetchPost는 응답을 기다리지 않고 console.log()를 실행하기 때문에 다음 코드들이 실행되어 Promise 객체가 result에 담김

SMS 전송

Coolsms - Node.js SDK 확인

SDK(Software Development Kit)란 개발자가 앱을 커스텀할 수 있도록 제공해주는 일종의 도구 모음과 같은 개념

실제 제품을 제작하는 데 도움이 되는 추가 상품이라고 여겨지며, 포함되는 내용물은 제작사마다 차이가 존재

Node.js SDK를 살펴보면 아래와 같은 단문 문자 전송을 위한 예제를 확인할 수 있음

// send_sms.js

/**
* 단문 문자(SMS) 발송 예제
* 발신번호, 수신번호에 반드시 -, * 등 특수문자를 제거하여 기입하시기 바랍니다. 예) 01012345678
*/

const coolsms = require("coolsms-node-sdk").default;
const messageService = new coolsms("ENTER_YOUR_API_KEY", "ENTER_YOUR_API_SECRET");

// 단일 발송 예제
messageService.sendOne({
	to: "수신번호",
	from: "계정에서 등록한 발신번호 입력",
	text: "한글 45자, 영어 90자 이하 입력되면 자동으로 SMS타입의 메시지가 발송됩니다."
}).then(res => console.log(res));

아래의 명령어를 통해 모듈 설치

yarn add coolsms-node-sdk

import한 coolsms에서 SDK를 사용할 수 있도록 데이터를 가져오는 코드를 추가

import coolsms from 'coolsms-node-sdk';

export async function sendTokenToSMS(myphone, token) {
    const SMS_KEY = process.env.SMS_KEY;  // 본인의 Coolsms API key 입력
    const SMS_SECRET = process.env.SMS_SECRET;  // 본인의 Coolsms API Secret 입력
    const SMS_SENDER = process.env.SMS_SENDER;  // Coolsms에서 발신 번호로 등록해 주었던 휴대전화 번호 입력

    const mysms = coolsms.default;  // SDK 가져오기
		const messageService = new mysms(SMS_KEY, SMS_SECRET);
    const result = await messageService.sendOne({
        to: myphone,
        from: SMS_SENDER,
        text: `[코드캠프] 안녕하세요?! 요청하신 인증번호는 [${token}] 입니다.`,
    });
    console.log(result);
}

환경변수 분리

Github와 같은 공유 저장소에 본인만의 key 값이 올라가게 되면 도용 위험이 발생하기 때문에 환경변수로 분리하여 관리해 주어야 함 → .env 파일 작성

// .env

// 예시
SMS_KEY = Coolsms_API_KEY
SMS_SECRET = Coolsms_API_Secret
SMS_SENDER = 01012345678

환경변수 파일을 읽어오기 위해 라이브러리 설치

yarn add dotenv

dotenv를 import 해오는 코드 추가

// index.js

import 'dotenv/config'

이제 process.env라는 명령어를 사용하여 변수를 선언하게 되면 해당 명령어가 .env 파일의 키값을 찾아 읽어줌

EMAIL 전송

Nodemailer를 사용

yarn add nodemailer

Nodemailer 또한 coolsms와 마찬가지로 메일 전송을 위한 초기 세팅이 필요

authuser에는 e-mail 사전 설정 과정에서 게정 보안 설정을 마친 email, pass에는 2단계 인증 과정을 거쳐 생성한 앱 비밀번호를 입력

발신자 정보에 대한 설정이 완료된 데이터를 변수 transporter에 담아줌

// email.js

import nodemailer from 'nodemailer';

// ...

export async function sendWelcomeTemplateToEmail(myemail, mytemplate) {
    const transporter = nodemailer.createTransport({
        service: "gmail",
        auth: {
            user: "youremail@gmail.com",
            pass: "abcdefghijklmnop"
        }
    })

    const result = await transporter.sendMail({
        from: "youremail@gmail.com",
        to: myemail,
        subject: "[코드캠프] 가입을 축하합니다!!!",
        html: mytemplate
    })
    console.log(result);

    // console.log(`${myemail}로 가입환영템플릿 ${mytemplate}를 전송합니다.`)
}

위와 같이 transporter에 붙여서 sendMail 메서드를 사용하면 이메일 전송이 가능

  • from → 보낸 사람 이메일
  • to → 받는 사람 이메일
  • subject → 이메일 제목
  • html → 이메일을 통해 보여질 html 템플릿

await를 사용해 메일 전송이 완료될 때까지 기다린 후, 그 결과를 변수 result에 담아 console.log()로 확인

환경변수 분리

// .env

// 예시
EMAIL_USER=youremail@gmail.com
EMAIL_PASS=abcdefghijklmnop
EMAIL_SENDER=youremail@gmail.com
// ...

import 'dotenv/config';

// ...

export async function sendWelcomeTemplateToEmail(myemail, mytemplate) {
    const EMAIL_USER = process.env.EMAIL_USER;
    const EMAIL_PASS = process.env.EMAIL_PASS;
    const EMAIL_SENDER = process.env.EMAIL_SENDER;

    const transporter = nodemailer.createTransport({
        service: "gmail",
        auth: {
            user: EMAIL_USER,
            pass: EMAIL_PASS
        }
    })

    const result = await transporter.sendMail({
        from: EMAIL_SENDER,
        to: myemail,
        subject: "[코드캠프] 가입을 축하합니다!!!",
        html: mytemplate
    })
    console.log(result);

    // console.log(`${myemail}로 가입환영템플릿 ${mytemplate}를 전송합니다.`)
}
profile
열심히 굴러가기 !

0개의 댓글