project-root/
│
├── app.js # 메인 서버 파일 (애플리케이션 진입점)
├── package.json # 프로젝트 메타데이터 및 의존성 관리
├── config/ # 환경 설정 및 데이터베이스 설정
│ ├── config.js # 환경변수 및 설정
│ └── db.js # 데이터베이스 연결 설정
│
├── controllers/ # 요청 처리 로직
│ ├── userController.js
│ └── productController.js
│
├── models/ # 데이터베이스 모델 정의
│ ├── userModel.js
│ └── productModel.js
│
├── routes/ # 라우팅 처리
│ ├── userRoutes.js
│ └── productRoutes.js
│
├── services/ # 비즈니스 로직 (Controller와 Model 사이 로직)
│ ├── userService.js
│ └── productService.js
│
├── middlewares/ # 미들웨어 함수 (인증, 로깅 등)
│ ├── authMiddleware.js
│ └── errorHandler.js
│
├── views/ # 템플릿 파일 (EJS, Pug 등)
│ └── index.ejs
│
├── public/ # 정적 파일 (CSS, JavaScript, 이미지 등)
│ ├── css/
│ ├── js/
│ └── images/
│
├── utils/ # 공통 유틸리티 함수
│ └── helper.js
│
└── tests/ # 테스트 코드 (Jest, Mocha 등)
├── user.test.js
└── product.test.js
기본 파일 및 폴더 구조
각 폴더 및 파일 설명
app.js 또는 server.js
기능: 애플리케이션의 진입점.
내용: 서버 설정, 미들웨어 등록, 라우트 연결.
package.json
기능: 프로젝트의 의존성 및 스크립트 관리.
내용: 설치된 패키지 목록과 실행 스크립트 정의.
config/
기능: 환경 설정 및 데이터베이스 연결 정보.
파일 예시: config.js(환경 변수), db.js(DB 설정).
controllers/
기능: HTTP 요청을 처리하고, 비즈니스 로직 호출.
내용: 요청을 받아 서비스를 호출하고 응답 반환.
models/
기능: 데이터베이스 스키마 및 모델 정의.
내용: ORM(Mongoose, Sequelize 등)으로 데이터 구조 정의.
routes/
기능: URL 경로와 컨트롤러 연결.
내용: RESTful API 경로 정의.
services/
기능: 비즈니스 로직 구현 (Controller와 Model 사이 로직).
내용: 데이터 처리, 복잡한 연산 수행.
services 폴더는 Node.js 프로젝트에서 비즈니스 로직이나 외부 서비스와의 상호작용을 처리하는 코드를 포함하는 데 사용됩니다. 이를 통해 컨트롤러나 라우터에서 복잡한 로직을 분리하고, 재사용성과 유지보수성을 높일 수 있습니다.
git add 취소하기(파일 상태를 Unstage로 변경하기) 아래와 같이 실수로 git add * 명령을 사용하여 모든 파일을 Staging Area에 넣은 경우, Staging Area(git add 명령 수행한 후의 상태)에 넣은 파일을 빼고 싶을 때가 있다. // 모든 파일이 Staged 상태로 바뀐다. $ git add * // 파일들의 상태를 확인한다. $ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) renamed: README.md -> README modified: CONTRIBUTING.md 이때, git reset HEAD [file] 명령어를 통해 git add를 취소할 수 있다.
뒤에 파일명이 없으면 add한 파일 전체를 취소한다. CONTRIBUTING.md 파일을 Unstaged 상태로 변경해보자. // CONTRIBUTING.md 파일을 Unstage로 변경한다. $ git reset HEAD CONTRIBUTING.md Unstaged changes after reset: M CONTRIBUTING.md // 파일들의 상태를 확인한다. $ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) renamed: README.md -> README Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: CONTRIBUTING.md https://gmlwjd9405.github.io/2018/05/25/git-add-cancle.html
위에서 소개해 드린 화살표 함수들은=>왼쪽에 있는 인수를 이용해=>오른쪽에 있는 표현식을 평가하는 함수들이었습니다.
그런데 평가해야 할 표현식이나 구문이 여러 개인 함수가 있을 수도 있습니다. 이 경우 역시 화살표 함수 문법을 사용해 함수를 만들 수 있습니다. 다만, 이때는 중괄호 안에 평가해야 할 코드를 넣어주어야 합니다. 그리고return지시자를 사용해 명시적으로 결괏값을 반환해 주어야 합니다.
아래와 같이 말이죠.
let sum = (a, b) => { // 중괄호는 본문 여러 줄로 구성되어 있음을 알려줍니다.
let result = a + b;
return result; // 중괄호를 사용했다면, return 지시자로 결괏값을 반환해주어야 합니다.
};
alert( sum(1, 2) ); // 3
아직 끝나지 않았습니다.
지금까진 간결함이라는 특징을 중심으로 화살표 함수에 대해 알아보았습니다. 하지만 이게 다가 아닙니다!
화살표 함수는 여기서 소개한 기능 이외에도 다른 흥미로운 기능을 지원합니다.
자세한 내용을 배우려면 자바스크립트의 다른 내용들을 더 알아야 합니다. 화살표 함수의 깊은 내용을 알기위해 필요한 내용을 배운 후에화살표 함수 다시 살펴보기에서 그 내용들을 다루도록 하겠습니다.
지금까진 본문이 한 줄인 화살표 함수, 화살표 함수가 콜백으로 쓰인 경우에 대해서 알아보았습니다.
Error: Error: NJS-116: password verifier type 0x939 is not supported by node-oracledb in Thin mode
at Object.throwErr (D:\dev\nodejs\node_modules\oracledb\lib\errors.js:693:10)
at AuthMessage.encode (D:\dev\nodejs\node_modules\oracledb\lib\thin\protocol\messages\auth.js:210:20)
at Protocol._encodeMessage (D:\dev\nodejs\node_modules\oracledb\lib\thin\protocol\protocol.js:109:20)
at Protocol._processMessage (D:\dev\nodejs\node_modules\oracledb\lib\thin\protocol\protocol.js:163:18)
at ThinConnectionImpl.connect (D:\dev\nodejs\node_modules\oracledb\lib\thin\connection.js:843:30)
at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
at async ThinPoolImpl.bgThreadFunc (D:\dev\nodejs\node_modules\oracledb\lib\thin\pool.js:455:11) {
code: 'NJS-116'
그래서 Thick 모드로 연결을 시도 하던중 기존 오라클 클라이언트 경로를 환경 변수 Path에 추가 해 주고 다음과 같이 경로를 잡아 주었는데,,
Error initializing Oracle client: Error: DPI-1047: Cannot locate a 64-bit Oracle Client library: "The specified module could not be found". See https://node-oracledb.readthedocs.io/en/latest/user_guide/installation.html for help
Node-oracledb installation instructions: https://node-oracledb.readthedocs.io/en/latest/user_guide/installation.html
You must have Windows 64-bit Oracle Client libraries in your PATH environment variable.
If you do not have Oracle Database on this computer, then install the Instant Client Basic or Basic Light package from
https://www.oracle.com/database/technologies/instant-client/winx64-64-downloads.html
A Microsoft Visual Studio Redistributable suitable for your Oracle client library version must be available.
at Object.initOracleClient (D:\dev\nodejs\node_modules\oracledb\lib\oracledb.js:783:20)
at Object.<anonymous> (D:\dev\nodejs\server.js:9:10)
at Module._compile (node:internal/modules/cjs/loader:1546:14)
at Object..js (node:internal/modules/cjs/loader:1689:10)
at Module.load (node:internal/modules/cjs/loader:1318:32)
at TracingChannel.traceSync (node:diagnostics_channel:315:14)
at wrapModuleLoad (node:internal/modules/cjs/loader:218:24)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:170:5)
at node:internal/main/run_main_module:36:49 {
code: 'DPI-1047'
}
Oracle connection pool created
Server is running on http://localhost:3000
결국 클라이언트 전체 디렉터리를 프로젝트 폴더 아래에 복사하고 다음과 같이 경로를 잡아 주니 해결..!
매일 하는 업무인 DB 점검 업무에 대해 화면으로 보면 좋겠다. 생각하여, 요즘 관심있는 nodejs를 이용해 개발을 해보기로한다. 먼저 위의 블로그를 참조해 환경 구성을 해주었다.
Express
Express는 Node.js 기반의 웹 응용 프레임워크로, 웹 응용 프로그램 및 RESTful API를 손쉽게 구축할 수 있게 해주는 도구입니다. 간결하면서도 강력한 기능을 제공하여 서버 사이드 로직을 쉽게 작성할 수 있도록 도와줍니다.
CORS(Cross-Origin Resource Sharing)
CORS는 웹 브라우저에서 실행 중인 JavaScript가 다른 출처의 리소스에 접근하는 것을 허용하는 메커니즘을 제공합니다. 서로 다른 도메인 간의 HTTP 요청이 보안 정책에 의해 차단되는 것을 우회할 수 있게 해주는 중요한 보안 기능 중 하나입니다. Express에서는 cors 미들웨어를 사용하여 CORS 문제를 처리합니다.
Body-Parser
Body-Parser는 Express에서 HTTP 요청의 본문을 쉽게 파싱 할 수 있도록 도와주는 미들웨어입니다. 클라이언트에서 서버로 전송되는 데이터를 해석하여 서버에서 사용할 수 있도록 만들어줍니다. JSON, URL-encoded 및 기타 형식의 데이터를 파싱할 수 있습니다.
oracledb
위 블로그와 달리 현재 내 운영DB는 Oracle 이므로 Oracle 모듈을 대신 설치 해주기로 한다.
요약
Express는 Node.js를 기반으로 한 웹 응용 프레임워크로, 빠르고 간편한 웹 애플리케이션 및 API를 만들 수 있도록 지원합니다.
CORS는 다른 출처의 리소스에 대한 웹 브라우저에서의 접근을 허용하는 메커니즘으로, Express에서는 cors 미들웨어를 통해 처리합니다.
Body-Parser는 Express에서 HTTP 요청의 본문을 쉽게 파싱 하여 서버에서 사용할 수 있도록 도와줍니다.
mysql2는 Node.js에서 MySQL 데이터베이스와의 상호 작용을 위한 드라이버로, 비동기 쿼리와 프라미스를 지원하여 효율적인 코드 작성을 가능케 합니다.
필요한 라이브러리 설치
npm install express cors body-parser
PS E:\nodejs> npm install express cors body-parser
added 2 packages, and audited 68 packages in 6s
13 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
PS E:\nodejs>
오라클 모듈 설치
npm install oracledb --save
PS E:\nodejs> npm install oracledb --save
added 1 package, and audited 69 packages in 6s
13 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
Server.js 생성
// server.js
// 필요한 모듈을 가져옵니다.
const express = require('express');
const oracle = require('oracledb');
const cors = require('cors');
const bodyParser = require('body-parser');
// Express 애플리케이션을 생성합니다.
const app = express();
// 서버를 위한 포트를 설정합니다.
const port = 3000;
// 모든 라우트에 대해 CORS를 활성화하여 교차 출처 문제를 방지합니다.
app.use(cors());
// 서버를 특정 포트에서 실행합니다.
app.listen(port, () => {
console.log(`게시판 앱이 포트 ${port}에서 실행 중입니다.`);
});
Database 연결 설정
1. config 폴더를 생성 후 database 정보를 입력할 database.js 파일 생성
// 오라클 DB 설정 파일
module.exports = { user :process.env.NODE_ORACLEDB_USER || "suzi",
password :process.env.NODE_ORACLEDB_PASSWORD || "a123",
connectString :process.env.NODE_ORACLEDB_CONNECTIONSTRING || "localhost:1521/xe",
externalAuth :process.env.NODE_ORACLEDB_EXTERNALAUTH ? true : false
};
2. 외부 파일에서 데이터베이스 구성을 가져올 수 있게 server.js에 DB 정보 추가
// server.js
// ... 코드 생략...
// 외부 파일에서 데이터베이스 구성을 가져옵니다.
const dbConfig = require('./config/database.js');
// 제공된 구성을 사용하여 ORACLE 연결 풀을 만듭니다.
const connection = oracle.createPool(dbConfig);
JSON 데이터 처리를 위한 JSON 파서 추가
// server.js
// ... 코드 생략
// 들어오는 JSON 데이터를 처리하기 위한 JSON 파서를 설정합니다.
const jsonParser = bodyParser.json();
이제 html 파일 작성을 위한 public 폴더 생성
public 폴더에 메인 페이지를 만들기 위해 index.html 파일을 생성해 준다.
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<!-- 페이지의 메타 정보를 설정합니다. -->
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- 페이지의 스타일을 지정하는 CSS 코드입니다. -->
<style>
body {
font-family: 'Arial', sans-serif;
margin: 0;
padding: 0;
background-color: #f8f9fa;
}
h1 {
background-color: #343a40;
color: #ffffff;
padding: 20px;
margin: 0;
}
nav ul {
list-style: none;
padding: 0;
margin: 0;
background-color: #343a40;
overflow: hidden;
}
nav ul li {
float: left;
display: inline;
padding: 10px;
}
nav ul li a {
text-decoration: none;
color: #ffffff;
font-weight: bold;
display: inline-block;
padding: 10px 20px;
background-color: #343a40;
transition: background-color 0.3s ease;
}
nav ul li a:hover {
background-color: #495057;
}
#articles-list {
list-style: none;
padding: 0;
margin: 20px;
}
#articles-list li {
background-color: #ffffff;
border: 1px solid #ced4da;
padding: 15px;
margin-bottom: 10px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
#articles-list li a {
text-decoration: none;
color: #343a40;
font-weight: bold;
}
#articles-list li a:hover {
color: #007bff;
}
</style>
</head>
<body>
<!-- 페이지의 제목을 설정합니다. -->
<title>게시글 목록</title>
<!-- 페이지 상단에 표시되는 제목입니다. -->
<h1>게시글 목록</h1>
<!-- 네비게이션 링크 -->
<nav>
<ul>
<!-- 게시글 작성 페이지로 이동하는 링크 -->
<li><a href="create.html">게시글 작성</a></li>
</ul>
</nav>
<!-- 게시글 목록을 표시하는 부분입니다. -->
<ul id="articles-list"></ul>
</body>
</html>
작성 후 server.js에서 메인페이지를 지정해 준다.
// server.js
// 메인 HTML 파일을 제공하는 라우트입니다.
app.get('/', (req, res) => {
res.sendFile(__dirname + '/public/index.html')});
npm : 이 시스템에서 스크립트를 실행할 수 없으므로 C:\Program Files\nodejs\npm.ps1 파일을 로드할 수 없습니다. 자세한 내용은 about_Execution_Policies(https://go.microsoft.com/
fwlink/?LinkID=135170)를 참조하십시오.
위치 줄:1 문자:1
+ npm init
+ ~~~
+ CategoryInfo : 보안 오류: (:) [], PSSecurityException
+ FullyQualifiedErrorId : UnauthorizedAccess
아래와 같이 실행 정책 변경
PS C:\Dev\nodejs> Set-ExecutionPolicy RemoteSigned
PS C:\Dev\nodejs> Get-ExecutionPolicy
RemoteSigned
PS C:\Dev\nodejs> npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.
See `npm help init` for definitive documentation on these fields
and exactly what they do.
Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.
Press ^C at any time to quit.
package name: (nodejs)