CORS๊ฐ ๋ฑ์ฅํ๊ธฐ ์ ์๋ SOP(Same Origin Policy) ์ ์ฑ ์ด ๋จผ์ ์์๋ค. ์๋ฅผ ๋ค์ด, ๋ค์ด๋ฒ ๋ธ๋ผ์ฐ์ ์ api ์์ฒญ๊ณผ ๊ทธ์ ๋ฐ๋ฅธ ์๋ต์ ๋ค์ด๋ฒ ๋ฐฑ์๋์์๋ง ๋ณด๋ผ ์ ์๊ณ , ๋ค์ ๋ธ๋ผ์ฐ์ ๋ ๋ค์ ๋ฐฑ์๋์์๋ง ๋ณด๋ผ ์ ์์๋ค.
๊ทธ๋ฌ๋ค๊ฐ ๋ค์์์๋ ๋ค์ด๋ฒ์ ๋ฐฑ์๋์ api ์์ฒญํ ์ ์๋๋ก ํ์! ํด์ ๋์จ ๊ฒ์ด CORS
(Cross Origin Resource Sharing)๋ค.
preflight(api ์์ฒญ ๋ณด๋ด๊ธฐ ์ ์ ๋ฏธ๋ฆฌ ์์ฒญ ๋ณด๋ด๋ณด๋ ๊ฒ)๋ฅผ ๋ณด๋ด๋ฉด, ๋ฐฑ์๋์์๋ ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ด์ค๋ ๋๋์ง, ์๋๋์ง ๊ฒ์ฌ๋ฅผ ํ๊ณ ์๋ ค์ฃผ๊ฒ ๋๋ค.
๋ฐฑ์๋์์ CORS ๋ฐฐ์ด์ ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ด์ค๋ ๋๋ ๋ธ๋ผ์ฐ์ ๋ฅผ ๋ช ์ํด๋๊ณ , ๊ฒ์ฌ ํ์ CORS ํ์ฉ ํน์ ๊ฑฐ์ ์ ๋ณด๋ธ๋ค.
CORS๊ฐ ๊ฑฐ์ ๋ ๊ฒฝ์ฐ, ์ด๋ป๊ฒ ํด์ผ ํ ๊น?
๋ค๋ฅธ ๋ฐฑ์๋๋ก ์ฐํํด์ ์๋ api ์์ฒญ์ ๋ณด๋ด๋ ค๋ ๋ฐฑ์๋๋ก ์ ๊ทผํ ์ ์๋ค. ์ด๋ ๋ธ๋ผ์ฐ์ ์ ๋ฐฑ์๋ ์ฌ์ด์์ ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ์์ฃผ๋ ๋๋ฆฌ์ธ ์ญํ ์ ํ๋ ์๋ฒ๋ฅผ ํ๋ก์์๋ฒ(proxy)
๋ผ๊ณ ํ๋ค.
๊ทธ ์ธ์ ๋ชจ๋ฐ์ผ๋ก api ์์ฒญ์ ๋ณด๋ด๋ ๋ฐฉ๋ฒ๋ ์๋ค. ์ด ๊ฒฝ์ฐ ๋ธ๋ผ์ฐ์ ์ ๋ค๋ฅด๊ฒ ๋ฐฑ์๋ ์ปดํจํฐ์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ๋ก ์ฃผ๊ณ ๋ฐ์ ์ ์๋ค.
๊ทธ๋ฌ๋ฉด ๋ค ์ฐํํ๋ฉด ๋ ํ
๋ฐ ์ ๊ตณ์ด CORS ์ ์ฑ
์ด ์๋๊ฑธ๊น? ๋ฐ๋ก ๋ธ๋ผ์ฐ์ ๋ฅผ ๋ณดํธํ๊ธฐ ์ํด์๋ค!
๋ธ๋ผ์ฐ์ ๊ฐ ๋ก๊ทธ์ธ์ ํ๋ฉด, ๋ฐฑ์๋์์ ๊ฒ์ฆ ํ ๋ธ๋ผ์ฐ์ ์ ๋ก๊ทธ์ธ์ฆํ๋ฅผ ๋ณด๋ด๊ฒ ๋๊ณ , ๋ธ๋ผ์ฐ์ ์ ์ฟ ํค๋ผ๋ ๊ณณ์ ๋ก๊ทธ์ธ์ฆํ๋ฅผ ์ ์ฅํด๋๋๋ค.
์ฟ ํค์ ๋๊ตฌํํ ์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์๋์ง ์ ์ฅ๋์ด ์๊ณ , ๋ก๊ทธ์ธ์ฆํ๊ฐ ์ ์ฅ๋์ด ์๋ ์ํ์์ ๋ก๊ทธ์ธ์ฆํ๋ฅผ ๋ฐ์๋ ๋ฐฑ์๋์ ๋ค์ api๋ฅผ ์์ฒญํ ์ ์๋ค.
๋ฐ๋ผ์ ์ ๋ขฐํ ์ ์๋ ์ฌ์ดํธ๋ง์ CORS ํ์ฉํด์ค ์ ์๋ค. ์๋ ๋ธ๋ผ์ฐ์ ์ ๋๊ฐ์ด ์๊ธด ํดํน ์ฌ์ดํธ๊ฐ ์ ์์ ์๋ํ๋ ๊ฒ์ ๋ง์์ค ์ ์๋ ๊ฒ์ด๋ค!
๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ๋ฐ์ดํฐ๋ฅผ ๋ด์๋๋ ์ ์ฅ์์ด๋ค. ๋ฐ์ดํฐ๋ฅผ ๋ด์๋๋ ๋ฐฉ์์๋ ํฌ๊ฒ 2๊ฐ์ง๊ฐ ์๋ค.
SQL(ํ ๋ฐฉ์): Oracle, MySQL, Postgresql..
NoSQL(์๋ฅ ๋ฐฉ์): MongoDB, Redis, Firebase..
SQL ๋ฐฉ์์ NoSQL ๋ฐฉ์๊ณผ ๋ฌ๋ฆฌ ํ ์ฌ์ด์ ๊ด๊ณ์ฑ์ ๋ถ์ฌํ ์ ์๋ค. ๊ด๊ณ์ฑ์ ๋ถ์ฌํ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๊ด๊ณํ ๋ฐ์ดํฐ ๋ฒ ์ด์ค
๋ผ๊ณ ํ๋ค. ํต์ ์ ๋์์ฃผ๋ ํด๋ก ORM(Object Relation Mapping)์ ์ฌ์ฉํ๋ค.
NoSQL ๋ฐฉ์์ ์๋ฅ ๋ดํฌ์ document๋ฅผ ๋ชจ์๋๋ ๋ฐฉ์์ด๋ค. ์ฌ๊ธฐ์ ์๋ฅ ๋ดํฌ๋ฅผ ์ปฌ๋ ์
์ด๋ผ๊ณ ๋ถ๋ฅด๊ณ , ํต์ ์ ๋์์ฃผ๋ ํด๋ก ODM(Object Document Mapping)์ ์ฌ์ฉํ๋ค.
DB ๊ด๋ฆฌ ํ๋ก๊ทธ๋จ์๋ DBeaver, MySQL webpack ๋ฑ์ด ์๋ค. ์์ ์์๋ DBeaver๋ฅผ ์ฌ์ฉํ๋ค.
์ค์ตํ ๋ด์ฉ์ ๋ค์๊ณผ ๊ฐ๋ค.
ORM์ ์ค์นํด์ ORM์ ํตํด DB์ ์ฐ๊ฒฐ.
JS์ ๋ฐฑ์๋ ํ ์ด๋ธ ๊ตฌ์กฐ๋ฅผ class ํํ๋ก ๋ง๋ค์ด์ค.
ํด๋นํ๋ class๋ฅผ ๋ฃ์ผ๋ฉด DB์ Board table์ด ๋ง๋ค์ด์ง.
DB ๊ด๋ฆฌ ํ๋ก๊ทธ๋จ์ ํตํด DB์ ํ ์ด๋ธ์ด ์ ๋ง๋ค์ด์ ธ ์๋์ง ํ์ธ.
์๋ ์๋ฐ์คํฌ๋ฆฝํธ๋ ๊ฐ๋ฐ์ ํ๊ณ , ๋ธ๋ผ์ฐ์ ์์๋ง ์คํ์ํฌ ์ ์์๋๋ฐ, node.js
๊ฐ ๋์ค๋ฉด์ ๋ธ๋ผ์ฐ์ ๋ฅผ ์ผ์ง ์๊ณ ์คํ์ํฌ ์ ์๋ ๋ฐฉ๋ฒ์ด ์๊ฒผ๋ค.
- ํ์ฅ์ js๋ก ํ์ผ ๋ง๋ค๊ธฐ
- ์ฝ๋ ์์ฑ
- ํฐ๋ฏธ๋์ node ํ์ผ ์ ๋ ฅํด์ ํ์ผ ์คํ์ํค๊ธฐ
ts/tsx ํ์ฅ์ ํ์ผ ๋ง๋ค๊ธฐ
typescript ์ค์น ๋ฐ ์ค์
yarn add --dev typescript
ts-node(ํ์ ์คํฌ๋ฆฝํธ ์คํํ๋ก๊ทธ๋จ) ์ค์น
yarn add ts-node
package.json์ ํ์ผ ์คํ ๋ช ๋ น์ด ์ถ๊ฐ ํ ๋ช ๋ น์ด๋ฅผ ํฐ๋ฏธ๋์ ์ ๋ ฅ(yarn ๋ช ๋ น์ด)
"scripts": {
"๋ช
๋ น์ด": "ts-node index.ts"
},
typeORM
์ ์ด์ฉํด์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ฐฑ์๋๋ฅผ ์ฐ๊ฒฐํ ์ ์๋ค.
yarn add typeorm
yarn add pg(typeorm์ด postgres์ ์ฐ๊ฒฐํ๊ธฐ ์ฝ๊ฒ ๋์์ฃผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ)
import { DataSource } from "typeorm";
import { Board } from "./Board.postgres";
const AppDataSource = new DataSource({
type: "postgres",
host: "DB๊ฐ ์๋ ์ปดํจํฐ์ IP ์ฃผ์",
port: DB๊ฐ ์๋ ์ปดํจํฐ์ port number,
username: "postgres",
password: "password",
database: "postgres",
entities: [Board], // entities์ ํ์ผ๊ฒฝ๋ก
synchronize: true,
logging: true,
});
AppDataSource.initialize()
.then(() => {
console.log("์ฐ๊ฒฐ ์ฑ๊ณต!");
})
.catch((error) => console.log(error, "์ฐ๊ฒฐ ์คํจ!"));
Board.postgres.ts ํ์ผ์ ๋ง๋ค๊ณ , entity
๋ฅผ ๋ง๋๋ ์ฝ๋๋ฅผ ์์ฑํ๋ค.
// entities ๋ง๋ค์ด์ฃผ๊ธฐ _ ์๋ก์ด ํ์
์คํฌ๋ฆฝํธํ์ผ ๋ง๋ค๊ธฐ
import { BaseEntity, Column, Entity, PrimaryGeneratedColumn } from "typeorm";
// @ -> ๋ฐ์ฝ๋ ์ดํฐ(typeORM์๊ฒ ํ
์ด๋ธ์์ ์๋ ค์ค. ๋ฐ์ฝ๋ ์ดํฐ๋ ํจ์)
@Entity()
export class Board extends BaseEntity {
// primaryGenerateColumn: ์๋์ผ๋ก ์์ฑ๋๋ ๋ฒํธ
@primaryGenerateColumn(โincrementโ)
number!: number;
@column({type : โtextโ})
wrtier!: string;
@Column({ type: "text" })
title!: string;
@Column({ type: "text" })
contents!: string;
}
์ฌ๊ธฐ์ ๋ฐ์ฝ๋ ์ดํฐ์ ํ์ ์ tsconfig.json์์ ์ค์ ํด์ค์ผ ํ๋ค.
"experimentalDecorators": true
์ข์ธก ์๋จ ํ๋ฌ๊ทธ ๋ชจ์ ํด๋ฆญ
postgreSQL ์ ํ
Host ๋ถ๋ถ์ localhost ๋์ ๋ฐฑ์๋ ์ฃผ์ ์ ๋ ฅ
๋ชจ๋ ์ ๋ ฅ ํ test connection ํด๋ฆญ(ํ๋์ ๋จ๋ฉด ์๋ฃ๋ ๊ฒ์ด๋ฏ๋ก ์๋ฃ ๋๋ฅด๊ธฐ)
์ด๋ ๊ฒ ํ๋ฉด DB์ ํ ์ด๋ธ์ด ์ ๋ง๋ค์ด์ง ๊ฒ์ ํ์ธํ ์ ์๋ค.