개요 Docker Compose로 DB 인스턴스 생성, 실행 CI/CD 환경 구성을 위해 Docker Compose를 활용해 DB 인스턴스를 초기화하는 과정이 왜 필요한지에 대한 개요 및 세부 설명은 앞선 포스트를 참고 바란다. 해당 포스트는 docker-compose-db.yml 에 대한 내용과 docker-compose-db.yml을 활용해 Docker Container를 실행하는 내용을 포함하고 있다. Docker Compose로 Database 인스턴스 구성 (개요, Oracle)...
a02. React JS 설치 및 앱 생성 먼저 리액트 공식 페이지에 진입하고 중앙의 시작하기 버튼을 클릭한다. 리액트 공식 페이지 우측 네비게이션 메뉴에서 새로운 React 앱 만들기를 클릭한다. React JS Application을 생성하기 위해서는 Node JS와 npm 설치가 필요하다. 공식 페이지에서는 현재 React JS 공식 페이지에서는 Node JS 14.0.0 이상, npm 5.6을...
a01. React JS를 시작하기 앞서 Frontend 기술에 흥미가 생긴지는 언젠지 제대로 기억나지 않을만큼 오래된 것 같다. 신입생 시절에는 고작 HTML만 배운 신입생이 몇줄 끄적거린 태그들이 브라우저에 즉시 반영되는게 좋았고, 복학생 때는 서버와 클라이언트라는게 뭔지 알게되면서 데이터의 흐름이 어플리케이션으로 구현되는 것이 좋았다. 취업준비와 현업에 와서는 페이지를 매번 로드하지 않는 SPA(Single Page...
개요 Java 기반 서버 프로젝트 개발 시 많은 개발자들이 패키지 구조를 스프링 웹 계층형 구조를 기반으로 구성할 것이다. 이러한 패키징 방식은 Controller, Service, Repository, Domain 과 같이 각각의 웹 계층을 대표 혹은 구성하는 클래스로 이루어진다. 프로젝트 패키지 구조에 관심을 갖고 관련 내용을 찾기 전에는 이러한 사실 조차 몰랐었고, 이러한 서버...
클라이언트 실행 NodeJS, npm 설치는 기타 오픈소스가 많으므로 생략하고 진행한다. /reddit-clone-app/client 경로에서 다음을 수행. npm 모듈 설치 ~$ npm install NextJS App Build ~$ npm run build:prod NextJS App Start ~$ npm run start:prod PM2를 사용한 Client 실행 [PM2를 사용하는 이유] Node.js 애플리케이션을 계속 유지하기 위해서. node.js가 다운되면 PM2는 다운타임...
실행 환경에 따른 env 파일 생성 env-cmd 패키지를 이용해서 Application 실행 환경에 따라 .env파일을 따로 정의해서 사용할 수 있다. 기존의 reddit-clone-app\server\.env 파일은 개발 환경에서 사용하기 위해 .env.development 파일로 파일명을 변경해준다. 이후 reddit-clone-app\server\.env.production 파일을 생성한다. 개발 환경 => .env.development 운영 환경 => .env.production reddit-clone-app\server\.env.production 파일의 내용은 아래와 같다. 현재 사용하고 있는...
실행 환경에 따른 env 파일 생성 env-cmd 패키지를 이용해서 Application 실행 환경에 따라 .env파일을 따로 정의해서 사용할 수 있다. 기존의 reddit-clone-app\client\.env 파일은 개발 환경에서 사용하기 위해 .env.development 파일로 파일명을 변경해준다. 이후 reddit-clone-app\client\.env.production 파일을 생성한다. 개발 환경 => .env.development 운영 환경 => .env.production reddit-clone-app\client\.env.production 파일의 내용은 아래와 같다. 현재 사용하고 있는...
AWS EC2 인스턴스 생성 AWS 계정을 생성하고 EC2 인스턴스를 프리티어(무료)로 사용하는 방법에 대해서는 사전에 블로그에 작성한 포스트를 참고하면 된다. 해당 포스트에서는 아마존 리눅스 2 이미지를 사용해 서버를 구성했으므로 필요에 따라 다른 이미지를 선택해도 무방하다. 무료로 AWS EC2 인스턴스 사용하기(프리 티어) AWS에 Docker 설치 내가 사용하는 AWS 서버 OS 이미지는 아마존...
개요 계정 정보가 있는 보통의 웹 어플리케이션은 DBMS를 필수적으로 사용하게 된다. 신규 기능이나, 제품 구조가 변경되어야 하는 개발 요구사항이 있다고 가정해보자. 이 때 제품의 버전이나 브랜치 단위로 DB 테이블 스키마가 변경될 수 있으며, 서버 설치 시 필수적인 초기 데이터 또한 추가/수정/삭제될 수 있다. CI/CD 환경을 구성할 때 Server, Front 소스만...
개요 계정 정보가 있는 보통의 웹 어플리케이션은 DBMS를 필수적으로 사용하게 된다. 신규 기능이나, 제품 구조가 변경되어야 하는 개발 요구사항이 있다고 가정해보자. 이 때 제품의 버전이나 브랜치 단위로 DB 테이블 스키마가 변경될 수 있으며, 서버 설치 시 필수적인 초기 데이터 또한 추가/수정/삭제될 수 있다. CI/CD 환경을 구성할 때 Server, Front 소스만...
개요 웹 어플리케이션은 크게 두 프로젝트(Server, Front)로 구성되어있을 가능성이 높다. Server는 말 그대로 클라이언트 요청을 처리하고 Database 서비스를 처리하는 프로젝트이고, Front는 브라우저 위에서 동작하는 화면으로 어플리케이션 클라이언트 역할을 수행하게된다. 내가 맡고 있는 제품(웹앱)을 기준으로 CI/CD 환경을 구성하는 방법에 대해 정리할 예정이다. Docker Docker에 대한 설명은 이전 포스트를 참고하기 바람. Docker를...
인덱스 구조 칼럼의 값, ROWID가 항상 정렬된 상태를 유지 칼럼의 값은 NULL을 제외한 모든 값 보유 ROWID를 저장하고 있으므로 테이블의 불필요한 I/O를 줄일 수 있음 Root, Branch, Leaf Block을 이용하여 Tree 구조로 관리 테이블 데이터의 데이터 파일 정보 확인 SELECT employee_id, last_name, commission_pct, rowid, -- 데이터 파일 번호 DBMS_ROWID.ROWID_RELATIVE_FNO(rowid) AS...
실행 계획 (Execution Plans) SQL을 실행하기 위한 처리 순서도 Optimizer에 의해 생성되며 Shared Pool의 Library Cache에 저장 문장 실행 전 예측되는 실행 계획은 PLAN_TABLE에 저장 실제 사용된 실행 계획이 아닌 현재 시점의 예상되는 실행 계획을 PLAN_TABLE에 저장 함 $ORACLE_HOME/rdbms/admin/utlxplan.sql 파일 이용하여 PLAN_TABLE 생성 가능 (10g DB부터는 기본 제공) DBMS_XPLAN.DISPLAY 이용하여...
SQL문 구문 분석 : 개요 Parse : 구문 분석 (실행 계획 확보) 문법 검사 의미 분석 (객체, 권한 유무) IF 동일 문장 사용 여부 TRUE : 실행 계획 재사용 FALSE : 실행 계획 생성 / 저장 Bind : 바인드 변수 사용 시 바인드 변수에 값 입력 SELECT * FROM EMP...
Oracle 데이터베이스 서버 구조 서버 프로세스 : User 프로세스의 요청을 수행하는 서버PC의 프로세스. 실제 DB가 설치된 서버 프로세스를 의미한다. 유저 프로세스 : 서버 프로세스와의 커넥션을 통해 사용자가 DB에 접근할 수 있도록 해주는 프로세스. SGA(System Global Area) : 모든 사용자가 공유하여 사용하는 메모리 공간. PGA(Program Global Area) : 사용자마다 공유하지 않고...
개요 데이터베이스 SQL 성능 고도화 튜닝 기간: 2022년 12월 07일 ~ 12월 10일 (09:00 ~ 18:00, 점심 12:00 ~ 13:00) 교수: 류청하 chongharyu@itnvalue.co.kr 강의 수단, 링크 줌 https://us06web.zoom.us/j/87815058511?pwd=empXWU9YRWx4NUIzQWo1b0djSlNiZz09 공유폴더 https://drive.google.com/drive/folders/1TqKqs4biE26VbGDnMAx9dn3c5HxinFff?usp=sharing 실습환경 구성 Oracle Database 19c Standard Editition (Oracle Cloud Database) SQL Developer 사용 실습계정 https://docs.google.com/spreadsheets/d/16xAqOFDKSnO7Co6Mf5BS3-69lGAGFcWSqRUs16XuOMU/edit?usp=sharing 다운로드 https://drive.google.com/drive/folders/14CO1D_AIUgdh8KCIz7TbIGaiax2XOxAr?usp=sharing 다운받은 SQL Developer는...
유저 페이지 완성 UI 유저 페이지 생성 유저 페이지의 context path는 /u/[username]의 형태를 갖도록 한다. 이를 위해 reddit-clone-app\client\src\pages\u\[username].tsx 파일을 생성하고 아래 내용을 입력한다. import UserPage from 'react' const UserPage = () => { const router = useRouter(); // 사용자 이름을 URL에서 가져옴 const username = router.query.username; // swr 요청을 사용해...
Intersection observer 화면에 DOM 엘리먼트가 교차되는 것을 감시하고 개발자가 정의한 부분만큼 교차되었을 때 원하는 로직을 실행하기 위해 사용한다. threshold는 DOM엘리먼트가 뷰포트와 교차된 비율을 의미하며 해당 비율만큼 교차되었을 때 구문이 실행됨을 의미한다. 마지막 포스트가 화면에 교차되었을 때 다음 포스트 가져오기 reddit-clone-app\client\src\pages\index.tsx 파일에 아래 내용을 추가한다. ...생략 // 현재 감시중인 ELEMENT의 id값...
useSWRInfinite 이란 [useSWRInfinite 문서] https://swr.vercel.app/ko/docs/pagination#useswrinfinite SWR은 페이지 매김 및 무한 로딩과 같은 일반적인 UI 패턴을 지원하기 위해 전용 API useSWRInfinite를 제공한다. 무한 스크롤 UI패턴의 경우 지속적으로 다음 페이지 데이터를 가져오기 위한 용도로 사용된다. [useSWRInfinite 반환 값] data : 요청을 통해 각 페이지 응답 값의 배열 error : useSWR의 error와 동일...
포스트 나열하기 커뮤니티 상세 페이지 진입 시 해당 커뮤니티에 작성된 포스트들을 나열하기 위해 커뮤니티 상세 페이지 reddit-clone-app\client\src\pages\r\[sub].tsx 파일에 아래 내용을 추가한다. ...생략 import PostCard from '../../components/PostCard'; ...생략 let renderPosts; if(!sub) { // 커뮤니티 존재하지 않을 때 renderPosts = <p className='text-lg text-center'>로딩중...</p> } else if(sub.posts.length === 0) { // 포스트가 없을...
투표 적용 시 즉시 업데이트 코멘트와 마찬가지로 useSWR 사용 구문에서 mutate를 가져오고 이를 투표 요청하는 vote함수에서 실행해주면 된다. reddit-clone-app\client\src\pages\r\[sub]\[identifier]\[slug].tsx 파일에 아래 내용을 추가해 본다. ...생략 const { data: post, error, mutate } = useSWR<Post>(identifier && slug ? `/posts/${identifier}/${slug}` : null) ...생략 const vote = async (value: number, comment?:Comment) => {...
포스트, 코멘트 투표 UI 포스트와 코멘트 투표 완성 UI는 아래와 같다 포스트, 코멘트 투표 UI 템플릿 작성 포스트 내용 페이지 내 포스트, 코멘트 투표 UI를 추가해야 하므로 reddit-clone-app\client\src\pages\r\[sub]\[identifier]\[slug].tsx 파일에 아래 내용을 추가한다. [포스트 투표 부분] ...생략 {post && ( <> <div className="flex"> {/* 투표 가능 부분 */} <div className="flex-shrink-0 w-10...
useSWR mutate 란? 캐시 된 데이터를 개발자가 원하는 시점에서 갱신하기 위한 함수이다. useSWRConfig() hook으로부터 mutate 함수를 얻을 수 있으며, mutate(key)를 호출하여 동일한 키를 사용하는 다른 SWR hook*에게 갱신 메시지를 전역으로 브로드캐스팅할 수 있습니다. 포스트 코멘트 작성에서 mutate 적용 현재 댓글 작성 후 작성한 코멘트가 즉시 화면에 갱신되지 않는다. 새로고침을 수행하면...
코멘트 리스트 가져오기 포스트 내용 페이지 진입 시 SWR을 사용해서 해당 포스트에 작성된 코멘트를 가져온다. reddit-clone-app\client\src\pages\r\[sub]\[identifier]\[slug].tsx 파일에 아래 내용을 추가한다. ...생략 const PostPage = () => { const router = useRouter(); const { identifier, sub, slug } = router.query; const { authenticated, user } = useAuthState(); const [ newComment, setNewComment...
포스트 댓글 UI 로그인 된 상태에서는 댓글 작성이 가능하도록, 로그인이 되지 않은 상태에서는 댓글 작성을 위해 로그인 해주세요 메시지를 출력한다. 완성된 UI는 아래와 같다. 포스트 댓글 UI 템플릿 작성 댓글은 포스트 내용 페이지에 진입 시 작성할 수 있어야 하므로 reddit-clone-app\client\src\pages\r\[sub]\[identifier]\[slug].tsx 파일에 템플릿을 아래와 같이 추가한다. ...생략 // 로그인 여부에 따라...
포스트 페이지 결과 UI 포스트 페이지 생성 포스트 페이지의 context path는 /r/{SubName}/{identifier}/{slug}의 형태를 띌 것이므로 reddit-clone-app\client\src\pages\r\[sub]\[identifier]\[slug].tsx 파일을 생성하고 아래 내용을 입력한다. import axios from "axios"; import { useRouter } from "next/router" import useSWR from 'swr' import { Post } from "../../../../types"; const PostPage = () => { const router =...
포스트 Create 페이지 기능 앞서 생성했던 포스트 Create 생성 페이지에서 생성하기 버튼을 통해 form 태그의 onSubmit 이벤트가 발생했을 때 동작하게 될 submitPost 함수를 아래와 같이 추가한다. reddit-clone-app\client\src\pages\r\[sub]\create.tsx ...생략 // 페이지 URL내의 커뮤니티 이름(subName)을 사용하기 위해 추가 const router = useRouter(); const { sub: subName } = router.query; const submitPost= async...
포스트 Create 페이지 UI 포스트 Create 페이지 UI 구현 포스트 Create 페이지의 context path를 /r/{커뮤니티명}/create 으로 해주기 위해 reddit-clone-app\client\src\pages\r\[sub]\create.tsx 경로에 파일을 생성한다. 아래의 내용을 입력한다. import axios from 'axios'; import { GetServerSideProps } from 'next'; import React, { useState } from 'react' const PostCreate = () => { // 포스트...
사이드 바 컴포넌트 생성, 적용 reddit-clone-app\client\src\components\SideBar.tsx 경로에 파일을 생성하고 아래 내용을 입력한다. import dayjs from 'dayjs'; import Link from 'next/link'; import React from 'react' import { useAuthState } from '../context/auth'; const SideBar = ({ sub }) => { const { authenticated } = useAuthState(); return ( <div className='hidden w-4/12 ml-3...
ref를 사용하여 이미지 올리기 먼저 DOM상에 이미지 파일을 업로드하기 위해 reddit-clone-app\client\src\pages\r\[sub].tsx 파일에 아래 내용을 추가해준다. import React, { ChangeEvent, useEffect, useRef, useState } from 'react'; ...생략 const fileInputRef = useRef<HTMLInputElement>(null); ...생략 return ( <> {sub && <> <div> // 추가 부분 <input type="file" hidden={true} ref={fileInputRef} onChange={uploadImage} /> ...생략 fileInputRef :...
커뮤니티 상세 페이지 UI 템플릿 reddit-clone-app\client\src\pages\r\[sub].tsx 경로의 파일을 생성하고 아래 내용을 입력한다. import axios from 'axios' import { useRouter } from 'next/router'; import React from 'react' import useSWR from 'swr'; const SubPage = () => { const fetcher = async (url: string) => { try { const res = await...
SWR (Stale-while-revalidate) 란? 데이터를 가져오기 위한 React Hook 라이브러리이다. SWR은 원격 데이터를 가져올 때 캐싱된 데이터가 있으면 그 데이터를 먼저 반환(stale)한 다음 가져오기 요청(revalidate)을 보내고, 마지막으로 최신 데이터와 함께 제공하는 라이브러리입니다. **캐시 데이터를 제공함으로써 사용자에게 응답속도가 빠르다 ** SWR 사용법 res = useSWR() 형태로 사용하며 React Hook으로, 주 인자로 key와...
커뮤니티 리스트 UI reddit-clone-app\client\src\pages\index.tsx 파일을 아래와 같이 수정한다. import type { NextPage } from 'next' import Link from 'next/link' const Home: NextPage = () => { return ( <div className='flex max-w-5xl px-4 pt-5 mx-auth'> {/* 포스트 리스트 */} <div className='w-full md:mr-3 md:w-8/12'></div> {/* 사이드바 */} <div className='hidden w-4/12 ml-3 md:block'>...
상단바 UI 생성 import axios from 'axios'; import Link from 'next/link' import React from 'react' import { useAuthDispatch, useAuthState } from '../context/auth' const NavBar: React.FC = () => { const { loading, authenticated } = useAuthState(); const dispatch = useAuthDispatch(); const handleLogout = () => { axios.post("/auth/logout") .then(() => {...
인증에 따른 제한 현재 로그인 전 브라우저 쿠키에 token이 없는 상태로 /subs/create 페이지에 접속이 가능하다. 인증되지 않은 사용자가 커뮤니티 생성 페이지에 접근이 가능하다는 것이다. 이러한 문제점을 해결하기 위해 Next.js의 getServerSideProps를 사용한다. reddit-clone-app\client\src\pages\subs\create.tsx 파일에 아래 내용을 추가한다. ...생략 // 서버 사이드 렌더링으로 서버 요청 시 데이터를 불러온다 export const getServerSideProps: GetServerSideProps...
State 생성 reddit-clone-app\client\src\pages\subs\create.tsx 파일에서 이전에 UI를 위한 템플릿을 작성했다. UI의 기능 구현을 위해 State를 선언하고 필요 모듈을 import한다. // 필요 모듈 선언 useRouter, useState, axios import axios from 'axios'; import { useRouter } from 'next/router'; import React, { FormEvent, useState } from 'react' import InputGroup from '../../components/InputGroup' const SubCreate =...
커뮤니티 생성 페이지 UI 현재 개발하고 있는 Reddit-clone-app에서 커뮤니티를 생성하는 페이지의 UI는 아래와 같다. 커뮤니티 생성 페이지 UI 파일 생성 reddit-clone-app\client\src\pages\subs\create.tsx 폴더 구조와 파일을 생성하고, 아래 소스를 입력한다. 구분 폴더명이 subs인 이유는 Reddit 서비스에서 커뮤니티를 Subreddits 라고 지칭하기 때문이다. import React from 'react' import InputGroup from '../../components/InputGroup' const SubCreate =...
개요 진행중인 사이드 프로젝트의 배포 관리를 위해 AWS(Amazon Web Service) EC2 인스턴스를 생성할 이유가 생겼다. 현재 회사에서도 기업용 AWS를 사용중이고 6개의 EC2 인프라를 관리중이지만 직접 무료버전의 개인용 인스턴스는 생성해본 바는 없었다. 업무적으로도 AWS Lightsail (경량 인스턴스)만 생성해봤고, 담당자에게 요청한 스펙의 인스턴스를 제공 받아 사용했을 뿐 직접 인스턴스를 생성한 적은 없기에...
사용자 정보를 Context에 담아 사용하는 이유 React Context를 사용하지 않고 User정보를 각각의 React 컴포넌트에서 사용하기 위해서는 컴포넌트 간 User 정보를 주고 받는 작업이 매번 이루어진다. 그러나 React Context에서 User 정보를 관리하게 되면 컴포넌트 간 데이터를 주고 받을 필요 없이 로그인 후 언제든 React Context에서 User 정보를 사용 가능하다. React Context...
로그인 후 Client Cookie 처리 로그인 요청 후 response 쿠기에 정상적으로 jwt 토큰이 담겨 오는 것을 확인했다. 그러나 개발자도구 > Application 탭 내 jwt 토근이 저장되지 않는다. 이유는 Server에서 로그인 후 response 객체에 쿠키를 Set 하는 과정에서 옵션넣어줘야 한다. reddit-clone-app\server\src\routes\auth.ts 파일에 아래 내용을 추가한다. ...생략 const login = async (req...
로그인 페이지 기능 생성 reddit-clone-app\client\src\pages\login.tsx 파일에 아래의 내용을 추가한다. import Axios from 'axios'; ...생략 import React, { FormEvent, useState } from 'react' ...생략 const login = () => { // State 생성 const [username, setUsername] = useState(""); const [password, setPassword] = useState(""); const [errors, setErrors] = useState<any>({}); // handleSubmit 함수...
로그인 페이지 UI 생성 reddit-clone-app\client\src\pages\login.tsx 파일을 생성하고 아래의 내용으로 편집한다. import React from 'react' import InputGroup from '../components/InputGroup' const Login = () => { return ( <div className='bg-white'> <div className='flex flex-col items-center justify-center h-screen p-6'> <div className='w-10/12 mx-auto md:w-96'> <h1 className='mb-2 text-lg font-medium'>로그인</h1> <form onSubmit={handleSubmit}> <InputGroup placeholder='Username' value={username} setValue={setUsername} error={errors.username}...
register.tsx 코드 작성 import Link from 'next/link' import React, {useState} from 'react' import InputGroup from '../components/InputGroup' const Register = () => { const [email, setEmail] = useState(""); const [username, setUsername] = useState(""); const [password, setPassword] = useState(""); const [errors, setErrors] = useState<any>({}); return ( <div className="bg-white"> <div className='flex flex-col items-center...
회원가입 UI 페이지 완성 모습 register.tsx 파일 생성 reddit-clone-app/client/src/pages/register.tsx 파일을 생성한다. UI를 다음과 같이 작성한다. import Link from 'next/link' import React from 'react' const register = () => { return ( <div className="bg-white"> <div className='flex flex-col items-center justify-center h-screen p-6'> <div className='w-10/12 mx-auto md:w-96'> <h1 className='mb-2 text-lg font-medium'>회원가입</h1> <form> <button...
Tailwind CSS 적용을 위한 모듈 설치하기 reddit-clone-app/client 경로에서 npm 모듈 설치 npm i -D postcss-preset-env tailwindcss Tailwind 설정 파일 생성 reddit-clone-app/client 경로 터미널에서 아래 명령어 입력 npx tailwind init 아래와 같이 tailwind.config.js 파일이 생성됩니다. PostCSS 빌드 적용을 위한 postcss 설정 파일 생성 reddit-clone-app/client 경로 터미널에서 아래 명령어 입력 touch postcss.config.js...
Comment 기능 화면 Comment 컬럼 Comment Entity 작성 import { Exclude, Expose } from 'class-transformer'; import { BeforeInsert, Column, Entity, Index, JoinColumn, ManyToOne, OneToMany } from 'typeorm'; import { makeId } from '../utils/helpers'; import BaseEntity from './Entity'; import Post from './Post'; import { User } from './User'; import Vote from...
Vote 기능 화면 Vote 테이블 컬럼 Vote 엔티티 작성 import { Column, Entity, JoinColumn, ManyToOne } from "typeorm" import BaseEntity from './Entity'; import Post from "./Post"; import { User } from "./User"; @Entity("votes") export default class Vote extends BaseEntity { @Column() value: number; @ManyToOne(() => User) @JoinColumn({name: "username", referencedColumnName: "username"})...
포스트 테이블 컬럼 포스트 엔티티 작성 import { Exclude, Expose } from "class-transformer"; import { BeforeInsert, Column, Entity, Index, JoinColumn, ManyToOne, OneToMany } from "typeorm"; import { makeId, slugify } from "../utils/helpers"; import BaseEntity from "./Entity"; import Sub from "./Sub"; import { User } from "./User"; import Vote from "./Vote";...
URI, URL, URN 란? URL과 URI의 차이점 URL은 어떻게 리소스를 얻을 것이고 어디에서 가져와야 하는지 명시하는 URI이다. URN은 리소스를 어떻게 접근할 것인지 명시하지 않고 경로와 리소스 자체를 특정하는 것을 목표로 하는 URI이다.
개요 엔티티를 생성할 때 상태뿐 아니라 행위까지 엔티티 내 정의하여 행위의 반환값까지 프론트엔드에서 사용할 수 있게 한다. 이를 풀어서 설명하면 데이터베이스에서 User객체를 조회할 때 아래 User 클래스의 행위인 getter : name(), getFullName() 값을 함께 조회하게 된다. 마찬가지로 조회 시 제외해야할 행위에 대해 정의할 수 있다. import { Expose } from...
class-tranformer 모듈이란? Class-transformer를 사용하면 Plain object를 클래스 인스턴스로 변환할 수 있다. class-transformer를 이용해서 자바스크립트 리터럴 객체를 클래스의 인스턴스로 변경해주면 좋은 점 아래와 같은 자바스크립트 객체가 있다고 가정한다. 이 객체들의 firstName과 lastName을 합치고자할 때를 예를 들어 보자 class-transformer 없이 구현 toFullName(user) 함수를 정의하고 FullName 반환값을 구하는 과정이 필요하다. class-transformer 사용해서 구현...
테이블 컬럼 엔티티 작성 import { Expose } from "class-transformer"; import { Column, Entity, Index, JoinColumn, ManyToMany, ManyToOne, OneToMany } from "typeorm"; import BaseEntity from './Entity'; import Post from "./Post"; import { User } from "./User"; @Entity("subs") export default class Sub extends BaseEntity { @Index() @Column({ unique: true }) name:...
User 테이블 컬럼 User 엔티티 작성 import { IsEmail, Length } from "class-validator" import { Entity, Column, Index, OneToMany, BeforeInsert } from "typeorm" import BaseEntity from './Entity'; import bcrypt from 'bcryptjs'; import Vote from "./Vote"; import Post from "./Post"; @Entity("users") export class User extends BaseEntity { @Index() @IsEmail(undefined, { message:...
레딧 앱 E-R Diagram 강의의 주제인 레딧 앱의 DB E-R Diagram이다. Entity를 생성하는 이유 ORM의 사용 없이 DB 테이블을 생성하기 위해서는 DDL (Database Definition Language)를 사용하여 일일히 테이블을 생성해줘야하지만, TypeORM을 사용할 때는 Entity Class가 데이터 베이스 테이블로 변환되기 때문에 Class를 생성한 컬럼을 정의해주면 된다. E-R Diagram와 일치하는 Entity 생성 Users...
TypeORM 이란? TypeORM은 Node.js에서 실행되고 Typescript로 작성된 객체 관계형 매퍼 라이브러리다. TypeORM은 MySQL, PostgreSQL, MariaDB, SQLite, MS SQL Server, Oracle, SAPHana 및 WebSQL과 같은 여러 데이터베이스를 지원한다. ORM (Object Relational Mapping) 이란? 객체과 관계형 데이터베이스의 데이터를 자동으로 변형 및 연결하는 작업입니다. ORM을 이용한 개발은 객체와 데이터베이스의 변형에 유연하게 사용할 수...
필요한 모듈 pg Postgresql 데이터베이스와 인터페이스하기 위한 Node.js 모듈 모음이다. 일련의 명령어나 함수, 옵션, 프로그램 언어에 의해 제공되는 명령어나 데이터를 표현하기 위한 다른 방법들로 구성되는 프로그래밍 인터페이스. 간단하게 말해서 Postgresql 데이터베이스를 Node.js에서 사용할 수 있게 도와주는 모듈. callbacks, promises, connecting pooling, C/C++, bindings 등등 typeorm typescript 및 javascript(ES5, ES6, ES7,...
개요 처음엔 이력서 양식으로 Jekyll 블로그 내 하나의 페이지를 구성하고자 했다. 블로그 URL만으로 내 정보와 이력을 조회할 수 있어 접근성, 준비성 면에서 좋겠다고 생각을 했다. 개인정보가 포함된 페이지이다 보니 누구에게나 공개할 수는 없었고 패스워드 모달을 통해 접근을 제한하고자 했으나, 서버를 두지 않는 정적 페이지(Jekyll) 특성상 브라우저에 패스워드를 저장하지 않고는, 인증...
docker-compose를 사용해 Postgresql 컨테이너 실행 docker-compose란 Docker 이미지를 이용해 컨테이너를 실행하는 것에 더해 docker-compose.yml, Dockerfile 등의 설정파일을 사용하여 host/guest 포트 설정, volume 매핑, 환경변수 설정, 컨테이너 실행 후 shell 수행 등 다양한 설정을 추가할 수 있는 Docker의 기능이다. docker-compose.yml 파일 생성 reddit-clone-app/ 경로에 docker-compose.yml 파일 생성하여 아래 내용 기입한다. version:...
Next.js App 생성 Reddit 프로젝트 폴더 구조를 다음과 같이 생성한다. reddit-clone-app client server Visual Studio Code (편집기)를 사용해 client 폴더 경로를 열고, 터미널을 실행한다. 아래 명령어를 사용해 Next.js App을 client 폴더에 생성한다. npx create-next-app@latest --typescript ./ Node.js 백엔드 서버 생성 Visual Studio Code (편집기)를 사용해 server 폴더 경로를 열고, 터미널을...
Node JS 란? 리액트 프로젝트를 만들기 위해서 Node.js와 npm의 선 설치가 필요하다. Node.js를 받을 때 npm도 같이 설치된다. Node.js란 크롬 V8 자바스크립트 엔진으로 빌드한 자바스크립트 런타임으로서, 웹 브라우저 환경이 아닌 곳에서도 자바스크립트를 사용하여 연산할 수 있다. React 설치 시 Node.js가 필요한 이유 리액트 앱은 웹 브라우저에서 실행되는 코드여서 Node.js와 직접적인...
getStaticProps를 이용한 포스트 리스트 나열 props로 포스트 데이터 가져오기 index.tsx // getStaticProps 의 반환값(포스팅 md파일 데이터)을 빌드 시 가져옴 const Home = ({allPostsData}: { allPostsData: { date: string title: string id: string }[] }) => { return ( <HTML> ... </HTML> ) } export default Home // lib/post.js 에서 생성한...
Type Assertion Typescript가 추론한 타입을 얼마든지 변경 가능하다. 이 때 사용되는 매커니즘이 Type Assertion이다. 개발자가 컴파일러에게 내가 너보다 타입을 더 잘 알고있다. 의심하지 마라고 말하는 것과 같다. Type Assertion을 사용하면 값의 타입을 설정하고, 컴파일러에 이를 유추하지 않도록 지시할 수 있다. 아래의 경우 컴파일러는 foo type이 속성이 없는 {} 라고 추론하므로...
Type Annotaton, Type Inference Type Annotaton : 개발자가 타입을 타입스크립트에게 직접 말해주는 것 var a: nubmer = 10; Type Inference : 타입 스크립트가 알아서 타입을 추론하는 것 var a= 10; var : 선언 a : 변수 : : Annotate number : Data Type 10 : 초기화 타입을 추론하지 못해서 Annotation을...
Typescript의 Type이란? 그 value가 가지고 있는 프로퍼티나 함수를 추론할 수 있는 방법이다. “apple” 두 가지로 말할 수 있음 String 문자열 value인데 문자열이 가지는 프로퍼티, 메소드를 가지고 있는 value 자바스크립트에서 문자열 Properties + Methods let string: string; // 프로퍼티 'string'.length // 여러 메소드 존재 'string'.replace(); 'string'.split(); ... Properties string.length는 문자열의 속성인...
Markdown 파일이란? (.md 파일) Markdown은 텍스트 기반의 마크업 언어로 쉽게 쓰고 읽을 수 있으며 HTML로 변환이 가능하다. 특수 기호와 문자를 이용한 매우 간단한 구조의 무넙을 사용하여 웹에서도 보다 빠르게 컨텐츠를 작성하고 직관적으로 인식할 수 있다. 마크다운이 최근 각광받기 시작한 이유는 깃헙에서 사용하는 README.md 덕분이다. 마크다운을 통해서 설치방법, 소스 코드 설명,...
Typescript가 나오게 된 배경 Javascript는 본래 클라이언트 측 언어로 도입되었다. 그런데 Node.js의 개발로 인해 Javascript를 클라이언트 측 뿐 아니라 서버 기술로도 활용가능해졌다. 그러나 코드가 커지고 복잡해져 코드를 유지관리/재사용하기 어려워지고, Type 검사 및 컴파일 시 오류 검사의 기능을 수용하지 못하기 때문에 Javascript는 본격적인 서버 기술로 Enterprise, 기업 수준에서 성공하지 못하게 되었다....
Data Fetching 보통 React JS에서 데이터를 가져올 때 useEffect 안에서 가져온다. 하지만 Next JS 에서는 다른 방법을 사용해서 가져오는데 무엇인지 알아보자. getStaticProps Static Generation으로 빌드(build)할 때 데이터를 불러온다. (데이터를 미리 만들어 둠) getStaticProps를 사용해야 할 때 페이지를 렌더링하는 데 필요한 데이터. 사용자의 요청보다 먼저 build 시간에 필요한 데이터를 가져올 때...
Next JS 와 Pre-rendering Next JS는 모든 페이지를 pre-rendering한다. pre-rendering한다는 의미는 모든 페이지를 위한 HTML을 Client 사이드에서 Javascript로 처리하기 전, 사전에 생성한다는 것을 의미한다. 이렇게 하기 때문에 SEO(Search Engine Obtivization), 검색 엔진 최적화에 유리. Pre-rendering 테스트 브라우저에서 Javascript 사용을 하지 못하도록 만들면 Client 사이드(브라우저)에서 Pre-rendering한 HTML을 확인할 수 있다. 1....
Next JS 기본 파일 구조 npx create-next-app@latest --typescript 명령을 사용하여 Next JS app을 생성하면 아래와 같은 폴더 구조를 갖게된다. Next JS App의 기본 폴더 구조에 대해 알아보자. pages 폴더 pages 폴더 내에 Application 페이지들을 생성. index.tsx가 처름 ”/”(루트) 페이지가 된다. _app.tsx는 공통되는 레이아웃을 작성. (header, footer와 같은) URL을 통해 특정...
Next JS란? React의 SSR(Server Side Rendering)을 쉽게 구현할 수 있게 도와주는 간단한 프레임워크. (리액트는 라이브러리) React로 개발할 때 SPA(Single Page Application)을 이용하여 CSR(Client Side Rendering)을 하기 때문에 좋은 점도 있지만 단점도 있는데 그 부분이 바로 검색 엔진 최적화(SEO) 부분이다. Client Side Rendering을 하면 첫페이지에서 빈 html을 가져와 JS파일을 해석하여 화면을...
jekyll 테마를 커스텀 하는 이유 블로그를 시작하기로 마음을 먹고 마음에 드는 Jekyll 테마를 선택했다. 테마 개발자에게는 미안한 말이지만 꽤 많은 부분에서 100% 만족스럽지는 않았다. 그래서 나는 내가 직접 UI 디자인 커스텀이나, 미비한 기능을 보완하거나, 없는 기능을 추가하기로 했다. 이전 포스팅에서 사용했던 Github Repository와 Github Pages를 활용해 테마를 수정할 수 있는...
개인 블로그를 생성한 이유 내가 IT분야에서 첫 발을 내딛은 회사는 솔루션 기반 사업을 주로 수행하는 기업이다. 신입 JAVA 개발자 라는 모호한 기준 아래 지원했던 나의 현재 롤은 아이러니하게도 개발자와는 다소 거리가 있는 포지션이다. 솔루션 엔지니어, 서버/웹 QA, 서버 인프라 담당자 나의 바람인 개발자와는 다른 업무를 수행한 지 벌써 2년을 채워...
This post is written by Std Runner. 이 포스팅은 Std Runner가 작성했습니다. This post is written by Std Runner. This post is written by Std Runner. This post is written by Std Runner. This post is written by Std Runner. This post is written by Std Runner. This post is...
View the raw file used to generate this page to use as an example. @requires_authorization def somefunc(param1='', param2=0): r'''A docstring''' if param1 > param2: # interesting print 'Gre\'ater' return (param2 - param1 + 1 + 0b10l) or None class SomeClass: pass >>> message = '''interpreter ... prompt''' In line code...
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce bibendum neque eget nunc mattis eu sollicitudin enim tincidunt. Vestibulum lacus tortor, ultricies id dignissim ac, bibendum in velit. Proin convallis mi ac felis pharetra aliquam. Curabitur dignissim accumsan rutrum. In arcu magna, aliquet vel pretium et, molestie et arcu. Mauris...
Getting Started Install Jekyll Fork/Clone/Download Pudhina Fresh Configure _config.yml Add posts in _posts, add projects in _data/projects.yml and, customize the main page index.html Run bundle exec jekyll serve to test out the site at localhost:4000 Settings in _config.yml This is the file where configurations affecting the whole site live. _config.yml...
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce bibendum neque eget nunc mattis eu sollicitudin enim tincidunt. Vestibulum lacus tortor, ultricies id dignissim ac, bibendum in velit. Proin convallis mi ac felis pharetra aliquam. Curabitur dignissim accumsan rutrum. In arcu magna, aliquet vel pretium et, molestie et arcu. Mauris...
This post was originally posted on Apr 1st, 2020 but updated on Oct 25th, 2020 so this information is shown in the post meta.