hy30nq's blog
섹션 19: 더 많은 익스프레스: 템플릿을 사용한 정적 & 동적 콘텐츠(EJS) [49일차] 본문
섹션 19: 더 많은 익스프레스: 템플릿을 사용한 정적 & 동적 콘텐츠(EJS) [49일차]
hy30nq 2024. 2. 2. 10:45JSON이란 무엇인가?
JSON(JavaScript Object Notation)은 경량의 데이터 교환 포맷입니다. 사람이 읽고 쓰기 쉽고, 기계가 파싱하고 생성하기에 용이합니다. JSON은 두 가지 구조를 기반으로 합니다: 이름/값 쌍의 집합인 객체({ })와 값의 순서화된 리스트인 배열([ ]). 이는 현대 프로그래밍 언어의 대부분에서 쉽게 식별할 수 있는 데이터 구조입니다.
JSON의 특징과 장점
- 가독성: JSON은 텍스트 기반 포맷으로, 사람이 읽기 쉽습니다.
- 경량성: 데이터를 교환할 때 사용하는 대역폭을 최소화합니다.
- 언어 독립성: 다양한 프로그래밍 언어에서 쉽게 사용할 수 있습니다.
- 데이터 교환의 효율성: 웹 애플리케이션과 서버 간 데이터 전송에 최적화되어 있습니다.
JSON 사용 사례
- 웹 개발: 웹 페이지와 서버 간 비동기 데이터 교환(AJAX)에 널리 사용됩니다.
- API와 웹 서비스: 다양한 시스템 간 통합에 JSON 형식을 이용한 RESTful API가 많이 사용됩니다.
- 데이터 저장과 구성: 설정 파일이나 간단한 데이터 저장에 JSON 형식이 이용됩니다.
JSON의 구조
JSON은 두 가지 주요 구조를 가집니다:
- 객체: 중괄호({ })로 둘러싸인 키와 값의 쌍으로 구성됩니다. 각 키는 문자열이며, 값은 다양한 타입(문자열, 숫자, 배열, 또 다른 객체 등)이 될 수 있습니다.
- 배열: 대괄호([ ])로 둘러싸인 값의 순서화된 리스트입니다. 배열 내의 값은 어떤 타입이든 될 수 있습니다.
JSON 활용 예제
JSON의 간결하고 이해하기 쉬운 구조는 다양한 데이터 교환 요구를 쉽게 충족시킵니다. 예를 들어, 웹 애플리케이션에서 사용자 정보를 서버로 전송할 때 JSON 객체를 사용할 수 있습니다.
{
"이름": "홍길동",
"나이": 25,
"이메일": "hong@gildong.com",
"취미": ["독서", "여행"]
}
이 예제는 사용자의 이름, 나이, 이메일 주소, 취미를 포함하는 JSON 객체를 보여줍니다. 이처럼 JSON은 데이터를 명확하고 구조화된 방식으로 표현할 수 있게 해줍니다, 이는 개발자가 데이터를 더 쉽게 처리하고 활용할 수 있게 만듭니다.
JSON은 그 유연성과 간편함 덕분에 현대 웹 개발에서 필수적인 기술로 자리 잡았습니다. 데이터를 쉽고 효율적으로 교환하고자 하는 모든 개발자와 프로젝트에 권장됩니다.
JavaScript에서의 Path, FS, Express
JavaScript는 웹 페이지 개발뿐만 아니라 서버 측 애플리케이션 개발에도 널리 사용됩니다. Node.js 환경에서 JavaScript는 파일 시스템을 다루고, 웹 서버를 구축하는 데 필수적인 여러 모듈을 제공합니다. 여기서는 Node.js의 핵심 모듈인 Path와 FS, 그리고 웹 애플리케이션 프레임워크인 Express에 대해 소개합니다.
1. Path 모듈
Path 모듈은 파일 시스템 경로를 다루는 데 사용됩니다. 이 모듈을 사용하여 경로 문자열을 쉽게 조작할 수 있으며, 운영 체제 간의 차이를 자동으로 처리합니다.
- 기능: 파일 경로 생성, 경로 정보 분석, 경로 문자열 정규화, 파일 확장자 처리 등
- 사용 예:
path.join()
,path.resolve()
,path.basename()
,path.extname()
등
const path = require('path');
const filePath = path.join('/users', 'john', 'docs', 'letter.txt');
console.log(filePath); // '/users/john/docs/letter.txt' on POSIX, '\users\john\docs\letter.txt' on Windows
2. FS 모듈
FS(File System) 모듈은 파일 시스템에 접근하여 파일을 읽고 쓰는 기능을 제공합니다. 이 모듈을 통해 파일 생성, 삭제, 읽기, 쓰기 등의 작업을 할 수 있습니다.
- 기능: 파일 읽기/쓰기, 파일 상태 확인, 디렉토리 생성/삭제 등
- 사용 예:
fs.readFile()
,fs.writeFile()
,fs.stat()
,fs.mkdir()
,fs.unlink()
등
const fs = require('fs');
fs.readFile('example.txt', 'utf8', (err, data) => {
if (err) throw err;
console.log(data);
});
3. Express
Express는 Node.js를 위한 가장 인기 있는 웹 프레임워크 중 하나입니다. 간단한 웹 애플리케이션부터 복잡한 RESTful API까지 다양한 웹 서비스를 쉽고 빠르게 구축할 수 있게 해줍니다.
- 기능: 라우팅, 미들웨어 지원, 템플릿 엔진 통합, 요청 처리, 응답 관리 등
- 사용 예: 서버 생성, 라우트 정의, 미들웨어 추가, 서버 리스닝
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.listen(3000, () => {
console.log('Server is running on http://localhost:3000');
});
결론
Path, FS, Express 모듈은 Node.js 환경에서 JavaScript로 서버 사이드 애플리케이션을 개발할 때 필수적인 도구입니다. 이 모듈들은 파일 시스템 작업, 웹 서버 구축, API 개발 등 다양한 기능을 제공하여 JavaScript의 활용 범위를 웹 브라우저에서 서버 측 애플리케이션으로 확장시킵니다.
ExpressJS의 express.urlencoded({ extended: false })
미들웨어
ExpressJS에서 express.urlencoded({ extended: false })
미들웨어는 클라이언트로부터 오는 요청의 본문(body)을 파싱하는 데 사용됩니다. 이 미들웨어는 주로 <form>
태그에서 제출된 데이터를 처리하거나, POST 요청에서 Content-Type이 application/x-www-form-urlencoded
인 요청 본문을 파싱할 때 사용됩니다. 여기서 extended: false
옵션은 본문 데이터가 "URL-encoded" 형식으로 파싱될 때 사용되는 라이브러리를 지정합니다.
URL-Encoded 데이터
URL-Encoded 형식은 웹 폼 데이터를 서버로 전송할 때 사용되는 인코딩 방식입니다. 이 형식은 키-값 쌍을 &
로 연결하고, 공백은 +
또는 %20
으로, 특수 문자는 %
로 인코딩합니다. 예를 들어, 사용자 이름과 비밀번호를 전송할 때 다음과 같이 인코딩될 수 있습니다: username=JohnDoe&password=123456
.
extended
옵션
express.urlencoded()
함수는 extended
옵션을 받습니다. 이 옵션은 본문을 파싱할 때 사용되는 라이브러리를 선택합니다.
extended: true
일 경우, qs 라이브러리를 사용하여 복잡한 객체와 배열을 허용하는 본문 파싱을 합니다. 이는 중첩된 객체를 표현할 수 있게 해줍니다.extended: false
일 경우, querystring 라이브러리를 사용하여 문자열과 배열만을 허용하는 본문 파싱을 합니다. 이는 간단한 키-값 쌍만을 처리할 수 있습니다.
미들웨어 사용 예제
const express = require('express');
const app = express();
// URL-encoded 데이터 파싱 미들웨어 적용
app.use(express.urlencoded({ extended: false }));
app.post('/login', (req, res) => {
// req.body를 통해 폼 데이터에 접근
const { username, password } = req.body;
res.send(`Username: ${username}, Password: ${password}`);
});
app.listen(3000, () => {
console.log('Server is running on http://localhost:3000');
});
결론
express.urlencoded({ extended: false })
미들웨어는 Express 애플리케이션에서 클라이언트가 제출한 폼 데이터를 쉽게 처리할 수 있게 해줍니다. extended: false
옵션을 사용함으로써, 단순한 키-값 쌍을 처리하는 경우에 적합한 설정을 제공합니다. 이는 웹 개발에서 폼 데이터를 다루는 기본적이면서도 중요한 부분을 간소화해줍니다.
JavaScript에서의 new
키워드 이해하기
JavaScript는 프로토타입 기반의 언어로, 객체 지향 프로그래밍 패턴을 지원합니다. 이러한 패턴의 핵심 요소 중 하나가 바로 new
키워드입니다. new
키워드를 사용하면 생성자 함수를 통해 새로운 객체를 생성할 수 있습니다. 이 블로그 글에서는 new
키워드의 작동 원리와 사용 방법에 대해 자세히 알아보겠습니다.
new
키워드란?
new
키워드는 JavaScript에서 생성자 함수를 호출할 때 사용되며, 새로운 객체를 만들고 그 객체를 초기화합니다. 생성자 함수는 보통 대문자로 시작하는 관례를 따르며, new
를 사용하여 호출될 때 this
키워드는 새롭게 생성된 객체를 가리킵니다.
new
키워드의 작동 과정
- 새 객체 생성:
new
키워드는 먼저 빈 객체를 생성합니다. - 프로토타입 연결: 생성된 객체의
[[Prototype]]
(또는__proto__
) 속성이 생성자 함수의prototype
객체를 가리키도록 설정합니다. - 생성자 함수 실행: 생성자 함수의 본문이 실행되며,
this
는 새로 생성된 객체에 바인딩됩니다. - 객체 반환: 생성자 함수가 명시적으로 객체를 반환하지 않으면,
new
표현식은this
에 의해 참조된 새 객체를 반환합니다.
new
사용 예제
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.greet = function() {
console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
};
const john = new Person('John', 30);
john.greet(); // "Hello, my name is John and I am 30 years old."
이 예제에서 Person
함수는 생성자 함수로 사용되며, new Person('John', 30)
은 Person
의 인스턴스를 생성합니다. 생성된 객체 john
은 Person.prototype
에 정의된 greet
메소드에 접근할 수 있습니다.
new
와 객체 리터럴의 차이
new
키워드를 사용하여 객체를 생성하는 방법과 객체 리터럴 {}
을 사용하는 방법 사이에는 중요한 차이가 있습니다. 객체 리터럴은 단순히 새 객체를 생성하고 초기화하는 반면, new
키워드는 생성자 함수를 통해 객체를 생성하므로, 생성된 객체는 생성자 함수의 프로토타입 체인을 상속받습니다. 이는 객체가 공통의 메소드나 속성을 공유할 수 있게 하며, 메모리를 효율적으로 사용할 수 있게 합니다.
결론
new
키워드는 JavaScript에서 객체 지향 프로그래밍을 구현하는 데 중요한 도구입니다. 생성자 함수와 함께 사용되어, 코드의 재사용성을 높이고, 메모리 사용을 최적화하며, 객체 간의 상속 관계를 설정하는 데 도움을 줍니다. 이러한 이유로, new
키워드의 작동 원리를 이해하고 올바르게 사용하는 것은 JavaScript 개발자에게 필수적인 기술입니다.
__dirname
이해하기: Node.js에서의 디렉토리 경로
Node.js 개발 과정에서 __dirname
은 현재 실행 중인 스크립트가 위치한 디렉토리의 절대 경로를 나타내는 중요한 전역 변수입니다. 이 변수는 파일 시스템 작업을 수행할 때 기준 경로로 사용되며, 모듈이 위치한 디렉토리의 정확한 경로를 얻는 데 유용합니다.
__dirname
의 특징
- 절대 경로 제공:
__dirname
은 현재 모듈의 절대 경로를 문자열로 반환합니다. 이는 파일 시스템 작업을 상대 경로가 아닌 절대 경로를 기준으로 수행하려 할 때 유용합니다. - 보안과 신뢰성: 코드가 다른 환경이나 다른 디렉토리 구조에서 실행될 때,
__dirname
을 사용하면 경로 관련 문제를 방지할 수 있습니다. 이는 코드의 이식성과 신뢰성을 높여줍니다. - Node.js의 내장 변수: 별도의 선언이나 초기화 없이 Node.js 환경에서 바로 사용할 수 있습니다.
__dirname
사용 예시
const path = require('path');
// 현재 디렉토리의 절대 경로와 'logs' 디렉토리를 조합하여 새 경로 생성
const logDirectory = path.join(__dirname, 'logs');
console.log(logDirectory);
// 출력 예: /Users/yourname/projects/yourproject/logs
이 예시에서 path.join()
메소드는 __dirname
변수를 사용하여 현재 스크립트가 있는 디렉토리의 절대 경로와 'logs'라는 하위 디렉토리 이름을 결합합니다. 결과적으로, 운영 체제의 파일 시스템 구조에 관계없이 올바른 경로를 얻을 수 있습니다.
__dirname
과 process.cwd()
의 차이
__dirname
과 비슷한 목적으로 사용될 수 있는 또 다른 Node.js의 기능은 process.cwd()
입니다. 그러나 두 변수 사이에는 중요한 차이가 있습니다:
__dirname
: 현재 실행 중인 파일이 위치한 디렉토리의 절대 경로를 반환합니다.process.cwd()
: Node.js 프로세스가 시작된 작업 디렉토리를 반환합니다. 즉, Node.js 명령을 실행한 쉘 또는 터미널의 현재 디렉토리입니다.
이 두 가지는 특히 Node.js 애플리케이션을 다양한 디렉토리에서 실행할 때 경로 처리 방식에 영향을 미칩니다.
결론
__dirname
은 Node.js 개발에서 파일 시스템 경로를 안전하고 신뢰성 있게 다루기 위해 필수적인 전역 변수입니다. 코드의 이식성과 유지 보수성을 향상시키는 데 중요한 역할을 하며, 다양한 환경과 디렉토리 구조에서의 안정적인 파일 접근을 보장합니다.
Node.js의 readFileSync()
와 writeFileSync()
Node.js에서 파일 시스템 작업은 매우 중요한 부분입니다. 이 중 readFileSync()
와 writeFileSync()
함수는 파일을 동기적으로 읽고 쓰는 기본적인 방법을 제공합니다. 이들 함수는 fs
모듈의 일부이며, 파일 처리 작업을 간단하고 직관적으로 수행할 수 있게 해줍니다.
readFileSync()
함수
readFileSync()
함수는 지정된 경로의 파일 내용을 동기적으로 읽어서 반환합니다. 이 함수를 사용할 때 Node.js는 파일의 모든 내용을 읽은 후에야 다음 코드를 실행합니다. 이는 파일 크기가 크거나 디스크 속도가 느린 경우 프로그램의 성능에 영향을 줄 수 있습니다.
- 구문:
fs.readFileSync(path[, options])
- 매개변수:
path
: 읽을 파일의 경로입니다.options
: 인코딩이나 반환될 데이터의 형식을 지정하는 객체입니다.options
가 문자열인 경우, 인코딩을 의미합니다.
- 반환 값: 기본적으로 Buffer 객체를 반환하지만,
options
에 문자열 인코딩('utf8'
등)을 지정하면 문자열을 반환할 수 있습니다.
예제:
const fs = require('fs');
// 파일 동기적으로 읽기
const data = fs.readFileSync('example.txt', 'utf8');
console.log(data);
writeFileSync()
함수
writeFileSync()
함수는 지정된 데이터를 파일에 동기적으로 쓰는 작업을 수행합니다. 이 함수를 사용하면 데이터가 완전히 파일에 쓰여진 후에야 다음 코드가 실행됩니다. 파일 쓰기 작업 중에 오류가 발생하면 예외가 발생하므로, try-catch 블록으로 예외 처리를 해야 합니다.
- 구문:
fs.writeFileSync(file, data[, options])
- 매개변수:
file
: 쓰기 작업을 할 파일의 경로입니다.data
: 파일에 쓸 데이터입니다.options
: 파일 쓰기 옵션을 지정하는 객체입니다. 인코딩, 모드, 플래그 등을 설정할 수 있습니다.
- 반환 값: 없음.
예제:
const fs = require('fs');
// 파일에 데이터 동기적으로 쓰기
try {
fs.writeFileSync('output.txt', 'Hello, World!', 'utf8');
console.log('File written successfully');
} catch (err) {
console.error('Error writing file:', err);
}
주의 사항
readFileSync()
와 writeFileSync()
는 동기적인 함수이기 때문에, 이들을 사용하는 동안 Node.js 이벤트 루프가 차단됩니다. 따라서 이러한 함수는 주로 애플리케이션의 시작 단계나 작업량이 많지 않은 스크립트에서 사용하는 것이 좋습니다. 서버와 같이 높은 I/O 처리량이 요구되는 환경에서는 비동기적인 방식(fs.readFile()
, fs.writeFile()
등)을 사용하는 것이 더 적합합니다.
'Web > 100일 코딩 챌린지 - Web Development' 카테고리의 다른 글
섹션 20: 동적 라우트(URL), 오류 & 관리 처리하기 더 큰 Express 프로젝트 [51일차] (0) | 2024.02.02 |
---|---|
섹션 19: 더 많은 익스프레스: 템플릿을 사용한 정적 & 동적 콘텐츠(EJS) [50일차] (0) | 2024.02.02 |
섹션 18: 익스프레스JS로 노드JS 향상 [48일차] (0) | 2024.01.30 |
섹션 17: 노드JS 소개 - 백엔드 개발 시작하기 [47일차] (0) | 2024.01.30 |
섹션 16: 백엔드 개발 [46일차] (0) | 2024.01.29 |