next-market-app으로 폴더를 생성했다.
터미널에서 CNA (맞겠지?)
npx create-next-app@latest ./
src하위에 components 폴더생성
컴포넌트를 생성하여 layout에서 import
import Navbar from '@/components/Navbar';
import할때 @가 붙는것은 alias가 자동으로 붙어서 깔끔하게 경로작성가능하다.
NavBar.tsx
useState를 사용하려면 클라이언트 컴포넌트라고 use client로 명시를 해야한다.
'use client'
import Link from "next/link";
import { useState } from "react";
import NavItem from "./NavItem";
const Navbar = () => {
const [menu, setMenu] = useState(false);
const handleMenu = () => setMenu(!menu);
return (
<nav className="relataive z-10 w-full bg-orange-500 text-white">
<div className="flex items-center justify-between mx-5 sm:mx-10 lg:mx-20">
<div className="flex items-center text-2xl h-14">
<Link href="/">Logo</Link>
</div>
{/* sm보다 클때 */}
<div className="text-2xl sm:hidden">
{(menu === false) ? <button onClick={handleMenu}>+</button> : <button onClick={handleMenu}>-</button>}
</div>
<div className="hidden sm:block">
<NavItem />
</div>
</div>
<div className="block sm:hidden">
{(menu === false) ? null : <NavItem mobile />}
</div>
</nav>
)
}
export default Navbar;
NavItem.tsx
import Link from 'next/link'
import React from 'react'
const NavItem = ({mobile} : {mobile?: boolean}) => {
return (
<ul
className={`text-md justify-center flex gap-4 w-full items-center ${mobile && "flex-col h-full"}`}
>
<li className="py-2 text-center border-b-4 cursor-pointer">
<Link href="/admin">Admin</Link>
</li>
<li className="py-2 text-center border-b-4 cursor-pointer">
<Link href="/user">User</Link>
</li>
<li className="py-2 text-center border-b-4 cursor-pointer">
<button>Sign out</button>
</li>
<li className="py-2 text-center border-b-4 cursor-pointer">
<button>Sign in</button>
</li>
</ul>
);
}
export default NavItem
스타일링만 완료.
일반유저와 어드민 페이지가 있는데 일단 생성부터. (나중에 권한별로 접근 제한)
app의 하위폴더에 admin과 user폴더 생성후 page.tsx 생성.
파일 시스템 라우팅이 잘되는것을 확인할 수 있다.
dev dependency로 prisma 설치
npm install -D prisma
npx prisma init
env파일에 데이터베이스 url등록이 필요
데이터베이스 url: postgres
.env
파일 생성
DATABASE_URL="postgresql://postgres:password@localhost:5432/nextjsapp"
https://railway.app/ -> 추천. 무료이나 한달에 500시간 제한있다.
https://supabase.com/
Start a New Project로 프로젝트 생성
New Project를 postgres 사용해서 생성
database url 복사
.env
파일에 데이터베이스 URL 넣기
도커를 이용해서 Postgres실행을 추천.
docker-compose.yml
version: "3"
services:
db:
image: postgres:latest
restart: always
ports:
- "5432:5432"
environment:
POSTGRES_USER: "postgres"
POSTGRES_PASSWORD: "password"
volumes:
- ./data:/var/lib/postgresql/data
실행 명령어: docker-compose up
도커허브에서 포스트그레스 이미지를 가져오는데 시간이 걸리긴함.
env 넣는방법: DATABASE_URL="postgresql://username:password@localhost:5432/dbname"
그냥 설치하고 재부팅하니 잘 됨.
버전 확인
몽고DB는 ODM(Object Data Modeling)라이브러리.
ORM이란,
객체와 관계형 데이터베이스의 데이터를 자동으로 변형 및 연결하는 작업.
ORM을 이용한 개발은 객체와 데이터베이스 변형에 유연하게 사용할 수 있다.
객체지향 프로그래밍은 클래스사용 <- (ORM으로)매핑 -> 관계형데이터베이스는 테이블사용
객체 모델과 관계형 모델간 불일치 존재... ??
ORM vs Pure Javascript
orm: const boards = Board.find({title: 'Hello', status: 'PUBLIC'});
pure javascript:
db.query('SELECT * FROM boards WHERE title = 'Hello' AND staus='PUBLIC', (err, result) => {
if(err) {
throw new Error('Error')
}
boards = result.rows;
})
개발에서 추상화(Abstraction)라는것은 추상화를 많이 하면 할수록 어떠한 복잡한 로직을 알지 못하더라도 그 로직을 간단하게 사용할 수있게 해줌. 불필요한 정보는 숨기고 중요한 정보만을 표현해서 프로그램을 간단하게 해줌)
데이터베이스도 사용하는 방법에 따라 추상화가 많이 되어있는 라이브러리를 사용할 수도 있고 그렇지 않은 라이브러리를 사용해서 데이터베이스를 컨트롤 할 수 있다.
추상화정도를 3단계로 나눈다.
데이터베이스 드라이버는 데이터베이스 연결(때때로 연결 풀링)을 처리한다. 이수준에서는 원시 SQL문자열을 작성하여 데이터베이스에 전달하고 데이터베이스에서 응답을 받는다.
Node.js생태계에는 이 계층에서 작동하는 많은 라이브러리가 있다.
이러한 각 라이브러리는 기본적으로 동일한 방식으로 작동한다. 데이터베이스 인증정보를 가져오고, 새 데이터베이스 인스턴스를 인스턴스화하고, 데이터베이스에 연결하고, 문자열 형식으로 쿼리를 보내고 결과를 비동기적으로 처리한다.
단순한 데이터베이스 드라이버 모듈과 완전한 ORM을 사용하는 것의 중간 수준.
이 계층에서 작동하는 가장 주목할만한 모듈은 Knex이다.
기본 SQL쿼리와 매우 유사하다. 또 문자열을 연결하여 SQL을 형성하는 경우(보안 취약점이 종종 발생)보다 훨씬 더 편리한 방식으로 프로그래밍 방식으로 동적쿼리를 생성할 수 있다.
최고수준의 추상화. ORM으로 작업할때 일반적으로 더 많은 설정을 사전에 수행해야한다. ORM의 요점은 이름(object relational mapping)에서 알 수 있듯이 관계형 데이터베이스의 데이터를 애플리케이션의 객체(클래스 인스턴스)에 매핑하는 것이다.
데이터베이스를 보는 Tool
https://www.postgresql.org/download/windows/
https://postgresapp.com/downloads.html
도커 실행을 먼저 하고 (docker-compose up
)
운영체제에 맞게 설치 후 pgAdmin 실행
설치할때 포트번호 5433으로 설치하다가 db연결안돼서 한시간동안 씨름했는데
C:\Program Files\PostgreSQL\16\data
경로에 postgresql.conf
폴더에서 포트번호 5432로 수정하고 서비스 restart하면된다.
서버 resister후
npx prisma db push
를 하면 db에 push한다는 명령인데
pgAdmin에서 새로고침하면
DB url 마지막의 데이터베이스가 생성되는것을 확인 할 수 있다.
데이타베이스에 연결이 안될때.. pgAdmin 서버에서 다시 등록해보고 안되면 서비스에서 postgresql을 restart해서 재등록하면된다...
테이블, 컬럼을 작성하려면 먼저 DB Schema가 필요하다. 작성 후 npx prisma db push한다.
잘 작성된 schema를 다음 공식문서에서 복사하여 prisma/schema.prisma
파일에 붙여넣는다.
model User {
id String @id @default(cuid())
name String?
hashedPassword String?
email String? @unique
emailVerified DateTime?
image String?
accounts Account[]
sessions Session[]
}
User테이블에 비밀번호가 기본적으로 없는데 hashedPassword라고 추가해준다.
hashedPassword는 복구화 할 수 없는 비밀번호라는 뜻..
String에 ?를 붙이면 optional하게 사용한다는 의미다.
구글로그인이나 깃헙 로그인을 한다면 비밀번호가 없기때문에 optional하게 넣는다.
SQL에서 변경된 테이블구조 확인할 수 있음.
스키마파일이 하이라이팅이 안되어있어서 불편한데 Prisma extension을 설치하면 syntax highlighting과 formatting, auto-completion, ... 기능이 지원된다.
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
: Account의 userId(fields)는 User의 id(references)와 같다. onDelete: Cascade
는 해당 유저를 지우면 해당 유저의 Account도 지워짐 설정. npx prisma db push
를 하여 데이터 push를 한다.
pgAdmin을 새로고침하면
스키마 파일을 토대로 테이블이 생성된것을 확인할 수 있다.