node.js - 서버 / 포트 / nodemon / API 함수 추가 /swagger 본문
서버
서버는 백엔드 컴퓨터나 DB컴퓨터처럼 특정된 것이 아니라, 클라이언트로 '요청을 받는' 모든 것들을 의미한다.
반대로 클라이언트 또한 브라우저나 사용자로 특정된 것이 아닌, '요청하는' 모든 것들이라 볼 수 있다.
클라이언트와 서버 사이의 관계를 가볍게 요약하자면 다음과 같다.
괄호 안 숫자 == 포트번호 | 프론트엔드 (3000) | 백엔드 (4000) | DB (3306) |
브라우저 컴퓨터 / 프로그램 | HTML / CSS / JS 요청 및 응답 | ||
프론트엔드 컴퓨터 / 프로그램 | API 요청 및 응답 | ||
백엔드 컴퓨터 / 프로그램 | DB / 해당데이터 요청 및 응답 |
포트
이때, 각각의 컴퓨터/프로그램은 프론트엔드(3000), 백엔드(4000), DB(3306) 포트번호를 가지고 있으며,
이 번호는 무조건적으로 정해진 포트번호가 아니며 사용자가 변경하여 사용할 수 있다.
포트 번호는 0~65535(2**16-1) 사이의 번호를 가지며,
참고로 http의 기본 포트번호는 80, https의 포트번호는 433. (생략이 가능하다.)
nodemon
nodemon은 개방한 서버가 중간에 수정될 시 서버가 종료하지 않고 파일 저장만 해주면 자동으로 서버가 재실행되는 기능이다.
설치를 하게 되면 아래와 같이 package.json에 nodemon이 추가되며,
scripts 를 추가하면 'nodemon index.js 를 실행하는 명령어를 입력시킬 수 있다.
(이때, 내가 임의로 입력한 명령어인 'yarn gohome'을 터미널에 입력 시 서버가 개방된다.)
// package.json
"scripts": {
"gohome" : "nodemon index.js" // 스크립트, 명령어 추가
},
"dependencies": {
"express": "^4.18.2",
"nodemon": "^2.0.20", // nodemon 추가된 부분
// 중략 //
// 터미널
yarn gohome // 스크립트에 추가한 명렁어 입력 시, 서버 개방
API 만들기 (휴대폰 인증번호 토큰 전송 및 응답하기)
요약하자면, phone.js에 휴대폰 인증번호 토큰을 가져오기 위한 함수들을 모아둔 뒤, index.js로 export 한 모습이다.
이후 포스트맨에서 '/tokens/phone'주소로 post 요청 시 해당 번호로 랜덤한 인증번호가 발송되었음을 확인할 수 있다.
// index.js // API 사용을 위한 express 사용 중
import {checkPhone, getToken, sendTokenToSMS} from "./phone.js"
const app = express(); // express 관련
app.use(express.json()) // express 관련
// 중략 //
app.post("/tokens/phone", function(req, res) { // 이때의 /tokens/phone : '엔드포인트'라고 함
console.log(req)
let myPhone = req.body.qqq // '응답.바디'의, qqq로 저장된 데이터를 가져옴
// 이때, qqq는 전화번호를 저장하고 있음
const isValid = checkPhone(myPhone)
if(isValid == false) return
const myToken = getToken()
sendTokenToSMS(myPhone, myToken)
res.send("인증 완료!")
})
app.listen(3000); // 포트 3000에 서버 개방
// phone.js // 이전에 작성했던 코드 붙여넣은 것
export function checkPhone (myphone) {
if(myphone.length < 10 || myphone.length > 11){
console.log("에러 발생!!! 핸드폰 번호를 제대로 입력해주세요.") // Early-exit
return false
} else {
return true
}
}
export function getToken () {
const result = String(Math.floor(Math.random()*1000000)).padStart(6,"0")
console.log(result)
return result
}
export function sendTokenToSMS (myphone, result) {
console.log(myphone + "번호로 인증번호" + result + "를 전송합니다.")
}
import 추가하는 여러가지 방식
import default 나, 전부 import 했을 때 변수를 다루는 방법을 기억하면 좋을 것 같다.
import {checkPhone, getToken, sendTokenToSMS} from "./phone.js" // export 가져오기
import express from "express"; // export default 가져오기
import alalrlrlrlrlrl from "express"; // export default 이름바꿔 가져오기(유지보수 생각한 작명하기)
import alalrlrlrlrlrl, {checkPhone as zzzz, getToken} from "./phone.js" // default와 export 함께 쓰기
import * as ttt from "./phone.js" // export 한방에 다 가져오기
ttt.checkPhone // export 한방에 다 가져오기
ttt.getToken // export 한방에 다 가져오기
API & API 설명서 생성 (swagger)
1. API 생성
먼저 npmjs 사이트에서 두 프로그램을 다운받는다. (yarn add / 코드 병합)
- swagger-express : https://www.npmjs.com/package/swagger-ui-express
- swagger-jsdoc : https://www.npmjs.com/package/swagger-jsdoc
// index.js
// 위 두 가지를 병합한 뒤, 불필요한 것을 잘라낸 모습
import express from "express";
import swaggerUi from "swagger-ui-express";
import swaggerJsdoc from "swagger-jsdoc";
import {options} from './swagger/config.js' // 해당 파일은 기초 셋팅에 관한 부분이라 따로 보관
const app = express();
app.use("/api-docs", swaggerUi.serve, swaggerUi.setup(swaggerJsdoc(options)));
app.use(express.json());
// package.json 에 swagger-jsdoc & swagger-ui-express 가 추가된 모습
"scripts": {
"gohome" : "nodemon index.js"
},
"dependencies": {
"express": "^4.18.2",
"nodemon": "^2.0.20",
"swagger-jsdoc": "^6.2.7",
"swagger-ui-express": "^4.6.0"
}
}
이후 API 요청 & 응답을 받아오기 위한 함수를 작성한다.
app.get("/users", function (req, res) { // 엔드포인트 : users
const pi = [ // 배열 이름은 임의로 pi로 정함
{
email : "aaa@aaa.com",
name : "철수",
phone : "010-1234-5678",
personal : "220110-2222222",
prefer : "https://naver.com"
},
// 중략 //
}
]
res.send(pi);
})
밑 사진 : 포스트맨을 통해 응답을 받아온 모습 // 이때 '엔드포인트'에 대한 요청의 응답을 '라우팅'이라고 한다.
2. API 설명서 (swagger) 생성
swagger 를 편리하게 다루기 위한 swagger 폴더 생성 및 기초 설정을 넣어두기 위한 config.js 생성
// config.js
export const options = {
definition: {
openapi: "3.0.0",
info: {
title: "Hello World", // API 이름
version: "1.0.0",
},
},
apis: ["./swagger/*.swagger.js"], // files containing annotations as above
};
// 이때, apis 내 주소에 집중할 필요가 있는데,
// swagger 폴더 안, 뒷 이름이 swagger.js 로 끝나는 모든 파일에 대해 참조한다는 의미.
// '*' 는 '전체' 라는 의미를 갖는다. (import 에서도 어떤 파일 전체를 참조할 때 비슷한 방식으로 사용)
스웨거 파일 생성
// user.swagger.js
// get 관련 swagger
/**
* @swagger
* /users:
* get:
* summary: 회원 목록 조회
* tags: [Board]
* parameters:
* - in: query
* name: number
* type: int
* responses:
* 200:
* description: 성공
* content:
* application/json:
* schema:
* type: array
* items:
* properties:
* number:
// 중략 //
// post 관련 swagger
/**
* @swagger
* /유저:
* post:
* summary: 게시글 등록하기
* tags: [Board]
* responses:
* 200:
* description: 성공
*/
이때 스웨거 파일을 만들 때는 들여쓰기가 굉장히 중요하니 신경써줄 필요가 있다.
아래 사진은 로컬 포트로 swagger 를 확인한 모습이다.