사용자 스토리에 대한 와이어프레임을 작성하는 것은 모든 사람이 무엇을 구축해야 하는지 이해하는 데 도움이 된다. 그리고 와이어프레임은 사용자 스토리에 다시 연결할 수 있다. 연결된 사용자 스토리는 세부 사항을 구현하는 데 중요한 부분이 된다.
(파워포인트 또는 키노트를 사용)

  1. 슬라이드 크기를 디스플레이 해상도와 같은 크기로 설정한다.
  2. 페이지 템플릿을 만들기 위해 마스터 슬라이드를 사용한다.
  3. 아이콘을 만들기 위해 Awesome 폰트를 사용한다.
  4. 요소가 선택되지 않도록 잠금(Lock)을 선택한다.
  5. 연습은 완벽을 만든다.
참조 : 실전! 스프링 5 Vue.js 2 시작하는 모던  애플리케이션 개발 - 스프링 부트와 Vuex 활용한 실습 중심의 풀스택  애플리케이션 개발 ( 제임스 J.  (지은이))

'기타 개발 기록 > 개발 팁' 카테고리의 다른 글

데이터 모델링  (0) 2020.07.12
사용자 스토리 작성법  (0) 2020.07.11
  1. <사용자 유형>으로서, 나는 <어떤 가치 얻기>를 할 수 있도록, <어떤 것 하기>를 원한다. (나는 ~을 원한다. 나는 ~을 할 수 있다. 나는 ~을 하고 싶다.)
    • 등록된 사용자로서, 나는 애플리케이션에 로그인할 수 있도록, 나의 사용자 이름 또는 이메일 주소와 비밀번호를 활용할 수 있다.
  2. 사용자 스토리가 사용자에게 엔드-투-엔드 기능을 제공할 수 있는지 확인한다.
    • 폼 작성과 폼 제출을 나눠서 작성하면 x
  3. 사용자 스토리를 작고 실행 가능하게 유지한다.
    • 보드 멤버로서, 나는 카드를 관리할 수 있다. (x)
    • 보드 멤버로서, 나는 카드를 생성할 수 있다.
      보드 멤버로서, 나는 카드를 보관할 수 있다.
      보드 멤버로서, 나는 카드 리스트 사이에 카드를 이동시킬 수 있다.
      보드 멤버로서, 나는 카드 위치를 바꿀 수 있다.
      보드 멤버로서, 나는 보관된 카드를 삭제할 수 있다.

  4. 사용자 스토리에 허용 기준을 추가한다.
    • 방문자로서, 나는 나의 이메일 주소, 사용자 이름, 비밀번호로 사용자 계정을 등록하기를 원한다.
      • 이메일 주소가 시스템에 이미 존재해서는 안 된다.
      • 사용자 이름이 시스템에 이미 존재해서는 안 된다.
      • 비밀번호는 최소한 6자 이상이어야 한다.
      • 비밀번호는 최소한 1개의 숫자를 포함해야 한다.
      • 비밀번호는 최소한 1개의 문자를 포함해야 한다.
  5. 사용자 스토리에 사용자 인터페이스를 포함하는 것을 피해야 한다.
    • 관리자로서 나는 이름, 이메일 주소, 등록 날짜 별로 사용자를 검색하는 데 키워드 필드와 날짜 선택기를 사용할 수 있도록 필터를 실행하는 필터 열기 버튼을 클릭하기를 원한다. (x)
    • 관리자로서 나는 사용자를 빠르게 찾을 수 있도록 이름, 이메일 주소, 등록 날짜 별로 사용자를 검색하기를 원한다. (o)
  6. 사용자 스토리를 그룹화하기 위해 테마를 사용한다. 테마는 공통 속성을 공유하는 사용자 스토리 집단.
    • 카드라는 테마를 사용하고 카드와 관련된 모든 사용자 스토리를 이 테마에 그룹화.
  7. 사용자 스토리를 참조하기 위해 숫자 대신 짧은 제목을 사용.
    • 스토리 39 (x)
    • 카드 제목 편집하기 스토리  (o)

 

참조 : 실전! 스프링 5 Vue.js 2 시작하는 모던  애플리케이션 개발 - 스프링 부트와 Vuex 활용한 실습 중심의 풀스택  애플리케이션 개발 ( 제임스 J.  (지은이))

'기타 개발 기록 > 개발 팁' 카테고리의 다른 글

데이터 모델링  (0) 2020.07.12
와이어프레임 작성하기  (0) 2020.07.12

6.1 도커 플러그인이란?

6.2 도커 볼륨 플러그인

6.2.1 sshFS
6.2.2 Azure File Storage
6.2.3 Flocker
6.2.4 NFS와 Convoy

6.3 도커 네트워크 플러그인

6.3.1 위브

'개발 도서 > 시작하세요!도커' 카테고리의 다른 글

05 도커 컴포즈  (0) 2020.07.05
04 도커 머신  (0) 2020.07.05
03 도커 스웜  (0) 2020.07.05
02 도커 엔진 - 2.4 Dockerfile  (0) 2020.06.08
02 도커 엔진 - 2.3 도커 이미지  (0) 2020.06.07

5.1 도커 컴포즈를 사용하는 이유

여러 개의 컨테이너를 하나의 서비스로 정의해 컨테이너 묶음으로 관리할 수 있게 해 줌. 여러 개의 컨테이너의 옵션과 환경을 정의한 파일을 읽어 컨테이너를 순차적으로 생성하는 방식으로 동작함.

5.2 도커 컴포즈 설치

//Docker for Windows, Docker for Mac을 설치하면 도커 엔진과 함께 도커 컴포즈도 설치됨
docker-compose -v

5.3 도커 컴포즈 사용

5.3.1 도커 컴포즈 기본 사용법

5.3.1.1 docker-compose.yml 작성과 활용

//docker-compose.yml
version: '3.0'	//YAML 파일 포맷의 버전 지정
services:	//생성될 컨테이너들을 묶어놓은 단위
  web:	//생성될 서비스의 이름. docker run에서 사용한 옵션을 아래에 지정
    image: alicek106/composetest:web
    ports:
      - "80:80"
    links:
      - mysql:db
    command: apachectl -DFOREGROUND
  mysql:
    image: alicek106/composetest:mysql
    command: mysqld
    
    
//아무 설정하지 않으면 현재 디렉터리의 docker-compose.yml 파일을 읽어 도커 엔진에게 컨테이너 생성 요청
docker-compose up -d

//docker-compose.yml끝에 서비의 이름을 입력해 특정 서비스의 컨테이너만 생성
docker-compose up -d mysql

//docker-compose run 명령어로 컨테이너 생성. interactive 셸 사용 가능.
docker-compose run web /bin/bash

5.3.1.2 도커 컴포즈의 프로젝트, 서비스, 컨테이너

  • 하나의 프로젝트는 여러개의 서비스로 구성되고, 각 서비스는 여러 개의 컨테이너로 구성됨
  • 컨테이너의 이름 -> [프로젝트 이름]_[서비스 이름]_[서비스 내의 컨테이너의 번호]
//서비스의 컨테이너 수 늘리기
docker-compose scale mysql=2

//프로젝트 삭제
docker-compose down

//-p 옵션에 프로젝트의 이름을 사용해 제어할 프로젝트의 이름을 명시
docker-compose -p myproject up -d
docker-compose -p myproject ps
docker-compose -p myproject down

5.3.2 도커 컴포즈 활용

5.3.2.1 YAML 파일 작성
5.3.2.2 도커 컴포즈 네트워크
5.3.2.3 도커 스웜과 함께 사용하기
5.3.2.4 도커 스웜 모드와 함께 사용하기

'개발 도서 > 시작하세요!도커' 카테고리의 다른 글

06 도커 플러그인  (0) 2020.07.05
04 도커 머신  (0) 2020.07.05
03 도커 스웜  (0) 2020.07.05
02 도커 엔진 - 2.4 Dockerfile  (0) 2020.06.08
02 도커 엔진 - 2.3 도커 이미지  (0) 2020.06.07

4.1 도커 머신을 사용하는 이유

4.2 도커 머신 사용

4.2.1 도커 머신 시작
4.2.2 버추얼 박스를 이용한 로컬 가상 머신 생성
4.2.3 클라우드에 도커 서버 생성

  • 아마존 웹 서비스에 도커 서버 생성
  • 애저에 도커 서버 생성

4.2.4 온프레미스 환경에 연결

'개발 도서 > 시작하세요!도커' 카테고리의 다른 글

06 도커 플러그인  (0) 2020.07.05
05 도커 컴포즈  (0) 2020.07.05
03 도커 스웜  (0) 2020.07.05
02 도커 엔진 - 2.4 Dockerfile  (0) 2020.06.08
02 도커 엔진 - 2.3 도커 이미지  (0) 2020.06.07

3.1 도커 스웜을 사용하는 이유

여러 대의 서버를 손쉽게 하나의 자원 풀로 만들기 위해 사용. 클러스터를 만들 때 발생하는 아래의 이슈들을 도커스웜을 통해 해결.

  • 새로운 서버나 컨테이너가 추가됐을 때 이를 발견
  • 어떤 서버에 컨테이너를 할당할 것인가에 대한 스케줄러와 로드밸런서
  • 클러스터 내의 서버가 다운됐을 때 고가용성을 어떻게 보장할지

3.2 도커 스웜과 도커 스웜 모드

  • 도커 버전 1.6 이후부터 사용할 수 있는 컨테이너로서의 스웜(도커 스웜)
    <-> 도커 버전 1.12 이후부터 사용할 수 있는 도커 스웜 모드(스웜 모드)
  • 도커스웜은 도커를 제어하기 위한 에이전트가 컨테이너로서 존재하며 분산 콘테이너 또한 외부에 별도로 존재해야 함.
    <-> 스웜 모드는 에이전트가 도커 자체에 내장돼 있어 이를 별도로 설치할 필요가 없으며, 외부 분산 코디네이터를 설치할 필요도 없음.
    (스웜 모드가 스웜에 비해 설치와 사용이 더욱 쉽고 간편)
  • 도커 스웜은 여러 대의 도커 서버를 하나의 지점에서 사용하도록 단일 접근점을 제공하는데 초점을 둠.
    <-> 스웜모드는 웹 서비스 컨테이를 다루기 위한 클러스터링 기능에 초점을 둠.
  • 도커 스웜은 doker run, docker ps 등 일반적인 명령어로 클러스터의 서버를 제어하고 관리할 수 있는 기능을 제공함.
    <-> 스웜모드는 같은 컨테이너를 동시에 여러 개 생성해 필요에 따라 유동적으로 컨테이너의 수를 조절할 수 있으며, 컨테이너로의 연결을 분산하는 로드밸런싱 기능을 자체적으로 지원함.

3.3 도커 스웜 모드

3.3.1 도커 스웜 모드의 구조
3.3.2 도커 스웜 모드 클러스터 구축

//--advertise-addr에 다른 도커 서버가 매니저 노드에 접근하기 위한 IP주소 입력 (매니저 노드가 될 서버에서 입력)
docker swarm init --advertise-addr 192.168.0.100

//토큰을 사용해 워커 노드를 추가 (워커 노드로 사용할 각 서버에서 입력)
docker swarm join --token [token~] [ip~]

//매니저 노드에서 도커 서버가 정상적으로 클러스터에 추가됐는지 확인
docker node ls

//새로운 매니저 노드를 추가하기 위한 토큰 확인
docker swarm join-token manager

//워커 노드를 추가하기 위한 토큰 확인
docker swarm join-token worker

//토큰 갱신 (매니저 노드에서만 실행 가능)
docker swarm join-token --rotate manager

//워커 노드 삭제 (해당 워커 노드에서 실행) 
docker swarm leave

//정지된 워커노드를 매니저 노드에서 직접 삭제
docker swarm rm node01

//매니저 노드를 삭제하려면 --force 필요
docker swarm leave --force

//워커 노드를 매니저 노드로 변경
docker node promote swarm-worker1

//매니저 노드를 워커 노드로 변경
docker node demote swarm-worker1


3.3.3 스웜 모드 서비스

스웜 모드에서 제어하는 단위는 컨테이너가 아닌 서비스. 서비스는 같은 이미지에서 생성된 컨테이너의 집합. 서비스 내에 컨테이너는 1개 이상 존재할 수 있으며, 각 워커 노드와 매니저 노드에 할당됨. (≒태스크(Task))

3.3.3.1 스웜 모드 서비스 개념
3.3.3.2 서비스 생성
3.3.3.3 스웜 모드의 서비스 장애 복구
3.3.3.4 서비스 롤링 업데이트
3.3.3.5 도커 스웜 네트워크
3.3.3.6 서비스 디스커버리
3.3.3.7 스웜 모드 볼륨

3.3.4 도커 스웜 모드 노드 다루기

3.4 도커스웜

3.4.1 도커 스웜과 스웜 모드의 차이점
3.4.2 도커 스웜 클러스터 구축
3.4.3 도커 스웜 사용
3.4.4 도커 스웜 스케쥴러

_.chunk

사용법 :  _.chunk(array, [size=N]) is the 
용도 : 배열을 원하는 크기로 나눈다.

_.compact

사용법 : _.compact(array)
용도 : false, null, 0, "", undefined, NaN 등의 falsey값을 제거한 배열을 생성한다.

_.concat

사용법 : _.concat(array, [values])
용도 : 서로 다른 숫자나, 배열을 연결시켜 새로운 배열을 만든다.

_.difference

사용법 : _.difference(array, [values])
용도 : 두 배열에서 다른 원소를 찾아낸다.

_.differenceBy

사용법 : _.differenceBy(array, [values], [iteratee=_.identity])
용도 : _.difference + iteratee

_.differenceWith

사용법 :  _.differenceWith(array, [values], [comparator])
용도 : _.difference + comparator

_.drop

사용법 : _.drop(array, [n=1])
용도 : 앞에서부터 n개 원소를 제거함

_.dropRight

사용법 : _.dropRight(array, [n=1])
용도 : 뒤에서부터 n개 원소를 제거함

_.dropRightWhile

사용법 : _.dropRightWhile(array, [predicate=_.identity])
용도 : 조건이 falsey값을 반환할 때까지 뒤에서부터 제거

_.dropWhile

사용법 : _.dropWhile(array, [predicate=_.identity])
용도 : 조건이 falsey값을 반환할 때까지 앞에서부터 제거

_.fill

사용법 : _.fill(array, value, [start=0], [end=array.length])
용도 :  배열에 특정값을 채움

_.findIndex

사용법 : _.findIndex(array, [predicate=_.identity], [fromIndex=0])
용도 : 객체 배열에서 특정 조건에 해당하는 첫번째 객체의 인덱스를 찾음

_.findLastIndex

사용법 :_.findLastIndex(array, [predicate=_.identity], [fromIndex=array.length-1])
용도 :  객체 배열에서 특정 조건에 해당하는 마지막 객체의 인덱스를 찾음

_.first -> head

first -> head로 변경

_.flatten

사용법 : _.flatten(array)
용도 : 배열의 차원을 1차원 낮춤

_.flattenDeep

사용법 : _.flattenDeep(array)
용도 : 배열의 차원을 없앰

_.flattenDepth

사용법 : _.flattenDepth(array, [depth=1])
용도 :  depth만큼의 차원을 낮춤

_.fromPairs

사용법 : _.fromPairs(pairs)
용도 : key, value 배열을 객체로 바꿈 

_.head

사용법 : _.head(array)
용도 : 배열의 첫번째 원소를 반환함

_.indexOf

사용법 : _.indexOf(array, value, [fromIndex=0])
용도 : 배열에서 값의 인덱스 찾기

_.initial

사용법 : _.initial(array)
용도 : 배열의 마지막 원소를 제외한 모든 원소 추출

_.intersection

사용법 : _.intersection([arrays])
용도 : 배열 리스트 중 첫번째 배열과 나머지 배열들의 교집합 원소 추출

_.intersectionBy

사용법 : _.intersectionBy([arrays], [iteratee=_.identity])
용도 : _.intersection + iteratee

_.intersectionWith

사용법 : _.intersectionWith([arrays], [comparator])
용도 : _.intersection + comparator

_.join

사용법 : _.join(array, [separator=','])
용도 : 배열을 구분자를 사이에 두고 연결함

_.last

사용법 : _.last(array)
용도 : 배열의 마지막 원소를 찾음

_.lastIndexOf

사용법 : _.lastIndexOf(array, value, [fromIndex=array.length-1])
용도 :  _.indexOf + 오른쪽을 기준으로 왼쪽으로 검색

_.nth

사용법 : _.nth(array, [n=0])
용도 : 배열에서 n번째 요소 찾음

_.pull

사용법 : _.pull(array, values)
용도 : 배열에서 values에 포함된 값 제거

_.pullAll

사용법 : _.pullAll(array, [values])
용도 : _.pull + 제거할 값이 배열로 입력

_.pullAllBy

사용법 : _.pullAllBy(array, values, [iteratee=_.identity])
용도  : _.pullAll + iteratee

_.pullAllWith

사용법 : _.pullAllWith(array, values, [comparator])
용도 : _.pullAll + comparator

_.pullAt

사용법 : _.pullAt(array, [indexes])
용도 : index의 값을 제거하고, 제거한 index의 배열을 리턴함

_.remove

사용법 : _.remove(array, [predicate=_.identity])
용도 : predicate 조건으로 배열에서 원소를 제거

_.reverse

사용법 : _.reverse(array)
용도 : 배열을 원소 순서를 뒤집는다.

_.slice

사용법 : _.slice(array, [start=0], [end=array.length])
용도 : start ~ end-1 까지의 배열을 만든다.

_.sortedIndex

사용법 : _.sortedIndex(array, value)
용도 : 정렬을 유지한 상태로 삽입되기 위한 index를 찾는다. 

_.sortedIndexBy

사용법 : _.sortedIndexBy(array, value, [iteratee=_.identity])
용도 : _.sortedIndex + iteratee

_.sortedIndexOf

사용법 : _.sortedIndexOf(array, value)
용도 : _.indexOf + 정렬된 배열에서의 value index찾기

_.sortedLastIndex

사용법 : _.sortedLastIndex(array, value)
용도 : _.indexOf + 배열의 정렬 상태 유지하면서 삽입하기 위한 마지막 index

_.sortedLastIndexBy

사용법 : _.sortedLastIndexBy(array, value, [iteratee=_.identity])
용도 : .sortedLastIndex + iteratee

_.sortedLastIndexOf

사용법 : _.sortedLastIndexOf(array, value)
용도 : _.lastIndexOf + 배열의 정렬 상태 유지하면서 삽입하기 위한 마지막 index

_.sortedUniq

사용법 : _.sortedUniq(array)
용도 : _.uniq + 정렬

_.sortedUniqBy

사용법 : _.sortedUniqBy(array, [iteratee])
용도 : _.uniqBy + iteratee

_.tail

사용법 : _.tail(array)
용도 : 배열에서 첫번째 원소 제외한 나머지

_.take

사용법 : _.take(array, [n=1])
용도 : n크기 만큼의 배열만 선택

_.takeRight

사용법 : _.takeRight(array, [n=1])
용도 : 오른쪽에서 n크기 만큼의 배열만 선택

_.takeRightWhile

사용법 : _.takeRightWhile(array, [predicate=_.identity])
용도 : 오른쪽에서 predicate가 false를 반환할 때 까지의 배열 선택

_.takeWhile

사용법 : _.takeWhile(array, [predicate=_.identity])
용도 : 왼쪽에서 predicate가 false를 반환할 때 까지의 배열 선택

_.union

사용법 : _.union([arrays])
용도 : 중복 제외 배열 합치기

_.unionBy

사용법 : _.unionBy([arrays], [iteratee=_.identity])
용도 : _.union + iteratee

_.unionWith

사용법 : _.unionWith([arrays], [comparator])
용도 : _.unio + comparator

_.uniq

사용법 : _.uniq(array)
용도 : 중복제거

_.uniqBy

사용법 : _.uniqBy(array, [iteratee=_.identity])
용도 : _.uniq + iteratee

_.uniqWith

사용법 : _.uniqWith(array, [comparator])
용도 : _.uniq + comparator

_.unzip

사용법 : _.unzip(array)
용도 : 그룹화된 배열을 개별화

_.unzipWith

사용법 : _.unzipWith(array, [iteratee=_.identity])
용도 : _unzip + iteratee

_.without

사용법 : _.without(array, [values])
용도 : 배열에서 값 제거

_.xor

사용법 : _.xor([arrays])
용도 : 서로 다른 값으로 배열 제거

_.xorBy

사용법 : _.xorBy([arrays], [iteratee=_.identity])
용도 :  _.xor + iteratee

_.xorWith

사용법 : _.xorWith([arrays], [comparator])
용도 : _.xor + comparator

_.zip

사용법 : _.zip([arrays])
용도 : 배열을 그룹핑

_.zipObject

사용법 : _.zipObject([props=[]], [values=[]])
용도 : 배열을 key + value 객체로 그룹핑

_.zipObjectDeep

사용법 : _.zipObjectDeep([props=[]], [values=[]])
용도 : _.zipObject + 문자열에 속성 path를 허용

_.zipWith

사용법 : _.zipWith([arrays], [iteratee=_.identity])
용도 : _.zip + iteratee

'공식메뉴얼 > lodash' 카테고리의 다른 글

Collection  (0) 2020.07.12
Lodash란?  (1) 2020.06.27

Lodash란 js 라이브러리 공식 메뉴얼을 학습해보고자 한다.

"A modern JavaScript utility library delivering modularity, performance & extras" 

라고 공식 홈페이지에서 소개하고 있다.
jquery처럼 전역으로 선언해놓고 사용하면 유용하다. 특히 json으로 이루어진 배열을 다룰 때 또는 중첩 구조로 인해 객체 구조가 복잡해졌을 때 사용하면 유용하다.
유사한 라이브러리로는 underscore(https://underscorejs.org/)가 있으나, lodash가 브라우저 변화에 더 안정적이고, 더 많은 API와 성능 향상을 제공한다고 한다.
(참조 : https://benmccormick.org/2014/11/12/underscore-vs-lodash)

아래에 링크에 들어가면 메뉴얼이 잘 정리되어있으나, 학습을 위해 하나하나 뜯어보면서 기록해보기로 한다.

https://lodash.com/

 

Lodash

_.defaults({ 'a': 1 }, { 'a': 3, 'b': 2 });_.partition([1, 2, 3, 4], n => n % 2);DownloadLodash is released under the MIT license & supports modern environments. Review the build differences & pick one that’s right for you.InstallationIn

lodash.com

제공하는 카테고리 ? 

  • Array
  • Collection
  • Date
  • Function
  • Lang
  • Math
  • Number
  • Object
  • Seq
  • String
  • Util
  • Properties
  • methods

'공식메뉴얼 > lodash' 카테고리의 다른 글

Collection  (0) 2020.07.12
Array  (0) 2020.06.27

23.1 JWT의 이해

세션 기반 인증과 토큰 기반 인증의 차이

  • 세션 기반 인증 시스템
    • 서버가 사용자가 로그인 중임을 기억하고 있음. 로그인하면, 서버는 세션 저장소에 사용자의 정보를 조회하고 세션 id를 발급함. 발급된 id는 주로 브라우저의 쿠키에 저장.
    • 서버를 확장하기가 번거로움. (서버 여러개 되면 세션 전용 데이터베이스 만들어야 함.)
  • 토큰 기반 인증 시스템
    • 토큰은 로그인 이후 서버가 만들어 주는 문자열. 이 안에 사용자의 로그인 정보가 들어 있고, 해당 정보가 서버에서 발급되었음을 증명하는 서명이 들어 있음. (무결성 보장)
    • 로그인하면, 서버에서 사용자에게 해당 사용자의 정보를 지니고 있는 토큰을 발급해 주고, 추후 사용자가 다른 API를 요청하게 될 때 발급받은 토큰과 함께 요청하게 됨.
    • 서버 리소스 절약. 서버의 확장성 높음 

23.2 User 스키마/모델 만들기

  • 모델 메서드 만들기
  • 스태틱 메서드 만들기

23.3 회원 인증 API 만들기

  • 회원가입 구현하기
  • 로그인 구현하기

23.4 토큰 발급 및 검증하기

yarn add jsonwebtoken

23.4.1 비밀키 설정하기

openssl rand -hex 64

23.4.2 토큰 발급하기

  • localStorage, sessionStorage : 구현과 사용이 편리하지만, XSS에 취약.
  • 쿠키 : httpOnly 속성을 활성화해서  XSS방지, CSRF는 CSRF 토큰 사용 및 Referer 검증 등의 방식으로 제대로 막을 수 있음.
    const token = jwt.sign(
        {
            _id: this.id, username: this.username //첫 번째 파라미터 -> 토큰 안에 넣고 싶은 데이터
        },
        process.env.JWT_SECRET, //두 번째 파라미터 -> JWT 암호
        {
            expiresIn: '7d', //세 번째 파라미터 -> 유효기간
        }
    );

23.4.3 토큰 검증하기

const decoded = jwt.verify(token, process.env.JWT_SECRET);

23.4.4 토큰 재발급하기

23.4.5 로그아웃 기능 구현하기

23.5 posts API에 회원 인증 시스템 도입하기

23.6 username/tags로 포스트 필터링하기

 

22.1 소개하기

  • MongoDB는 관계형 데이터베이스의 스키마, 확장성에서의 한계를 극복한 문서 지향적 NoSQL 데이터베이스.
  • 데이터의 구조가 자주 바뀐다면 MongoDB가 유리, 까다로운 조건으로 데이터를 필터링해야 하거나, ACID 특성을 지켜야 한다면 RDBMS가 더 유리할 수 있음.

22.1.1 문서란?
22.1.2 MongoDB 구조
22.1.3 스키마 디자인 

22.2 MongoDB 서버 준비

22.2.1 설치

//macOS, Homebrew를 이용하여 설치
brew tap mongodb/brew
brew install mongodb-community
brew services start mongodb-community

22.2.2 MongoDB 작동 확인

//mongoDB 실행 확인
mongo

//버전 확인
>version()

22.3 mongoose의 설치 및 적용

MongoDB 기반 ODM(Object Data Modelling) 라이브러리. 데이터베이스 문서들을 자바스크립트 객체처럼 사용할 수 있게 해 줌

//mongoose, dotenv 설치
yarn add mongoose dotenv

//dotenv로 환경변수 호출
require('dotenv').config();
const {PORT, MONGO_URI} = process.env;

//mongoose로 서버와 데이터베이스 연결
mongoose.connect(MONGO_URI, {useNewUrlParser: true, useFindAndModify: false}).then(() =>
    console.log('connected to MongoDB')).catch(e => console.log(e));

22.4 ems으로 ES 모듈 import/export 문법 사용하기

//Node.js v12를 사용할 경우, package.json에 다음 줄을 추가하면 ES Module을 바로 사용할 수 있음
"scripts" : {
	...
},
"type" : "module"

//esm 추가
yarn add esm

// 기존 src/index.js 이름을 main.js로 변경하고, index.js를 아래와 같이 새로 생성
require = require('esm')(module);
module.exports = require('./mains.js');

//package.json 스크립트 변경
"scripts" : {
	"start" : "node -r esm src",
    "start:dev" : "nodemon --watch src -r esm src/indx.js"
}


//jsconfig.json 파일 추가하면 자동 완성을 통해 모듈을 불러올 수 있음
{
  "compilerOptions": {
    "target": "es6",
    "module": "es2015"
  },
  "include": ["src/**/*"]
}

22.5 데이터베이스의 스키마와 모델

  • 스키마 - 컬렉션에 들어가는 문서 내부의 각 필드가 어떤 형식으로 되어 있는지 정의하는 객체
  • 모델 - 스키마를 사용하여 만드는 인스턴스, 데이터베이스에 실제 작업을 처리할 수 있는 함수들을 지니고 있는 객체

22.6 MongoDB Compass의 설치 및 사용

MongoDB를 위한 GUI 프로그램
(www.mongodb.com/try/download/compass)

22.7 데이터 생성과 조회

  • 생성 : 모델로 인스턴스를 생성하고 save함수 호출
  • 데이터 리스트 조회 : 모델 인스턴스의 find함수를 사용 (exec()를 붙여줘야 서버에 쿼리 요청)
  • 단일 데이터 조회 : 모델 인스턴스의 findById 함수를 사용

22.8 데이터 삭제와 수정

  • 삭제 : remove - 특정 조건을 만족하는 데이터를 모두 지움, findByIdAndRemove - id를 찾아서 지움 , findOneAndRemove -  특정 조건을 만족하는 데이터 하나를 찾아서 제거
  • 수정 : findByIdAndUpdate 함수를 사용. id, 업데이트 내용, 업데이트 옵션을 차례로 파라미터로 받음

22.9 요청 검증

22.9.1 ObjectId 검증

//mongoDB에 적합한 object id인지 검증
import mongoose from 'mongoose';

const { ObjectId } = mongoose.Types;
ObjectId.isValid(id);

//미들웨어를 사용해서 검증이 필요한 컨트롤러에 삽입
export const checkObjectId = (ctx, next) => {
    const {id} = ctx.params;
    if (!ObjectId.isValid(id)) {
        ctx.status = 400;
        return;
    }
    return next();
}

posts.get('/:id', postCtrl.checkObjectId, postCtrl.remove);

22.9.2 Request Body 검증

//Joi 설치
yarn add joi

22.10 페이지네이션 구현

22.10.1 가짜 데이터 생성하기
22.10.2 포스트를 역순으로 불러오기
22.10.3 보이는 개수 제한
22.10.4 페이지 기능 구현
22.10.5 마지막 페이지 번호 알려 주기
22.10.6 내용 길이 제한

 

+ Recent posts