연산자연산자는 정적인 데이터들을 유기적으로 행동하게 하여 새로운 가치를 창출해 낸다.산술 연산자사칙 연산을 다루는 연산자이다.종류설명+왼쪽과 오른 쪽에 있는 값을 더한다.-왼쪽 값에서 오른쪽 값을 뺀다.*왼쪽 값과 오른쪽 값을 곱한다./왼쪽 값을 오른쪽 값으로 나눈다.%왼쪽 값을 오른쪽 값으로 나눈 나머지를 구한다. 대입 연산자오른쪽에 있는 값을 왼쪽에 대입하는 역할을 하며, 산술 연산자와 혼용해서 사용하기도 한다.종류설명=오른쪽 값을 왼쪽에 대입한다.+=왼쪽 값을 오른쪽 값과 더해서 다시 왼쪽 값에 대입한다.-=왼쪽 값에서 오른쪽 값을 빼고 다시 왼쪽 값에 대입한다.*=왼쪽 값에 오른쪽 값을 곱하고 다시 왼쪽 값에 대입한다./=왼쪽 값을 오른쪽 값으로 나누고 다시 왼쪽 값에 대입한다. %=왼쪽 값을 오..
라우팅 방식정적 라우팅목적지까지의 경로(혹은 다음 라우터)를 직접 입력하는 방식이다.장점: 동적 라우팅에 비해 속도가 빠르고 안정적이다.단점: 네트워크 상황의 변화를 반영하지 못하고, 네트워크 규모가 커질수록 작업량이 많아진다.동적 라우팅네트워크 상황을 반영하여 스스로 경로를 계산하고 변경하는 방식이다.장점: 네트워크 상황의 변화를 반영한다.단점: 변화에 적응할 때까지 시간이 필요하다.일반적으로는 동적 라우팅이 바람직하지만, 연결된 이웃 라우터가 하나밖에 없는 경우에는 정적 라우팅이면 충분하다. 라우팅 알고리즘원으로 표시된 것을 노드, 노드와 노드 사이를 잇는 선을 링크라고 한다.Link state 계열각 노드가 네트워크 전체의 형상과 모든 링크 비용을 파악한 후 목적지까지의 최단 경로를 계산하는 방식..
프로그래밍 언어코드를 해석하는 방식에는 두 가지가 있다. 컴파일러 언어코드 전체를 한 번에 해석하여 실행할 수 있는 파일로 변환한다. 코드를 해석하는 것을 컴파일이라고 하며, 컴파일러 언어는 컴파일 단계와 실행 단계로 분리되어 있다.장점실행할 때는 컴파일 없이 실행만 하면 되므로 코드 실행 속도가 빠르다.컴파일러 언어는 개발자가 메모리 관리와 CPU 사용 같은 HW 측면에서 더 많은 제어 권한을 가진다. 따라서 자원을 효율적으로 관리할 수 있다.단점코드에 변경 사항이 있을 때마다 빌드를 다시 해야 한다. 빌드는 소스코드를 이진코드로 변환하는 컴파일 과정과 실행 파일을 만드는 과정인 링크를 묶어 부르는 말이다.컴파일러 언어는 컴파일 시 지정된 플랫폼에 최적화되도록 만들어지기 때문에 플랫폼에 제약이 있다. ..
response format 바꾸기SQL 실행 결과의 pub_date 컬럼명을 pubDate로 바꿔준다.delete 연산자는 객체에 있는 프로퍼티를 제거해 준다.results.map(function (result) { result.pubDate = result.pub_date; delete result.pub_date;})mdn을 보면 위와 같은 설명이 있다. map()을 사용할 때 반환 값을 사용하지 않을 거면 forEach()나 for...of 루프를 사용하라는 말이다. 그래서 아래와 같이 작성했다.results.forEach(result => { result.pubDate = result.pub_date; delete result.pub_date;}..
장바구니 조회 장바구니는 로그인이 필요한 기능이다. 따라서 jwt를 확인하고, 해당 사용자의 장바구니에 있는 도서들을 응답으로 보내준다. jwt를 확인하는 부분은 carts.js에 미들웨어로 추가하였다. validateToken 함수 function validateToken(req, res, next) { const authorization = ensureAuthorization(req); if (authorization instanceof jwt.TokenExpiredError) { return res.status(StatusCodes.UNAUTHORIZED).json({ message: '로그인 세션이 만료되었습니다. 다시 로그인 하세요.' }); } else if (authorization inst..
사건의 발단 전체 도서 조회할 때 쿼리로 뭘 기준으로 정렬할 건지 입력받아서 정렬하려고 했다. 입력 가능한 기준은 최근 출판일 순, 좋아요 순, 판매량 순이다. 사건 워크벤치에서 아래 코드 실행하면 잘만 굴러간다. SELECT *, (SELECT COUNT(*) FROM likes WHERE liked_book_id = books.id) AS likes, (SELECT COUNT(*) FROM orderedBook WHERE orderedBook.book_id = books.id) AS orders FROM books ORDER BY pub_date DESC LIMIT 4 OFFSET 0; 근데 포스트맨으로 요청 날리고 응답으로 날아오는 결과 보면 정렬이 정말 전혀 안되어있다. 그냥 책 id 순서대로 보..
예외 처리 try...catch 예상하지 못한 수많은 에러를 처리하는 문법이다. try 구문의 코드를 실행하다가 에러가 발생하면 try 코드를 멈추고 catch로 빠져나간다. try 구문에서 발생하는 모든 에러는 catch에 잡힌다. try { // 코드 실행 } catch (error) { // 에러 처리 } finally { // 항상 실행되어야 하는 코드 } catch의 error 파라미터가 내장 에러 객체인 경우 name과 message 속성을 가지고 있다. name은 에러의 이름이고, message는 에러의 내용을 보여준다. try { // 코드 실행 } catch (error) { console.log(error.name); console.log(error.message); } throw 에러..
DELETE, TRUNCATE 차이 DELETE FROM 테이블명 WHERE 조건; 데이터는 지워지지만 테이블 용량은 줄어들지 않는다. 조건을 통해 원하는 데이터만 삭제할 수 있으며, 롤백이 가능하다. TRUNCATE 테이블명; 모든 행이 삭제되며 테이블이 생성되었던 최초의 상태로 되돌린다. 롤백이 불가능하다. 주문 API 구현 주문하기 items가 객체 배열에서 배열로 수정되었다. 따라서 items에 있는 id들에 대해 SELECT를 하는 코드가 추가되었고, 장바구니에서 주문된 도서를 삭제하는 코드도 추가되었다. Method POST URI /orders HTTP Status Code 성공(201) Request Body // 로그인 할 때 받은 token > header “Authorization” ..
Promise 지금까지는 콜백 함수를 통해 비동기 상황을 해결했다. 하지만 콜백 함수들이 여러 번 중첩되면 코드가 복잡해지고 가독성이 떨어지는 콜백 지옥 현상이 발생하기 때문에 Promise를 사용한다. new Promise로 프로미스 객체를 생성하고, resolve와 reject를 파라미터로 갖는 콜백 함수를 넣는다. 이 프로미스 변수에는 then과 catch 메서드가 있다. resolve가 호출되면 then이 실행되고, reject가 호출되면 catch가 실행된다. resolve와 reject에 넣어준 인수가 각각 then과 catch로 전해진다. finally 메서드는 끝나면 무조건 실행된다. const condition = true; const promise = new Promise((resolv..
Promise 지금까지는 콜백 함수를 통해 비동기 상황을 해결했다. 하지만 콜백 함수들이 여러 번 중첩되면 코드가 복잡해지고 가독성이 떨어지는 콜백 지옥 현상이 발생한다. 이 현상을 해결하기 위해 Promise를 사용한다. new Promise로 프로미스 객체를 생성하고, resolve와 reject를 파라미터로 갖는 콜백 함수를 넣는다. 이 프로미스 변수에는 then과 catch 메서드가 있다. resolve가 호출되면 then이 실행되고, reject가 호출되면 catch가 실행된다. resolve와 reject에 넣어준 인수가 각각 then과 catch로 전해진다. then이나 catch에서 다시 다른 then이나 catch를 붙일 수 있다. 이것을 promise chaining이라고 하며, 이전 ..