Day 13 - 쿼리 파라미터 실습, 구조분해할당, 이름 짓기, Map 객체, List 자료구조

이유승·2024년 11월 18일
0

* 프로그래머스, 타입스크립트로 함께하는 웹 풀 사이클 개발(React, Node.js) 5기 강의 수강 내용을 정리하는 포스팅.

* 원활한 내용 이해를 위해 수업에서 제시된 자료 이외에, 개인적으로 조사한 자료 등을 덧붙이고 있음.

1. 쿼리 파라미터 실습

req.params

app.get('/user/:id', (req, res) => {
  const userId = req.params.id;
  res.send(`User ID is: ${userId}`);
});
  • GET 메소드에서는 백엔드에서 값을 '조회'하는 용도이기 때문에, 백엔드로 어떤 값을 전송할 수 없다.
  • 그런데 특정 데이터를 조회하기 위해서 프론트에서 백으로 기준값을 전송해야 한다면 어떻게 해야하는가?
  • 쿼리 파라미터 (Query Parameters)를 사용한다.
  • 위 코드 예시, /user 경로 뒤에 id값을 입력받는다고 할 때. 백엔드에서는 요청 데이터를 관리하는 req 인자 내부에 'param' 객체를 통해 URL 상의 쿼리 파라미터를 관리하고 있다. 클라이언트가 /user/123와 같은 요청을 보낼 때, 123이 id으로 매핑되는 것.

  • 점 표기법을 활용하여 req 내부의 param 내부의 값을 가져와서 사용하면 된다.

app.get('/user/:userId/post/:postId', (req, res) => {
  const { userId, postId } = req.params; // Extract multiple parameters
  res.send(`User ID: ${userId}, Post ID: ${postId}`);
});
  • 여러 개의 파라미터를 URL에서 가져올 수도 있다.

  • http://localhost:3000/user/123/post/456라는 요청을 보낸다고 하면..

  • User ID: 123, Post ID: 456로 쿼리 파라미터가 매핑되어 온다.



req.query

  • URL에 데이터를 전달하는 또 다른 쿼리 파라미터(Query Parameters).
http://localhost:3000/search?query=node&sort=desc&page=2
  • 이 예시는 query, sort, page라는 쿼리 파라미터를 생성하고 그 값을 지정하는 예시.

query의 값은 node으로 매핑
sort의 값은 desc으로 매핑
page의 값은 2으로 매핑

app.get('/search', (req, res) => {
  const { query, sort, page } = req.query; // Extract query parameters
  res.send(`Search Query: ${query}, Sort: ${sort}, Page: ${page}`);
});
  • 이 쿼리 파라미터는 req.query으로 가져올 수 있다. 이전과 동일하게 객체 형태로 제공되고, URL에서 ? 뒤에 전달된 값들이 키-값 쌍으로 매핑된다.



params? query?

req.params: URL 경로에 정의된 Route Parameter를 처리.

req.query: URL의 쿼리 파라미터를 처리.

  • 쿼리 파라미터는 key값만 존재하더라도, 애초에 필수값이 아니기때문에 에러가 발생되거나 하지 않는다. undefined로만 처리되기 때문에 버그가 발생하거나 해도 알아차리기 어려울 수 있으니 주의해야 한다.

  • 특히! 쿼리 파라미터는 URL에 노출되기 때문에 누구나 쉽게 살펴볼 수 있다! 비밀번호 등의 민감한 정보를 전달할 때는 반드시 POST 요청과 req.body를 사용하는 것이 기본 중의 기본.

  • 실무에서는 POST 요청을 기본으로 깔고, HTTPS 사용 / 입력 데이터 검증 / 인증 및 권한 부여 / 데이터 암호화 / CSRF 방지 / CORS 설정 / 요청 제한 / 로그 및 모니터링 / API 키와 토큰 사용 / 보안 헤더 설정 / 배포 환경 보안 설정 / 정기점검 등의 방책들이 다중으로 설정된다.



Params과 객체 데이터를 활용한 API 실습

const express = require('express');
const app = express();
const { callBackYoutuber } = require('./api-test-01');

const PORT = process.env.PORT || 3000;

app.get('/', (req, res) => {
  res.send('Hello World!');
});

app.use('/:channelName', callBackYoutuber);

app.listen(3000, () => {
  console.log(`서버가 ${PORT} 포트에서 정상 동작 중입니다.`);
});
const youtuber1 = {
    channelName: 'AwesomeChannel',
    subscriberCount: 1500000,
    videoCount: 120,
};

const youtuber2 = {
    channelName: 'TechChannel',
    subscriberCount: 500000,
    videoCount: 80,
};

const youtuber3 = {
    channelName: 'FoodChannel',
    subscriberCount: 1200000,
    videoCount: 220,
};

const callBackYoutuber = (req, res) => {
    const channelName = req.params.channelName;

    if (channelName === 'AwesomeChannel') {
        res.json(youtuber1);
    } 
    else if (channelName === 'TechChannel') {
        res.json(youtuber2);
    }
    else if (channelName === 'FoodChannel') {
        res.json(youtuber3);      
    }
    else {
        res.json('존재하지 않는 대상입니다.');
    }
};

module.exports = { callBackYoutuber };



2. Javascript 학습

구조분해할당



이름 짓기 규칙



Map 객체

  • ES6에서 도입된 키-값(key-value) 쌍을 저장하는 자료형.

  • 객체와 유사하지만 더 다양한 키를 사용할 수 있는 기능과 추가적인 메서드를 제공한다.

  • 객체의 키는 문자열 또는 심볼만 가능하지만, Map의 키는 원시값(숫자, 문자열, 불리언)과 객체, 함수 등 모든 타입이 가능하다.

  • value는 일반 객체와 Map 모두 객체 타입 데이터를 담는게 가능하다.

const map = new Map();

주요 메서드

  • set(key, value)
    - 키와 값을 Map에 추가합니다.

  • get(key)
    - 주어진 키에 해당하는 값을 반환합니다.

  • has(key)
    - 주어진 키가 존재하면 true를 반환합니다.

  • delete(key)
    - 주어진 키를 삭제합니다.

  • clear()
    - 모든 키-값 쌍을 삭제합니다.

  • size
    - Map에 저장된 키-값 쌍의 개수를 반환합니다.

사용 예시

const map = new Map();

// 값 추가
map.set('name', 'Alice');
map.set('age', 25);

// 값 읽기
console.log(map.get('name')); // Alice
console.log(map.get('age')); // 25

// 키 확인
console.log(map.has('name')); // true
console.log(map.has('gender')); // false

// 크기 확인
console.log(map.size); // 2

객체와 Map의 차이점

특징객체(Object)Map
키의 데이터 타입문자열 또는 심볼만 가능모든 데이터 타입 가능 (객체, 함수 등 포함)
삽입 순서보장되지 않음삽입된 순서를 항상 보장
기본 프로토타입 키존재 (toString, __proto__ 등 포함)없음
크기 확인Object.keys(obj).length를 사용해야 함map.size로 간단히 확인 가능
반복 가능 여부직접 반복 구현 필요 (for...in이나 Object.entries 사용)기본적으로 iterable (for...ofmap.entries() 사용 가능)
성능대량의 데이터 추가/삭제 시 느림대량의 데이터 추가/삭제 시 더 빠름
용도단순 키-값 저장 시 사용 적합다양한 키 타입 및 순서가 중요한 경우 적합

요약

  • 객체: 간단한 키-값 저장에 적합, 문자열 또는 심볼을 키로 사용하는 경우에 유리.
  • Map: 키의 타입이 다양하거나 데이터 삽입 순서를 유지해야 하는 경우에 적합하며, 더 강력한 메서드와 성능을 제공.



List 자료구조

  • 동일한 타입 또는 다양한 타입의 데이터를 순서대로 저장할 수 있는 선형 자료구조.

  • 일반적으로 리스트는 배열(Array)과 연결 리스트(Linked List) 두 가지 형태로 나뉘어진다.

연결 리스트(Linked List)

  • 각 요소가 데이터와 다음 요소를 가리키는 포인터를 가진 노드로 구성된 리스트.
// 단순한 연결 리스트의 예
class Node {
  constructor(data) {
    this.data = data;
    this.next = null;
  }
}

class LinkedList {
  constructor() {
    this.head = null;
  }

  append(data) {
    const newNode = new Node(data);
    if (!this.head) {
      this.head = newNode;
      return;
    }
    let current = this.head;
    while (current.next) {
      current = current.next;
    }
    current.next = newNode;
  }
}

const list = new LinkedList();
list.append('a');
list.append('b');
list.append('c');
console.log(list.head); // 출력: Node { data: 'a', next: Node {...} }

배열(Array)과 연결 리스트(Linked List)의 비교

특징배열(Array List)연결 리스트(Linked List)
메모리 할당고정 크기 또는 연속된 메모리 공간 사용동적으로 메모리 할당
접근 속도O(1), 인덱스를 통해 직접 접근 가능O(n), 순차적으로 접근해야 함
삽입/삭제 속도느림(O(n)), 요소 이동 필요빠름(O(1)), 포인터 변경
메모리 효율성포인터가 없으므로 메모리 사용량 적음포인터를 저장해야 하므로 메모리 사용량 많음
구현 복잡도간단함상대적으로 복잡함
순서 유지삽입된 순서 유지삽입된 순서 유지
적합한 경우빠른 접근이 필요한 경우삽입/삭제가 빈번한 경우
profile
프론트엔드 개발자를 준비하고 있습니다.

0개의 댓글